Skip to content

Commit

Permalink
updates API to exclude need for k value as usize
Browse files Browse the repository at this point in the history
  • Loading branch information
supinie committed Jun 5, 2024
1 parent e3c02ba commit 1c2d19a
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 61 deletions.
18 changes: 9 additions & 9 deletions benches/my_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,61 @@ use enc_rust::kem::*;

pub fn gen_key_benchmark_512(c: &mut Criterion) {
c.bench_function("key_gen_bench_512", |b| {
b.iter(|| generate_key_pair(None, 2))
b.iter(|| generate_keypair_512(None))
});
}

pub fn gen_key_benchmark_768(c: &mut Criterion) {
c.bench_function("key_gen_bench_768", |b| {
b.iter(|| generate_key_pair(None, 3))
b.iter(|| generate_keypair_768(None))
});
}

pub fn gen_key_benchmark_1024(c: &mut Criterion) {
c.bench_function("key_gen_bench_1024", |b| {
b.iter(|| generate_key_pair(None, 4))
b.iter(|| generate_keypair_1024(None))
});
}

pub fn encap_benchmark_512(c: &mut Criterion) {
let (pk, _) = generate_key_pair(None, 2).unwrap();
let (pk, _) = generate_keypair_512(None).unwrap();
c.bench_function("encap_benchmark_512", |b| {
b.iter(|| pk.encapsulate(None, None))
});
}

pub fn encap_benchmark_768(c: &mut Criterion) {
let (pk, _) = generate_key_pair(None, 3).unwrap();
let (pk, _) = generate_keypair_768(None).unwrap();
c.bench_function("encap_benchmark_768", |b| {
b.iter(|| pk.encapsulate(None, None))
});
}

pub fn encap_benchmark_1024(c: &mut Criterion) {
let (pk, _) = generate_key_pair(None, 4).unwrap();
let (pk, _) = generate_keypair_1024(None).unwrap();
c.bench_function("encap_benchmark_1024", |b| {
b.iter(|| pk.encapsulate(None, None))
});
}

pub fn decap_benchmark_512(c: &mut Criterion) {
let (pk, sk) = generate_key_pair(None, 2).unwrap();
let (pk, sk) = generate_keypair_512(None).unwrap();
let (ciphertext_obj, _) = pk.encapsulate(None, None).unwrap();
c.bench_function("decap_benchmark_512", |b| {
b.iter(|| sk.decapsulate(ciphertext_obj.as_bytes()))
});
}

pub fn decap_benchmark_768(c: &mut Criterion) {
let (pk, sk) = generate_key_pair(None, 3).unwrap();
let (pk, sk) = generate_keypair_768(None).unwrap();
let (ciphertext_obj, _) = pk.encapsulate(None, None).unwrap();
c.bench_function("decap_benchmark_768", |b| {
b.iter(|| sk.decapsulate(ciphertext_obj.as_bytes()))
});
}

