Skip to content

Commit

Permalink
ct_cm4 update
Browse files Browse the repository at this point in the history
  • Loading branch information
eschorn1 committed Mar 23, 2024
1 parent 1bb2e9f commit f8ab279
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 166 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ harness = false

[profile.dev]
debug = true
lto = true
opt-level = 3
codegen-units = 1
#lto = true
#opt-level = 3
#codegen-units = 1


[profile.release]
Expand Down
29 changes: 22 additions & 7 deletions benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ struct BenchRng();

impl RngCore for BenchRng {
fn next_u32(&mut self) -> u32 { unimplemented!() }

fn next_u64(&mut self) -> u64 { unimplemented!() }

fn fill_bytes(&mut self, out: &mut [u8]) { out.iter_mut().for_each(|b| *b = 0); }

fn try_fill_bytes(&mut self, out: &mut [u8]) -> Result<(), rand_core::Error> {
self.fill_bytes(out);
Ok(())
Expand All @@ -31,13 +34,25 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let (ek_1024, dk_1024) = ml_kem_1024::KG::try_keygen_with_rng_vt(&mut bench_rng).unwrap();
let (_, ct_1024) = ek_1024.try_encaps_vt().unwrap();

c.bench_function("ml_kem_512 KeyGen", |b| b.iter(|| ml_kem_512::KG::try_keygen_with_rng_vt(&mut bench_rng)));
c.bench_function("ml_kem_768 KeyGen", |b| b.iter(|| ml_kem_768::KG::try_keygen_with_rng_vt(&mut bench_rng)));
c.bench_function("ml_kem_1024 KeyGen", |b| b.iter(|| ml_kem_1024::KG::try_keygen_with_rng_vt(&mut bench_rng)));

c.bench_function("ml_kem_512 Encaps", |b| b.iter(|| ek_512.try_encaps_with_rng_vt(&mut bench_rng)));
c.bench_function("ml_kem_768 Encaps", |b| b.iter(|| ek_768.try_encaps_with_rng_vt(&mut bench_rng)));
c.bench_function("ml_kem_1024 Encaps", |b| b.iter(|| ek_1024.try_encaps_with_rng_vt(&mut bench_rng)));
c.bench_function("ml_kem_512 KeyGen", |b| {
b.iter(|| ml_kem_512::KG::try_keygen_with_rng_vt(&mut bench_rng))
});
c.bench_function("ml_kem_768 KeyGen", |b| {
b.iter(|| ml_kem_768::KG::try_keygen_with_rng_vt(&mut bench_rng))
});
c.bench_function("ml_kem_1024 KeyGen", |b| {
b.iter(|| ml_kem_1024::KG::try_keygen_with_rng_vt(&mut bench_rng))
});

c.bench_function("ml_kem_512 Encaps", |b| {
b.iter(|| ek_512.try_encaps_with_rng_vt(&mut bench_rng))
});
c.bench_function("ml_kem_768 Encaps", |b| {
b.iter(|| ek_768.try_encaps_with_rng_vt(&mut bench_rng))
});
c.bench_function("ml_kem_1024 Encaps", |b| {
b.iter(|| ek_1024.try_encaps_with_rng_vt(&mut bench_rng))
});

c.bench_function("ml_kem_512 Decaps", |b| b.iter(|| dk_512.try_decaps_vt(&ct_512)));
c.bench_function("ml_kem_768 Decaps", |b| b.iter(|| dk_768.try_decaps_vt(&ct_768)));
Expand Down
20 changes: 15 additions & 5 deletions ct_cm4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ edition = "2021"

[dependencies]
fips203 = { path = "..", default-features = false, features = ["ml-kem-512"] }
cortex-m-semihosting = "0.5.0"
panic-semihosting = { version = "0.6.0", features = ["exit"] }
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.6.15" # Required by 'most recent' version of stm32f3-discovery below
stm32f3-discovery = "0.7.2"
panic-itm = "0.4.2"
cortex-m-rt = "0.7.3"
panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] }
microbit-v2 = "0.13.0"
rtt-target = { version = "0.5.0" } #, features = ["cortex-m"] }
rand_core = { version = "0.6.4", default-features = false }
hex-literal = "0.4.1"
rand_chacha = { version = "0.3.1", default-features = false }


[profile.dev]
debug = true
debug-assertions = false
overflow-checks = false
lto = true
opt-level = 3
codegen-units = 1


# cargo update -p fixed@1.26.0 --precise 1.23.1
14 changes: 14 additions & 0 deletions ct_cm4/Embed.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[default.general]
chip = "nrf52833_xxAA"

#[default.reset]
#halt_afterwards = true

[default.rtt]
enabled = true

[default.gdb]
enabled = false

[default.probe]
protocol = "Swd"
43 changes: 8 additions & 35 deletions ct_cm4/README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,10 @@
An example for the STM Discovery Board -- https://docs.rust-embedded.org/discovery/f3discovery/index.html
An example for the Microbit v2 Board -- <https://docs.rust-embedded.org/discovery/microbit/index.html>

One-off setup:
This example demonstrates the full loop of keygen, encaps then decaps functionality.
Cycle counts are measured, displayed, and operation confirmed to be constant-time.
See the link above for tooling setup.

