Skip to content

Commit

Permalink
slight api change, more comments
Browse files Browse the repository at this point in the history
  • Loading branch information
keks committed Nov 13, 2024
1 parent 9caa0ff commit 3c5be34
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 38 deletions.
4 changes: 4 additions & 0 deletions curve25519/src/impl_hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ use super::*;
pub struct HaclCurve25519;

impl Curve25519 for HaclCurve25519 {
// the hacl::ecdh function requires all parameters to be 32 byte long, which we enforce using
// types.
fn secret_to_public(pk: &mut [u8; PK_LEN], sk: &[u8; SK_LEN]) {
crate::hacl::secret_to_public(pk, sk)
}

// the hacl::ecdh function requires all parameters to be 32 byte long, which we enforce using
// types.
fn ecdh(out: &mut [u8; SHK_LEN], pk: &[u8; PK_LEN], sk: &[u8; SK_LEN]) -> Result<(), Error> {
if crate::hacl::ecdh(out, sk, pk) {
Ok(())
Expand Down
4 changes: 4 additions & 0 deletions curve25519/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ pub struct Error;
/// This trait is implemented by the backing implementations.
/// Only used for implementation agility.
trait Curve25519 {
/// Computes a public key from a secret key.
fn secret_to_public(pk: &mut [u8; PK_LEN], sk: &[u8; SK_LEN]);

/// Computes the scalar multiplication between the provided public and secret keys. Returns an
/// error if the result is 0.
fn ecdh(out: &mut [u8; SHK_LEN], pk: &[u8; PK_LEN], sk: &[u8; SK_LEN]) -> Result<(), Error>;
}

Expand Down
25 changes: 21 additions & 4 deletions ed25519/src/impl_hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ pub enum Error {
InvalidSignature,
}

/// The hacl implementation requires that
/// - the private key is a 32 byte buffer
/// - the signature is a 64 byte buffer,
/// - the payload buffer is not shorter than payload_len.
///
/// We enfore the first two using types, and the latter by using `payload.len()` and `payload_len`.
/// This has the caveat that `payload_len` must be <= u32::MAX, so we return an error if that is
/// not the case.
pub fn sign(payload: &[u8], private_key: &[u8; 32]) -> Result<[u8; 64], Error> {
let mut signature = [0u8; 64];
crate::hacl::ed25519::sign(
Expand All @@ -16,6 +24,15 @@ pub fn sign(payload: &[u8], private_key: &[u8; 32]) -> Result<[u8; 64], Error> {
Ok(signature)
}

/// The hacl implementation requires that
/// - the public key is a 32 byte buffer
/// - the signature is a 64 byte buffer,
/// - the payload buffer is not shorter than payload_len.
///
/// We enfore the first two using types, and the latter by using `payload.len()` and `payload_len`.
/// This has the caveat that `payload_len` must be <= u32::MAX, so we return an error if that is
/// not the case.
///
pub fn verify(payload: &[u8], public_key: &[u8; 32], signature: &[u8; 64]) -> Result<(), Error> {
if crate::hacl::ed25519::verify(
public_key,
Expand All @@ -30,8 +47,8 @@ pub fn verify(payload: &[u8], public_key: &[u8; 32], signature: &[u8; 64]) -> Re
}

/// Compute the public point for the given secret key `sk`.
pub fn secret_to_public(sk: &[u8; 32]) -> [u8; 32] {
let mut out = [0u8; 32];
crate::hacl::ed25519::secret_to_public(&mut out, sk);
out
/// The hacl implementation requires that these are both 32 byte buffers, which we enforce through
/// types.
pub fn secret_to_public(pk: &mut [u8; 32], sk: &[u8; 32]) {
crate::hacl::ed25519::secret_to_public(pk, sk)
}
2 changes: 2 additions & 0 deletions ed25519/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(feature = "hacl")]
pub mod hacl {
//! This module contains generated hacl code.
pub mod ed25519;
pub mod ed25519_precomptable;
}
Expand Down
5 changes: 5 additions & 0 deletions hacl-rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! This crate contains hacl-generated utility modules for other hacl-generated code.
//! You most likely don't need to import this.
//!
//! hacl-star commit: efbf82f29190e2aecdac8899e4f42c8cb9defc98
// Utility modules. In the generated hacl-rs, these are individual crates.
pub mod bignum;
pub mod fstar;
Expand Down
11 changes: 4 additions & 7 deletions libcrux-ecdh/src/hacl/curve25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ pub fn ecdh(
public_key: impl AsRef<[u8; 32]>,
) -> Result<[u8; 32], Error> {
let mut shared = [0u8; 32];
let ok = libcrux_curve25519::hacl::ecdh(&mut shared, private_key.as_ref(), public_key.as_ref());

if !ok {
Err(Error::InvalidInput)
} else {
Ok(shared)
match libcrux_curve25519::ecdh(&mut shared, private_key.as_ref(), public_key.as_ref()) {
Ok(_) => Ok(shared),
Err(_) => Err(Error::InvalidInput),
}
}

Expand All @@ -29,7 +26,7 @@ pub fn ecdh(
#[inline(always)]
pub fn secret_to_public(private_key: impl AsRef<[u8; 32]>) -> [u8; 32] {
let mut public = [0u8; 32];
libcrux_curve25519::hacl::secret_to_public(&mut public, private_key.as_ref());
libcrux_curve25519::secret_to_public(&mut public, private_key.as_ref());
public
}

Expand Down
2 changes: 2 additions & 0 deletions libcrux-hkdf/src/hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#![allow(unused_assignments)]
#![allow(unreachable_patterns)]

//! This module contains generated hacl code.
use libcrux_hacl_rs::lowstar;

/**
Expand Down
12 changes: 8 additions & 4 deletions libcrux-hkdf/src/hkdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ pub enum Error {

/// HKDF extract using hash function `mode`, `salt`, and the input key material `ikm`.
/// Returns the pre-key material in a vector of tag length.
pub fn extract(alg: Algorithm, salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> Vec<u8> {
pub fn extract(
alg: Algorithm,
salt: impl AsRef<[u8]>,
ikm: impl AsRef<[u8]>,
) -> Result<Vec<u8>, Error> {
let salt = salt.as_ref();
let ikm = ikm.as_ref();
match alg {
Expand Down Expand Up @@ -91,8 +95,8 @@ pub fn hkdf(
}
}

fn allocbuf<const N: usize, F: Fn(&mut [u8; N])>(f: F) -> Vec<u8> {
fn allocbuf<const N: usize, T, E, F: Fn(&mut [u8; N]) -> Result<T, E>>(f: F) -> Result<Vec<u8>, E> {
let mut buf = [0u8; N];
f(&mut buf);
buf.into()

f(&mut buf).map(|_| buf.into())
}
39 changes: 24 additions & 15 deletions libcrux-hkdf/src/impl_hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub trait HkdfMode<const HASH_LEN: usize> {
/// The result is written to `prk`.
///
/// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes.
fn extract(prk: &mut [u8; HASH_LEN], salt: &[u8], ikm: &[u8]);
fn extract(prk: &mut [u8; HASH_LEN], salt: &[u8], ikm: &[u8]) -> Result<(), Error>;

/// HKDF expand using the pre-key material `prk` and `info`. The output length
/// is defined through the type of the `okm` parameter, that the output is written to.
Expand Down Expand Up @@ -47,9 +47,10 @@ pub trait HkdfMode<const HASH_LEN: usize> {
info: &[u8],
) -> Result<(), Error> {
let mut prk = [0u8; HASH_LEN];
Self::extract(&mut prk, salt, ikm);
Self::extract(&mut prk, salt, ikm)?;
Self::expand(okm, &prk, info)
}

/// HKDF using the `salt`, input key material `ikm`, `info`. The output length
/// is defined by the parameter `okm_len`.
/// Calls `extract` and `expand` with the given input.
Expand All @@ -58,7 +59,7 @@ pub trait HkdfMode<const HASH_LEN: usize> {
/// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes.
fn hkdf_vec(salt: &[u8], ikm: &[u8], info: &[u8], okm_len: usize) -> Result<Vec<u8>, Error> {
let mut prk = [0u8; HASH_LEN];
Self::extract(&mut prk, salt, ikm);
Self::extract(&mut prk, salt, ikm)?;
Self::expand_vec(&prk, info, okm_len)
}
}
Expand All @@ -73,7 +74,11 @@ macro_rules! impl_hkdf {
impl HkdfMode<$hash_len> for $sname {
const MODE: Algorithm = $mode;

fn extract(prk: &mut [u8; $hash_len], salt: &[u8], ikm: &[u8]) {
fn extract(
prk: &mut [u8; $hash_len],
salt: &[u8],
ikm: &[u8],
) -> Result<(), Error> {
extract(prk, salt, ikm)
}

Expand All @@ -93,15 +98,20 @@ macro_rules! impl_hkdf {
/// HKDF extract using the `salt`, and the input key material `ikm`.
/// Returns the pre-key material in an array of hash length.
///
/// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes.
pub fn extract(prk: &mut [u8; $hash_len], salt: &[u8], ikm: &[u8]) {
crate::hacl::$extract(
/// Note that this function returns an [`Error::ArgumentsTooLarge`]
/// if `salt` or `ikm` is larger than 2**32 bytes.
pub fn extract(
prk: &mut [u8; $hash_len],
salt: &[u8],
ikm: &[u8],
) -> Result<(), Error> {
Ok(crate::hacl::$extract(
prk,
salt,
checked_u32(salt.len()).unwrap(),
checked_u32(salt.len())?,
ikm,
checked_u32(ikm.len()).unwrap(),
);
checked_u32(ikm.len())?,
))
}

/// HKDF expand using the pre-key material `prk` and `info`. The output length
Expand All @@ -110,7 +120,7 @@ macro_rules! impl_hkdf {
/// [`Error::OkmTooLarge`] if the requested `okm_len` is too large.
///
/// Note that this function returns an [`Error::ArgumentsTooLarge`]
/// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes.
/// if `prk`, `info`, or `OKM_LEN` is larger than 2**32 bytes.
pub fn expand<const OKM_LEN: usize>(
okm: &mut [u8; OKM_LEN],
prk: &[u8],
Expand All @@ -121,15 +131,14 @@ macro_rules! impl_hkdf {
return Err(Error::OkmTooLarge);
}

crate::hacl::$expand(
Ok(crate::hacl::$expand(
okm,
prk,
checked_u32(prk.len())?,
info,
checked_u32(info.len())?,
checked_u32(OKM_LEN)?,
);
Ok(())
))
}

/// HKDF using the `salt`, input key material `ikm`, `info`. The output length
Expand All @@ -145,7 +154,7 @@ macro_rules! impl_hkdf {
info: &[u8],
) -> Result<(), Error> {
let mut prk = [0u8; $hash_len];
extract(&mut prk, salt, ikm);
extract(&mut prk, salt, ikm)?;
expand(okm, &prk, info)
}

Expand Down
1 change: 1 addition & 0 deletions libcrux-hmac/src/impl_hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ macro_rules! impl_hmac {
/// Compute HMAC.
///
/// Note that this function panics if `key` or `data` is larger than 2**32 bytes.
/// This ensures that all values are in the range valid to be consumed by hacl-rs.
pub fn $name(dst: &mut [u8; $tag_len], key: &[u8], data: &[u8]) {
$fun(
dst,
Expand Down
14 changes: 12 additions & 2 deletions sha2/src/impl_hacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,35 @@ use super::*;
use libcrux_traits::Digest;

/// SHA2 224
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
pub fn sha224(payload: &[u8]) -> [u8; SHA224_LENGTH] {
let mut digest = [0u8; SHA224_LENGTH];
Sha224::hash(&mut digest, payload);
digest
}

/// SHA2 256
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
pub fn sha256(payload: &[u8]) -> [u8; SHA256_LENGTH] {
let mut digest = [0u8; SHA256_LENGTH];
Sha256::hash(&mut digest, payload);
digest
}

/// SHA2 384
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
pub fn sha384(payload: &[u8]) -> [u8; SHA384_LENGTH] {
let mut digest = [0u8; SHA384_LENGTH];
Sha384::hash(&mut digest, payload);
digest
}

/// SHA2 512
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
pub fn sha512(payload: &[u8]) -> [u8; SHA512_LENGTH] {
let mut digest = [0u8; SHA512_LENGTH];
Sha512::hash(&mut digest, payload);
Expand All @@ -47,14 +55,16 @@ macro_rules! impl_hash {

impl libcrux_traits::Digest<$digest_size> for $name {
/// Return the digest for the given input byte slice, in immediate mode.
/// Will panic if `payload` is longer than `u32::MAX`.
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
fn hash(digest: &mut [u8; $digest_size], payload: &[u8]) {
let payload_len = payload.len().try_into().unwrap();
$hash(digest, payload, payload_len)
}

/// Add the `payload` to the digest.
/// Will panic if `payload` is longer than `u32::MAX`.
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
fn update(&mut self, payload: &[u8]) {
let payload_len = payload.len().try_into().unwrap();
$update(self.state.as_mut(), payload, payload_len);
Expand Down
9 changes: 4 additions & 5 deletions src/hpke/kdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,10 @@ pub fn LabeledExtract(
labeled_ikm.extend_from_slice(&label);
labeled_ikm.extend_from_slice(ikm);

Ok(crate::hkdf::extract(
hkdf_algorithm(alg),
salt,
&labeled_ikm,
))
crate::hkdf::extract(hkdf_algorithm(alg), salt, &labeled_ikm).map_err(|err| match err {
libcrux_hkdf::Error::OkmTooLarge => HpkeError::CryptoError,
libcrux_hkdf::Error::ArgumentsTooLarge => HpkeError::InvalidParameters,
})
}

/// KDF: Labeled Expand
Expand Down
5 changes: 4 additions & 1 deletion src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,8 @@ pub fn key_gen(
Algorithm::Ed25519 => {
const LIMIT: usize = 100;
let mut sk = [0u8; 32];
let mut pk = [0u8; 32];

for _ in 0..LIMIT {
rng.try_fill_bytes(&mut sk)
.map_err(|_| Error::KeyGenError)?;
Expand All @@ -498,7 +500,8 @@ pub fn key_gen(

break;
}
let pk = ed25519::secret_to_public(&sk);

ed25519::secret_to_public(&mut pk, &sk);

Ok((sk.to_vec(), pk.to_vec()))
}
Expand Down

0 comments on commit 3c5be34

Please sign in to comment.