Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,23 @@ jobs:
RUSTDOCFLAGS: -Dwarnings
steps:
- uses: actions/[email protected]
- uses: dtolnay/rust-toolchain@stable
- name: Install stable Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
components: clippy

# Check using Clippy with the feature combinations listed in the README.
- run: cargo clippy
- run: cargo clippy --no-default-features --features aes,hkdfsha2,nistp,serde

- name: Format
run: cargo fmt --all -- --check

- name: Docs
run: cargo doc --no-deps

- name: Install nightly Rust
uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt

- name: Format
run: cargo +nightly fmt --all --message-format human -- --check

16 changes: 16 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Enforce consistent code formatting across the project
max_width = 100
use_small_heuristics = "Default"

# Comment formatting (requires nightly rustfmt)
wrap_comments = true
comment_width = 100

# Unstable features
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
error_on_line_overflow = true

# Note: format_code_in_doc_comments is NOT enabled due to known issues
# with block comment conversion and trailing comment alignment.
# See: https://github.com/rust-lang/rustfmt/issues/5533
13 changes: 7 additions & 6 deletions src/aead.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::IdLookupError;
use num_enum::TryFromPrimitive;
use std::str::FromStr;

/**
Aead represents an authenticated encryption with additional data
encryption function, as per [RFC9180§7.3](https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3)
*/
use num_enum::TryFromPrimitive;

use crate::IdLookupError;

/// An authenticated encryption with additional data encryption function, as per [RFC9180§7.3][1].
///
/// [1]: https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3
#[non_exhaustive]
#[repr(u16)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive)]
Expand Down
28 changes: 14 additions & 14 deletions src/base_mode_open.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use crate::{from_bytes, Config};
use hpke::HpkeError;

