Skip to content

Commit

Permalink
Add derandomized kyber768 ref from libjade-sys (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
xvzcf authored Aug 1, 2023
1 parent 85f5eff commit 1a1e207
Show file tree
Hide file tree
Showing 13 changed files with 19,130 additions and 159 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ${{ matrix.os }}

steps:

- name: Setup Ubuntu
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install ninja-build
Expand Down
10 changes: 8 additions & 2 deletions src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,19 @@ pub type Sha3_512Digest = [u8; digest_size(Algorithm::Sha3_512)];

macro_rules! sha3_impl {
($fun_name:ident, $output:ty, $jasmin_fun:expr, $hacl_fun:expr) => {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
any(target_os = "linux", target_os = "macos")
))]
pub fn $fun_name(payload: &[u8]) -> $output {
// On x64 we use Jasmin for AVX2 and fallback.
$jasmin_fun(payload)
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
any(target_os = "linux", target_os = "macos")
)))]
pub fn $fun_name(payload: &[u8]) -> $output {
// On all other platforms we use HACL
$hacl_fun(payload)
Expand Down
14 changes: 14 additions & 0 deletions src/jasmin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,17 @@ pub mod poly1305;
pub mod sha2;
pub mod sha3;
pub mod x25519;
pub mod kyber_derand;

#[cfg(test)]
mod testing {
use std::fmt::Write;

pub(crate) fn bytes_to_hex(bytes: &[u8]) -> String {
let mut s = String::with_capacity(2 * bytes.len());
for byte in bytes {
write!(s, "{:02x}", byte).unwrap();
}
s
}
}
107 changes: 107 additions & 0 deletions src/jasmin/kyber_derand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Allow dead code for now.
// The libjade code here isn't verified yet and thus isn't used.
#![allow(dead_code)]

use libjade_sys::{
jade_kem_kyber_kyber768_amd64_ref_dec, jade_kem_kyber_kyber768_amd64_ref_enc_derand,
jade_kem_kyber_kyber768_amd64_ref_keypair_derand,
};

type Kyber768KeypairSeed = [u8; 64];

type Kyber768PublicKey = [u8; 1184];
type Kyber768SecretKey = [u8; 2400];

type Kyber768EncapsulateSeed = [u8; 32];

type Kyber768Ciphertext = [u8; 1088];
type Kyber768SharedSecret = [u8; 32];

fn kyber768_keypair_derand_ref(
seed: Kyber768KeypairSeed,
) -> Result<(Kyber768PublicKey, Kyber768SecretKey), &'static str> {
let mut public_key: Kyber768PublicKey = [0; 1184];
let mut secret_key: Kyber768SecretKey = [0; 2400];

log::trace!("Jasmin kyber768 keypair_derand ref");
let r = unsafe {
jade_kem_kyber_kyber768_amd64_ref_keypair_derand(
public_key.as_mut_ptr(),
secret_key.as_mut_ptr(),
seed.as_ptr() as _,
)
};

if r != 0 {
Err("Error while generating kyber768 keypair.")
} else {
Ok((public_key, secret_key))
}
}

fn kyber768_enc_derand_ref(
public_key: Kyber768PublicKey,
seed: Kyber768EncapsulateSeed,
) -> Result<(Kyber768Ciphertext, Kyber768SharedSecret), &'static str> {
let mut ciphertext: Kyber768Ciphertext = [0; 1088];
let mut shared_secret = Kyber768SharedSecret::default();

log::trace!("Jasmin kyber768 enc_derand ref");
let r = unsafe {
jade_kem_kyber_kyber768_amd64_ref_enc_derand(
ciphertext.as_mut_ptr(),
shared_secret.as_mut_ptr(),
public_key.as_ptr() as _,
seed.as_ptr() as _,
)
};

if r != 0 {
Err("Error while running kyber768 derandomized encapsulated.")
} else {
Ok((ciphertext, shared_secret))
}
}

fn kyber768_dec_ref(
ciphertext: Kyber768Ciphertext,
secret_key: Kyber768SecretKey,
) -> Result<Kyber768SharedSecret, &'static str> {
let mut shared_secret = Kyber768SharedSecret::default();

log::trace!("Jasmin kyber768 dec ref");
let r = unsafe {
jade_kem_kyber_kyber768_amd64_ref_dec(
shared_secret.as_mut_ptr(),
ciphertext.as_ptr() as _,
secret_key.as_ptr() as _,
)
};

if r != 0 {
Err("Error while running kyber768 decapsulate.")
} else {
Ok(shared_secret)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn consistency_test() {
let _ = pretty_env_logger::try_init();

let keypair_seed = [0u8; 64];
let enc_seed = [0u8; 32];

let (public_key, secret_key) = kyber768_keypair_derand_ref(keypair_seed).unwrap();

let (ciphertext, shared_secret) = kyber768_enc_derand_ref(public_key, enc_seed).unwrap();

let shared_secret_decapsulated = kyber768_dec_ref(ciphertext, secret_key).unwrap();

assert_eq!(shared_secret_decapsulated, shared_secret);
}
}
18 changes: 18 additions & 0 deletions src/jasmin/sha2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,21 @@ pub fn sha256(input: &[u8]) -> Result<Sha256Digest, &'static str> {
Ok(digest)
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::jasmin::testing::bytes_to_hex;