pub fn decap_benchmark_1024(c: &mut Criterion) {
let (pk, sk) = generate_key_pair(None, 4).unwrap();
let (pk, sk) = generate_keypair_1024(None).unwrap();
let (ciphertext_obj, _) = pk.encapsulate(None, None).unwrap();
c.bench_function("decap_benchmark_1024", |b| {
b.iter(|| sk.decapsulate(ciphertext_obj.as_bytes()))
Expand Down
150 changes: 101 additions & 49 deletions src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl Ciphertext {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (pk, sk) = generate_key_pair(None, 3).unwrap();
/// # let (pk, sk) = generate_keypair_768(None).unwrap();
/// let (ciphertext_obj, shared_secret) = pk.encapsulate(None, None)?;
/// let ciphertext = ciphertext_obj.as_bytes();
///
Expand Down Expand Up @@ -122,22 +122,33 @@ fn new_key_from_seed(
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
pub trait AcceptableRng: RngCore + CryptoRng {}

/// Generates a new keypair for a given security level.
pub(crate) fn generate_key_pair(
rng: Option<&mut dyn AcceptableRng>,
k: K,
) -> Result<(PublicKey, PrivateKey), KeyGenerationError> {
let mut seed = [0u8; 2 * SYMBYTES];

if let Some(rng) = rng {
rng.try_fill_bytes(&mut seed)?;
} else {
let mut chacha = ChaCha20Rng::from_entropy();
chacha.try_fill_bytes(&mut seed)?;
};

let sec_level = SecurityLevel::new(k);

new_key_from_seed(&seed, sec_level)
}

/// Generates a new keypair for the 512 Security Parameters.
///
/// # Inputs
/// - `rng`: (Optional) RNG to be used when generating the keypair. Must satisfy the
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
/// - `k`: The k value corresponding to the security value to be used:
///
/// | Security Level | K |
/// |----------------|---|
/// | 512 | 2 |
/// | 768 | 3 |
/// | 1024 | 4 |
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
///
/// # Outputs
/// - [`PublicKey`] object
Expand All @@ -151,34 +162,75 @@ pub trait AcceptableRng: RngCore + CryptoRng {}
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// let (pk, sk) = generate_key_pair(None, 3)?;
/// let (pk, sk) = generate_keypair_512(None)?;
///
/// # Ok::<(), enc_rust::errors::KeyGenerationError>(())
/// ```
pub fn generate_key_pair(
rng: Option<&mut dyn AcceptableRng>,
k: usize,
) -> Result<(PublicKey, PrivateKey), KeyGenerationError> {
let k_result = K::try_from(k);

if let Ok(k_value) = k_result {
let mut seed = [0u8; 2 * SYMBYTES];

if let Some(rng) = rng {
rng.try_fill_bytes(&mut seed)?;
} else {
let mut chacha = ChaCha20Rng::from_entropy();
chacha.try_fill_bytes(&mut seed)?;
};

let sec_level = SecurityLevel::new(k_value);
pub fn generate_keypair_512(rng: Option<&mut dyn AcceptableRng>) -> Result<(PublicKey, PrivateKey), KeyGenerationError> {
generate_key_pair(rng, K::Two)
}

return new_key_from_seed(&seed, sec_level);
}
/// Generates a new keypair for the 768 Security Parameters.
///
/// # Inputs
/// - `rng`: (Optional) RNG to be used when generating the keypair. Must satisfy the
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
///
/// # Outputs
/// - [`PublicKey`] object
/// - [`PrivateKey`] object
///
/// # Errors
/// Will return a [`KeyGenerationError`] if:
/// - Given invalid K value
/// - RNG fails
///
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// let (pk, sk) = generate_keypair_768(None)?;
///
/// # Ok::<(), enc_rust::errors::KeyGenerationError>(())
/// ```
pub fn generate_keypair_768(rng: Option<&mut dyn AcceptableRng>) -> Result<(PublicKey, PrivateKey), KeyGenerationError> {
generate_key_pair(rng, K::Three)
}

Err(CrystalsError::InvalidK(k).into())
/// Generates a new keypair for the 1024 Security Parameters.
///
/// # Inputs
/// - `rng`: (Optional) RNG to be used when generating the keypair. Must satisfy the
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
///
/// # Outputs
/// - [`PublicKey`] object
/// - [`PrivateKey`] object
///
/// # Errors
/// Will return a [`KeyGenerationError`] if:
/// - Given invalid K value
/// - RNG fails
///
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// let (pk, sk) = generate_keypair_1024(None)?;
///
/// # Ok::<(), enc_rust::errors::KeyGenerationError>(())
/// ```
pub fn generate_keypair_1024(rng: Option<&mut dyn AcceptableRng>) -> Result<(PublicKey, PrivateKey), KeyGenerationError> {
generate_key_pair(rng, K::Four)
}


impl PrivateKey {
pub(crate) const fn sec_level(&self) -> SecurityLevel {
self.sk.sec_level()
Expand All @@ -189,7 +241,7 @@ impl PrivateKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// let (_, sk) = generate_key_pair(None, 3)?;
/// let (_, sk) = generate_keypair_768(None)?;
/// let pk = sk.get_public_key();
///
/// # Ok::<(), enc_rust::errors::KeyGenerationError>(())
Expand All @@ -206,7 +258,7 @@ impl PrivateKey {
///
/// # Inputs
/// - `bytes`: Buffer for the private key to be packed into. For corresponding
/// security levels, `bytes` should be of length:
/// security levels, `bytes` should be of length:
///
/// | Security Level | Length |
/// |----------------|--------|
Expand All @@ -220,7 +272,7 @@ impl PrivateKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// let (_, sk) = generate_key_pair(None, 3).unwrap();
/// let (_, sk) = generate_keypair_768(None).unwrap();
/// let mut sk_bytes = [0u8; 2400];
/// sk.pack(&mut sk_bytes)?;
///
Expand Down Expand Up @@ -262,7 +314,7 @@ impl PrivateKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (pk, new_sk) = generate_key_pair(None, 3).unwrap();
/// # let (pk, new_sk) = generate_keypair_768(None).unwrap();
/// # let mut sk_bytes = [0u8; 2400];
/// # new_sk.pack(&mut sk_bytes)?;
/// let sk = PrivateKey::unpack(&sk_bytes)?;
Expand Down Expand Up @@ -305,7 +357,7 @@ impl PrivateKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (pk, sk) = generate_key_pair(None, 3).unwrap();
/// # let (pk, sk) = generate_keypair_768(None).unwrap();
/// # let (ciphertext_obj, secret) = pk.encapsulate(None, None).unwrap();
/// # let ciphertext = ciphertext_obj.as_bytes();
/// let shared_secret = sk.decapsulate(ciphertext)?;
Expand Down Expand Up @@ -356,7 +408,7 @@ impl PublicKey {
///
/// # Inputs
/// - `bytes`: Buffer for the public key to be packed into. For corresponding
/// security levels, `bytes` should be of length:
/// security levels, `bytes` should be of length:
///
/// | Security Level | Length |
/// |----------------|--------|
Expand All @@ -370,7 +422,7 @@ impl PublicKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (pk, sk) = generate_key_pair(None, 3).unwrap();
/// # let (pk, sk) = generate_keypair_768(None).unwrap();
/// let mut pk_bytes = [0u8; 1184];
/// pk.pack(&mut pk_bytes)?;
///
Expand Down Expand Up @@ -404,7 +456,7 @@ impl PublicKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (new_pk, sk) = generate_key_pair(None, 3).unwrap();
/// # let (new_pk, sk) = generate_keypair_768(None).unwrap();
/// # let mut pk_bytes = [0u8; 1184];
/// # new_pk.pack(&mut pk_bytes)?;
/// let pk = PublicKey::unpack(&pk_bytes)?;
Expand All @@ -423,11 +475,11 @@ impl PublicKey {
/// # Inputs
/// - `seed`: (Optional) a 64 byte slice used as a seed for randomness
/// - `rng`: (Optional) RNG to be used during encapsulation. Must satisfy the
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
/// [`RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html) and
/// [`CryptoRng`](https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html) traits.
/// If RNG is not present, then
/// [`ChaCha20`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
/// will be used.
///
/// # Outputs
/// - [`Ciphertext`] object
Expand All @@ -441,7 +493,7 @@ impl PublicKey {
/// # Example
/// ```
/// # use enc_rust::kem::*;
/// # let (pk, sk) = generate_key_pair(None, 3).unwrap();
/// # let (pk, sk) = generate_keypair_768(None).unwrap();
/// let (ciphertext_obj, shared_secret) = pk.encapsulate(None, None)?;
///
/// # Ok::<(), enc_rust::errors::EncryptionDecryptionError>(())
Expand Down
9 changes: 6 additions & 3 deletions src/tests/kem.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#![allow(warnings)]
#[cfg(test)]
mod kem_tests {
use crate::kem::*;
use crate::{
kem::*,
tests::params::params_tests::sec_level_strategy,
};
use proptest::prelude::*;

prop_compose! {
fn new_keypair()
(k in 2..=4)
(sec_level in sec_level_strategy())
-> (PublicKey, PrivateKey) {
generate_key_pair(None, k as usize).unwrap()
generate_key_pair(None, sec_level.k()).unwrap()
}
}

Expand Down

0 comments on commit 1c2d19a

Please sign in to comment.