~~~
rustup target add thumbv7em-none-eabihf
rustup component add llvm-tools-preview
~~~

You will need to be running with two windows in parallel.

1. In the first window:

~~~
$ cd ct_cm4 # <here>
$ cargo build --target thumbv7em-none-eabihf
$ cargo readobj --target thumbv7em-none-eabihf --bin ct_cm4-fips203 -- --file-header # double-checks built object
$ cargo size --bin ct_cm4-fips203 --release -- -A
~~~

2. In the second window:

~~~
$ cd /tmp && openocd -f interface/stlink-v2-1.cfg -f target/stm32f3x.cfg
~~~

3. Back to the first window:

~~~
$ cargo run
then:
layout src
break k_pke.rs:29
continue
s
~~~
~~~
$ cd ct_cm4 # <here>
$ cargo embed
~~~
37 changes: 0 additions & 37 deletions ct_cm4/openocd.gdb

This file was deleted.

76 changes: 31 additions & 45 deletions ct_cm4/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,53 @@
#![no_std]
#![no_main]

use cortex_m::peripheral::DWT;
use cortex_m::asm;
use cortex_m_rt::entry;
use fips203::ml_kem_512;
use fips203::traits::KeyGen;
use rand_core::{CryptoRng, RngCore};
use stm32f3_discovery::leds::Leds;
use stm32f3_discovery::stm32f3xx_hal::{pac, prelude::*};
use stm32f3_discovery::switch_hal::ToggleableOutputSwitch;
use fips203::traits::{Decaps, Encaps, KeyGen, SerDes};
use microbit::{board::Board, hal::{pac::DWT, prelude::OutputPin}};
use rand_chacha::rand_core::SeedableRng;
use rtt_target::{rprintln, rtt_init_print};


// Dummy RNG that regurgitates zeros when 'asked'
struct MyRng();
impl RngCore for MyRng {
fn next_u32(&mut self) -> u32 { unimplemented!() }
fn next_u64(&mut self) -> u64 { unimplemented!() }
fn fill_bytes(&mut self, out: &mut [u8]) { out.iter_mut().for_each(|b| *b = 0); }
fn try_fill_bytes(&mut self, out: &mut [u8]) -> Result<(), rand_core::Error> {
self.fill_bytes(out);
Ok(())
}
}
impl CryptoRng for MyRng {}


#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }
use panic_rtt_target as _;


#[entry]
fn main() -> ! {

// Configure MCU
let device_peripherals = pac::Peripherals::take().unwrap();
let mut reset_and_clock_control = device_peripherals.RCC.constrain();

// Initialize LEDs
let mut gpioe = device_peripherals.GPIOE.split(&mut reset_and_clock_control.ahb);
#[rustfmt::skip]
let mut leds = Leds::new(gpioe.pe8, gpioe.pe9, gpioe.pe10, gpioe.pe11, gpioe.pe12,
gpioe.pe13, gpioe.pe14, gpioe.pe15, &mut gpioe.moder, &mut gpioe.otyper).into_array();

let mut my_rng = MyRng {};
let mut board = Board::take().unwrap();
board.DCB.enable_trace();
board.DWT.enable_cycle_counter();
board.display_pins.col1.set_low().unwrap();
rtt_init_print!();

let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123);
let mut expected_cycles = 0;
let mut i = 0u32;

loop {
if (i % 10) == 0 { leds[0].toggle().ok(); };
if (i % 100) == 0 { board.display_pins.row1.set_high().unwrap(); };
if (i % 100) == 50 { board.display_pins.row1.set_low().unwrap(); };
i += 1;

cortex_m::asm::isb();
rng.set_word_pos(1024 * i as u128); // Removes odd variability in drawing rng data

asm::isb();
let start = DWT::cycle_count();
cortex_m::asm::isb();
asm::isb();

let _res1 = ml_kem_512::KG::try_keygen_with_rng_vt(&mut my_rng);
let (ek, dk) = ml_kem_512::KG::try_keygen_with_rng_vt(&mut rng).unwrap();
let (ssk1, ct) = ek.try_encaps_with_rng_vt(&mut rng).unwrap();
let ssk2 = dk.try_decaps_vt(&ct).unwrap();

cortex_m::asm::isb();
asm::isb();
let finish = DWT::cycle_count();
cortex_m::asm::isb();
asm::isb();

assert_eq!(ssk1.into_bytes(), ssk2.into_bytes());

// Code will 'soon' present the cycle counts via semi-hosting,
// and will also include encaps/decaps cycle
let _count = finish - start;
// print_semi("Top", _count);
let count = finish - start;
if (i == 5) & (expected_cycles == 0) { expected_cycles = count };
if (i > 5) & (count != expected_cycles) { panic!("Non constant-time operation!!") };
if i % 10 == 0 { rprintln!("Iteration {} cycle count: {}", i, count); }
}
}
3 changes: 1 addition & 2 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use sha3::{Digest, Sha3_256, Sha3_512, Shake128, Shake256};
use sha3::digest::{ExtendableOutput, XofReader};
use sha3::digest::Update;
use sha3::digest::{ExtendableOutput, Update, XofReader};

use crate::ntt::multiply_ntts;
use crate::Q;
Expand Down
Loading

0 comments on commit f8ab279

Please sign in to comment.