-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit aba13f1
Showing
11 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/target | ||
**/*.rs.bk | ||
|
||
/target | ||
**/*.rs.bk | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "pqclean"] | ||
path = pqclean | ||
url = https://github.com/pqclean/PQClean.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[workspace] | ||
members=[ | ||
"pqcrypto-traits", | ||
"pqcrypto-kyber", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "pqcrypto-kyber" | ||
description = "Post-Quantum key-encapsulation mechanism Kyber768" | ||
version = "0.1.0" | ||
authors = ["Thom Wiggers <[email protected]>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
pqcrypto-traits = {path = "../pqcrypto-traits", version = "0.1.0" } | ||
libc = "0.2.0" | ||
|
||
[build-dependencies] | ||
cc = { version = "1.0" } | ||
glob = "0.3.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
extern crate cc; | ||
extern crate glob; | ||
|
||
use std::path::Path; | ||
|
||
|
||
fn main() { | ||
let target_dir = Path::new("../pqclean/crypto_kem/kyber768/clean"); | ||
let common_dir = Path::new("../pqclean/common"); | ||
let common_files = [ | ||
common_dir.join("fips202.c"), | ||
common_dir.join("notrandombytes.c"), | ||
common_dir.join("sha2.c"), | ||
]; | ||
|
||
let scheme_files = glob::glob(target_dir.join("*.c").to_str().unwrap()).unwrap(); | ||
cc::Build::new() | ||
.include("../pqclean/common") | ||
.include(target_dir) | ||
.files(common_files.into_iter()) | ||
.files(scheme_files.into_iter().map(|p| p.unwrap().to_string_lossy().into_owned())) | ||
.compile("libkyber768.a"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#![allow(unused)] | ||
use libc::c_int; | ||
|
||
pub const PQCLEAN_KYBER768_CLEAN_CRYPTO_SECRETKEYBYTES: usize = 2400; | ||
pub const PQCLEAN_KYBER768_CLEAN_CRYPTO_PUBLICKEYBYTES: usize = 1088; | ||
pub const PQCLEAN_KYBER768_CLEAN_CRYPTO_CIPHERTEXTBYTES: usize = 1152; | ||
pub const PQCLEAN_KYBER768_CLEAN_CRYPTO_BYTES: usize = 32; | ||
|
||
#[link(name = "kyber768")] | ||
extern "C" { | ||
pub fn PQCLEAN_KYBER768_CLEAN_crypto_kem_keypair(pk: *mut u8, sk: *mut u8) -> c_int; | ||
pub fn PQCLEAN_KYBER768_CLEAN_crypto_kem_enc(ct: *mut u8, ss: *mut u8, pk: *const u8) -> c_int; | ||
pub fn PQCLEAN_KYBER768_CLEAN_crypto_kem_dec( | ||
ss: *mut u8, | ||
ct: *const u8, | ||
sk: *const u8, | ||
) -> c_int; | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
use std::mem; | ||
#[test] | ||
fn test_ffi() { | ||
unsafe { | ||
let mut pk: [u8; PQCLEAN_KYBER768_CLEAN_CRYPTO_PUBLICKEYBYTES] = mem::uninitialized(); | ||
let mut sk: [u8; PQCLEAN_KYBER768_CLEAN_CRYPTO_SECRETKEYBYTES] = mem::uninitialized(); | ||
let mut ct: [u8; PQCLEAN_KYBER768_CLEAN_CRYPTO_CIPHERTEXTBYTES] = mem::uninitialized(); | ||
let mut ss1: [u8; PQCLEAN_KYBER768_CLEAN_CRYPTO_BYTES] = mem::uninitialized(); | ||
let mut ss2: [u8; PQCLEAN_KYBER768_CLEAN_CRYPTO_BYTES] = mem::uninitialized(); | ||
|
||
assert_eq!( | ||
0, | ||
PQCLEAN_KYBER768_CLEAN_crypto_kem_keypair(pk.as_mut_ptr(), sk.as_mut_ptr()) | ||
); | ||
assert_eq!( | ||
0, | ||
PQCLEAN_KYBER768_CLEAN_crypto_kem_enc( | ||
ct.as_mut_ptr(), | ||
ss1.as_mut_ptr(), | ||
pk.as_ptr() | ||
) | ||
); | ||
assert_eq!( | ||
0, | ||
PQCLEAN_KYBER768_CLEAN_crypto_kem_dec(ss2.as_mut_ptr(), ct.as_ptr(), sk.as_ptr()) | ||
); | ||
assert_eq!(ss1, ss2); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//! Kyber 768 | ||
//! | ||
//! Kyber is an IND-CCA2-secure key encapsulation mechanism (KEM), whose security is based on the | ||
//! hardness of solving the learning-with-errors (LWE) problem over module lattices. Kyber is one | ||
//! of the candidate algorithms submitted to the NIST post-quantum cryptography project. The | ||
//! submission lists three different parameter sets aiming at different security levels. | ||
//! Specifically, Kyber-512 aims at security roughly equivalent to AES-128, Kyber-768 aims at | ||
//! security roughly equivalent to AES-192, and Kyber-1024 aims at security roughly equivalent to | ||
//! AES-256. | ||
//! | ||
//! https://pq-crystals.org/kyber/ | ||
//! | ||
//! # Examples | ||
//! ``` | ||
//! use pqcrypto_kyber::*; | ||
//! let (pk, sk) = keygen(); | ||
//! let (ss1, ct) = encapsulate(pk); | ||
//! let ss2 = decapsulate(ct, sk); | ||
//! assert!(ss1 == ss2); | ||
//! ``` | ||
use std::mem; | ||
|
||
pub mod ffi; | ||
use pqcrypto_traits::kem; | ||
|
||
macro_rules! simple_struct { | ||
($type: ident, $size: expr) => { | ||
pub struct $type([u8; $size]); | ||
|
||
impl $type { | ||
/// Generates an uninitialized object | ||
/// | ||
/// Used to pass to ``ffi`` interfaces. | ||
/// | ||
/// Internal use only! | ||
fn new() -> Self { | ||
$type(unsafe { mem::uninitialized() }) | ||
} | ||
} | ||
|
||
impl kem::$type for $type { | ||
/// Get this object as a byte slice | ||
#[inline] | ||
fn as_bytes(&self) -> &[u8] { | ||
&self.0 | ||
} | ||
|
||
/// Construct this object from a byte slice | ||
fn from_bytes(bytes: &[u8]) -> Self { | ||
let mut array: [u8; $size] = unsafe { mem::uninitialized() }; | ||
array.copy_from_slice(bytes); | ||
$type(array) | ||
} | ||
} | ||
|
||
impl PartialEq for $type { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.0 | ||
.iter() | ||
.zip(other.0.iter()) | ||
.try_for_each(|(a, b)| if a == b { Ok(()) } else { Err(()) }) | ||
.is_ok() | ||
} | ||
} | ||
}; | ||
} | ||
|
||
simple_struct!(PublicKey, ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_PUBLICKEYBYTES); | ||
simple_struct!(SecretKey, ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_SECRETKEYBYTES); | ||
simple_struct!( | ||
Ciphertext, | ||
ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_CIPHERTEXTBYTES | ||
); | ||
simple_struct!(SharedSecret, ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_BYTES); | ||
|
||
pub const fn public_key_bytes() -> usize { | ||
ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_PUBLICKEYBYTES | ||
} | ||
|
||
pub const fn secret_key_bytes() -> usize { | ||
ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_SECRETKEYBYTES | ||
} | ||
|
||
pub const fn ciphertext_bytes() -> usize { | ||
ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_CIPHERTEXTBYTES | ||
} | ||
|
||
pub const fn shared_secret_bytes() -> usize { | ||
ffi::PQCLEAN_KYBER768_CLEAN_CRYPTO_BYTES | ||
} | ||
|
||
pub fn keygen() -> (PublicKey, SecretKey) { | ||
let mut pk = PublicKey::new(); | ||
let mut sk = SecretKey::new(); | ||
assert_eq!( | ||
unsafe { | ||
ffi::PQCLEAN_KYBER768_CLEAN_crypto_kem_keypair(pk.0.as_mut_ptr(), sk.0.as_mut_ptr()) | ||
}, | ||
0 | ||
); | ||
(pk, sk) | ||
} | ||
|
||
pub fn encapsulate(pk: PublicKey) -> (SharedSecret, Ciphertext) { | ||
let mut ss = SharedSecret::new(); | ||
let mut ct = Ciphertext::new(); | ||
|
||
assert_eq!( | ||
unsafe { | ||
ffi::PQCLEAN_KYBER768_CLEAN_crypto_kem_enc( | ||
ct.0.as_mut_ptr(), | ||
ss.0.as_mut_ptr(), | ||
pk.0.as_ptr(), | ||
) | ||
}, | ||
0, | ||
); | ||
|
||
(ss, ct) | ||
} | ||
|
||
pub fn decapsulate(ct: Ciphertext, sk: SecretKey) -> SharedSecret { | ||
let mut ss = SharedSecret::new(); | ||
assert_eq!( | ||
unsafe { | ||
ffi::PQCLEAN_KYBER768_CLEAN_crypto_kem_dec( | ||
ss.0.as_mut_ptr(), | ||
ct.0.as_ptr(), | ||
sk.0.as_ptr(), | ||
) | ||
}, | ||
0 | ||
); | ||
ss | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[test] | ||
pub fn test_kem() { | ||
let (pk, sk) = keygen(); | ||
let (ss1, ct) = encapsulate(pk); | ||
let ss2 = decapsulate(ct, sk); | ||
assert!(ss1.0 == ss2.0, "Difference in shared secrets!"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "pqcrypto-traits" | ||
version = "0.1.0" | ||
authors = ["Thom Wiggers <[email protected]>"] | ||
edition = "2018" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
pub trait PublicKey { | ||
fn as_bytes(&self) -> &[u8]; | ||
fn from_bytes(bytes: &[u8]) -> Self where Self: Sized; | ||
} | ||
|
||
pub trait SecretKey { | ||
fn as_bytes(&self) -> &[u8]; | ||
fn from_bytes(bytes: &[u8]) -> Self where Self: Sized; | ||
} | ||
|
||
pub trait Ciphertext { | ||
fn as_bytes(&self) -> &[u8]; | ||
fn from_bytes(bytes: &[u8]) -> Self where Self: Sized; | ||
} | ||
|
||
pub trait SharedSecret { | ||
fn as_bytes(&self) -> &[u8]; | ||
fn from_bytes(bytes: &[u8]) -> Self where Self: Sized; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod kem; |