#[test]
fn test_hash() {
let _ = pretty_env_logger::try_init();

let input = b"jasmin rulez" as &[u8];
let digest = sha256(input).unwrap();

println!("{:x?}", digest);
let expected = "16096ecad8aa127418804b21c8e2fe93c31453d66a7e9588a429813c968bddd1";
assert_eq!(expected, bytes_to_hex(&digest));
}
}
36 changes: 36 additions & 0 deletions src/jasmin/x25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,39 @@ pub(crate) mod mulx {
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::jasmin::testing::bytes_to_hex;

fn bmi2_and_adx_are_supported() -> bool {
std::arch::is_x86_feature_detected!("bmi2") && std::arch::is_x86_feature_detected!("adx")
}

#[test]
fn test_derive() {
let _ = pretty_env_logger::try_init();

let public = [
0x50, 0x4a, 0x36, 0x99, 0x9f, 0x48, 0x9c, 0xd2, 0xfd, 0xbc, 0x08, 0xba, 0xff, 0x3d,
0x88, 0xfa, 0x00, 0x56, 0x9b, 0xa9, 0x86, 0xcb, 0xa2, 0x25, 0x48, 0xff, 0xde, 0x80,
0xf9, 0x80, 0x68, 0x29,
];
let private = [
0xc8, 0xa9, 0xd5, 0xa9, 0x10, 0x91, 0xad, 0x85, 0x1c, 0x66, 0x8b, 0x07, 0x36, 0xc1,
0xc9, 0xa0, 0x29, 0x36, 0xc0, 0xd3, 0xad, 0x62, 0x67, 0x08, 0x58, 0x08, 0x80, 0x47,
0xba, 0x05, 0x74, 0x75,
];

let shared = if bmi2_and_adx_are_supported() {
mulx::derive(&private, &public).unwrap()
} else {
derive(&private, &public).unwrap()
};

println!("{:x?}", shared);
let expected = "436a2c040cf45fea9b29a0cb81b1f41458f863d0d61b453d0a982720d6d61320";
assert_eq!(expected, bytes_to_hex(&shared));
}
}
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ pub(crate) mod hw_detection;
pub use hw_detection::aes_ni_support;

// Jasmin
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
any(target_os = "linux", target_os = "macos")
))]
pub(crate) mod jasmin;

// libcrux
Expand Down
3 changes: 3 additions & 0 deletions sys/libjade/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ mod x64_build {
.allowlist_var("JADE_ONETIMEAUTH_POLY1305_.*")
.allowlist_function("jade_stream_chacha_chacha20.*")
.allowlist_var("JADE_STREAM_CHACHA_CHACHA20_.*")
.allowlist_function("jade_kem_kyber_kyber768_.*")
.allowlist_var("JADE_KEM_KYBER_KYBER768_.*")
// Block everything we don't need or define ourselves.
.blocklist_type("__.*")
// Disable tests to avoid warnings and keep it portable
Expand Down Expand Up @@ -114,6 +116,7 @@ mod x64_build {
"sha3_512_ref.s",
"chacha20_ref.s",
"poly1305_ref.s",
"kyber_kyber768_ref.s",
];
let mut all_files = files.clone();

Expand Down
34 changes: 34 additions & 0 deletions sys/libjade/jazz/include/kyber_kyber768_ref.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef JADE_KEM_KYBER_KYBER768_AMD64_REF_API_H
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_API_H

#include <stdint.h>

#define JADE_KEM_KYBER_KYBER768_AMD64_REF_SECRETKEYBYTES 2400
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_PUBLICKEYBYTES 1184
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_CIPHERTEXTBYTES 1088
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_KEYPAIRCOINBYTES 64
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_ENCCOINBYTES 32
#define JADE_KEM_KYBER_KYBER768_AMD64_REF_BYTES 32

#define JADE_KEM_KYBER_KYBER768_AMD64_REF_ALGNAME "Kyber768"

int jade_kem_kyber_kyber768_amd64_ref_keypair_derand(
uint8_t *public_key,
uint8_t *secret_key,
const uint8_t *coins
);

int jade_kem_kyber_kyber768_amd64_ref_enc_derand(
uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key,
const uint8_t *coins
);

int jade_kem_kyber_kyber768_amd64_ref_dec(
uint8_t *shared_secret,
const uint8_t *ciphertext,
const uint8_t *secret_key
);

#endif
1 change: 1 addition & 0 deletions sys/libjade/jazz/include/libjade.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "sha3_512_ref.h"
#include "poly1305_ref.h"
#include "chacha20_ref.h"
#include "kyber_kyber768_ref.h"

#ifdef SIMD256
#include "sha3_224_avx2.h"
Expand Down
Loading

0 comments on commit 1a1e207

Please sign in to comment.