Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added derandomized kyber to libjade-sys. #23

Merged
merged 6 commits into from
Aug 1, 2023
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
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(
franziskuskiefer marked this conversation as resolved.
Show resolved Hide resolved
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