/**
`base_mode_open` provides an interface to [`hpke::single_shot_open`]
that does not require compile time selection of an algorithm. Instead,
the selected algorithm is provided through the [`Config`] passed as
the first argument.

# Errors

This will return an `Result::Err` variant if:
use crate::{from_bytes, Config};

* we are unable to deserialize the private key or encapsulated key
* there is an error in key decapsulation
* there is an error in decryption
*/
/// Single-shot HPKE ciphertext opening.
///
/// `base_mode_open` provides an interface to [`hpke::single_shot_open`] that does not require
/// compile time selection of an algorithm. Instead, the selected algorithm is provided through the
/// [`Config`] passed as the first argument.
///
/// # Errors
///
/// This will return a `Result::Err` variant if:
///
/// * we are unable to deserialize the private key or encapsulated key
/// * there is an error in key decapsulation
/// * there is an error in decryption
pub fn base_mode_open(
config: &Config,
private_key: &[u8],
Expand Down
29 changes: 14 additions & 15 deletions src/base_mode_seal.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use crate::{from_bytes, Config, EncappedKeyAndCiphertext};
use hpke::{HpkeError, Serializable};

/**
`base_mode_seal` provides an interface to [`hpke::single_shot_seal`]
that does not require compile time selection of an
algorithm. Instead, the selected algorithm is provided through the
[`Config`] passed as the first argument.

# Errors

This will return an `Result::Err` variant if:

* we are unable to deserialize the recipient public key
* there is an error in key encapsultion
* there is an error in encryption
use crate::{from_bytes, Config, EncappedKeyAndCiphertext};

*/
/// Single-shot HPKE ciphertext sealing.
///
/// `base_mode_seal` provides an interface to [`hpke::single_shot_seal`] that does not require
/// compile time selection of an algorithm. Instead, the selected algorithm is provided through the
/// [`Config`] passed as the first argument.
///
/// # Errors
///
/// This will return an `Result::Err` variant if:
///
/// * we are unable to deserialize the recipient public key
/// * there is an error in key encapsultion
/// * there is an error in encryption
pub fn base_mode_seal(
config: &Config,
recipient_public_key: &[u8],
Expand Down
11 changes: 5 additions & 6 deletions src/ciphertext.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/**
a simple struct to return the combined encapsulated key
and ciphertext from seal
*/
/// Encapsulated key and ciphertext.
///
/// Obtained from [`crate::base_mode_seal::base_mode_seal`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EncappedKeyAndCiphertext {
/// the encapsulated encryption key
/// The encapsulated encryption key
pub encapped_key: Vec<u8>,

/// the ciphertext, encrypted with the key
/// The ciphertext, encrypted with the key
pub ciphertext: Vec<u8>,
}

Expand Down
78 changes: 40 additions & 38 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use hpke::HpkeError;

use crate::{
base_mode_open, base_mode_seal, Aead, EncappedKeyAndCiphertext, IdLookupError, Kdf, Kem,
};
use hpke::HpkeError;

/**
Config is an open struct that contains an ([`Aead`], [`Kdf`], [`Kem`])
algorithmic triple. This can be used with [`Config::base_mode_seal`],
[`Config::base_mode_open`], [`base_mode_seal`], or [`base_mode_open`].
*/
/// Configuration for crate interfaces.
///
/// Contains an ([`Aead`], [`Kdf`], [`Kem`]) algorithmic triple. This can be used with
/// [`Config::base_mode_seal`], [`Config::base_mode_open`], [`base_mode_seal`], or
/// [`base_mode_open`].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_crate::Serialize, serde_crate::Deserialize)
)]
#[cfg_attr(feature = "serde", serde(crate = "serde_crate"))]
pub struct Config {
/// the [authenticated encryption with additional data encryption function](crate::Aead) to be used
/// the [authenticated encryption with additional data encryption function](crate::Aead) to be
/// used
pub aead: Aead,
/// the [key derivation function](crate::Kdf) to be used
pub kdf: Kdf,
Expand All @@ -24,21 +26,19 @@ pub struct Config {
}

impl Config {
/**
base_mode_seal provides an interface to [`hpke::single_shot_seal`] that does
not require compile time selection of an algorithm. Instead, the
selected algorithm is provided through the [`Config`] that this
method is called on.

# Errors

This will return an `Result::Err` variant if:

* we are unable to deserialize the recipient public key
* there is an error in key encapsultion
* there is an error in encryption

*/
/// Single-shot HPKE ciphertext sealing.
///
/// `base_mode_seal` provides an interface to [`hpke::single_shot_seal`] that does not require
/// compile time selection of an algorithm. Instead, the selected algorithm is provided through
/// the receiver.
///
/// # Errors
///
/// This will return a `Result::Err` variant if:
///
/// * we are unable to deserialize the recipient public key
/// * there is an error in key encapsultion
/// * there is an error in encryption
pub fn base_mode_seal(
&self,
recipient_public_key: &[u8],
Expand All @@ -49,21 +49,19 @@ impl Config {
base_mode_seal(self, recipient_public_key, info, plaintext, aad)
}

/**
base_mode_open provides an interface to [`hpke::single_shot_open`]
that does not require compile time selection of an
algorithm. Instead, the selected algorithm is provided through the
[`Config`] that this method is called on.

# Errors

This will return an `Result::Err` variant if:

* we are unable to deserialize the private key or encapsulated key
* there is an error in key decapsulation
* there is an error in decryption

*/
/// Single-shot HPKE ciphertext opening.
///
/// `base_mode_open` provides an interface to [`hpke::single_shot_open`] that does not require
/// compile time selection of an algorithm. Instead, the selected algorithm is provided through
/// the receiver
///
/// # Errors
///
/// This will return a `Result::Err` variant if:
///
/// * we are unable to deserialize the private key or encapsulated key
/// * there is an error in key decapsulation
/// * there is an error in decryption
pub fn base_mode_open(
&self,
private_key: &[u8],
Expand All @@ -75,7 +73,11 @@ impl Config {
base_mode_open(self, private_key, encapped_key, info, ciphertext, aad)
}

/// Attempt to convert three u16 ids into a valid config. The id mappings are defined in the draft.
/// Attempt to convert three u16 ids into a valid [`Config`].
///
/// The ID mappings are defined in the [IANA HPKE registries][1].
///
/// [1]: https://www.iana.org/assignments/hpke/hpke.xhtml
pub fn try_from_ids(aead_id: u16, kdf_id: u16, kem_id: u16) -> Result<Config, IdLookupError> {
Ok(Self {
aead: aead_id.try_into().map_err(|_| IdLookupError("aead"))?,
Expand Down
6 changes: 4 additions & 2 deletions src/kdf.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::IdLookupError;
use num_enum::TryFromPrimitive;
use std::str::FromStr;

use num_enum::TryFromPrimitive;

use crate::IdLookupError;

/// A key derivation function used in HPKE.
///
/// Codepoints are defined in [RFC9180§7.2][1] and [draft-ietf-hpke-pq][2].
Expand Down
6 changes: 4 additions & 2 deletions src/kem.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{IdLookupError, Keypair};
use num_enum::TryFromPrimitive;
use std::str::FromStr;

use num_enum::TryFromPrimitive;

use crate::{IdLookupError, Keypair};

/// An asymmetric key encapsulation mechanism.
///
/// Codepoints are defined in [RFC9180§7.2][1] and [draft-ietf-hpke-pq][2].
Expand Down
3 changes: 2 additions & 1 deletion src/keypair.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::Kem;
use hpke::Serializable;

use crate::Kem;

/// An encoded keypair
#[derive(Debug, Clone, Eq, PartialEq, zeroize::Zeroize)]
pub struct Keypair {
Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ pub use kdf::{Kdf, KDF_ALL};
mod kem;
pub use kem::{Kem, KEM_ALL};

/**
A simple error type for failed id lookups
*/
/// A simple error type for failed id lookups
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
feature = "serde",
Expand Down
16 changes: 14 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,21 @@ macro_rules! match_algo {
#[cfg(feature = "shake")]
$crate::Kdf::Shake256 => match_algo!(@kem, $aead, hpke::kdf::KdfShake256, $kem, $fn),
#[cfg(feature = "shake")]
$crate::Kdf::TurboShake128 => match_algo!(@kem, $aead, hpke::kdf::KdfTurboShake128, $kem, $fn),
$crate::Kdf::TurboShake128 => match_algo!(
@kem,
$aead,
hpke::kdf::KdfTurboShake128,
$kem,
$fn
),
#[cfg(feature = "shake")]
$crate::Kdf::TurboShake256 => match_algo!(@kem, $aead, hpke::kdf::KdfTurboShake256, $kem, $fn),
$crate::Kdf::TurboShake256 => match_algo!(
@kem,
$aead,
hpke::kdf::KdfTurboShake256,
$kem,
$fn
),
}
};

Expand Down
Loading