From f6e6d728ac804af56243082c27779464a61b200a Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Mon, 10 Oct 2022 13:41:24 -0400 Subject: [PATCH 1/3] Switched STROBE dependency to strobe-rs to see if it fixes the BigEndian issue; also updated deps --- Cargo.toml | 9 ++++++--- src/lib.rs | 10 ---------- src/transcript.rs | 11 +++++------ 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5842c6b..c8ed604 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,14 +18,17 @@ exclude = [".travis.yml", ".gitignore"] features = ["nightly"] [dependencies] -keccak = { version = "0.1.0", default-features = false } -byteorder = { version = "1.2.4", default-features = false } +keccak = { version = "0.1", default-features = false } +byteorder = { version = "1.2", default-features = false } zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } rand_core = { version = "0.5", default-features = false } hex = {version = "0.3", default-features = false, optional = true} +[dependencies.strobe-rs] +git = "https://github.com/rozbb/strobe-rs" +rev = "2b2c677a3c8a36349f439195c0e086441aab3de1" + [dev-dependencies] -strobe-rs = "0.5" curve25519-dalek = "2" rand_chacha = "0.2" diff --git a/src/lib.rs b/src/lib.rs index 858614c..be2c95f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,17 +6,7 @@ //! Note that docs will only build on nightly Rust until //! [RFC 1990 stabilizes](https://github.com/rust-lang/rust/issues/44732). -#[cfg(target_endian = "big")] -compile_error!( - r#" -This crate doesn't support big-endian targets, since I didn't -have one to test correctness on. If you're seeing this message, -please file an issue! -"# -); - mod constants; -mod strobe; mod transcript; pub use crate::transcript::Transcript; diff --git a/src/transcript.rs b/src/transcript.rs index 9b72f48..ac6c3e0 100644 --- a/src/transcript.rs +++ b/src/transcript.rs @@ -1,8 +1,7 @@ use rand_core; +use strobe_rs::{SecParam, Strobe}; use zeroize::Zeroize; -use crate::strobe::Strobe128; - fn encode_u64(x: u64) -> [u8; 8] { use byteorder::{ByteOrder, LittleEndian}; @@ -52,7 +51,7 @@ fn encode_usize_as_u32(x: usize) -> [u8; 4] { /// Merlin](https://merlin.cool/use/index.html) section. #[derive(Clone, Zeroize)] pub struct Transcript { - strobe: Strobe128, + strobe: Strobe, } impl Transcript { @@ -80,7 +79,7 @@ impl Transcript { } let mut transcript = Transcript { - strobe: Strobe128::new(MERLIN_PROTOCOL_LABEL), + strobe: Strobe::new(MERLIN_PROTOCOL_LABEL, SecParam::B128), }; transcript.append_message(b"dom-sep", label); @@ -279,7 +278,7 @@ impl Transcript { /// [rekey_with_witness_bytes]: TranscriptRngBuilder::rekey_with_witness_bytes /// [finalize]: TranscriptRngBuilder::finalize pub struct TranscriptRngBuilder { - strobe: Strobe128, + strobe: Strobe, } impl TranscriptRngBuilder { @@ -349,7 +348,7 @@ impl TranscriptRngBuilder { /// Randomness](https://merlin.cool/transcript/rng.html) section of /// the Merlin website. pub struct TranscriptRng { - strobe: Strobe128, + strobe: Strobe, } impl rand_core::RngCore for TranscriptRng { From 874040cfa455afb1c068dedf947427b9cb164a23 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Mon, 10 Oct 2022 15:59:40 -0400 Subject: [PATCH 2/3] Moved STROBE dep away from a git/rev requirement --- Cargo.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c8ed604..eac5330 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,7 @@ byteorder = { version = "1.2", default-features = false } zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } rand_core = { version = "0.5", default-features = false } hex = {version = "0.3", default-features = false, optional = true} - -[dependencies.strobe-rs] -git = "https://github.com/rozbb/strobe-rs" -rev = "2b2c677a3c8a36349f439195c0e086441aab3de1" +strobe-rs = "0.8" [dev-dependencies] curve25519-dalek = "2" From 7afc51ebeaf130f940ec0c23074137f4d9122e86 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Mon, 10 Oct 2022 16:01:41 -0400 Subject: [PATCH 3/3] Removed local STROBE impl --- src/strobe.rs | 233 -------------------------------------------------- 1 file changed, 233 deletions(-) delete mode 100644 src/strobe.rs diff --git a/src/strobe.rs b/src/strobe.rs deleted file mode 100644 index ff0436f..0000000 --- a/src/strobe.rs +++ /dev/null @@ -1,233 +0,0 @@ -//! Minimal implementation of (parts of) Strobe. - -use core::ops::{Deref, DerefMut}; - -use keccak; -use zeroize::Zeroize; - -/// Strobe R value; security level 128 is hardcoded -const STROBE_R: u8 = 166; - -const FLAG_I: u8 = 1; -const FLAG_A: u8 = 1 << 1; -const FLAG_C: u8 = 1 << 2; -const FLAG_T: u8 = 1 << 3; -const FLAG_M: u8 = 1 << 4; -const FLAG_K: u8 = 1 << 5; - -fn transmute_state(st: &mut AlignedKeccakState) -> &mut [u64; 25] { - unsafe { &mut *(st as *mut AlignedKeccakState as *mut [u64; 25]) } -} - -/// This is a wrapper around 200-byte buffer that's always 8-byte aligned -/// to make pointers to it safely convertible to pointers to [u64; 25] -/// (since u64 words must be 8-byte aligned) -#[derive(Clone, Zeroize)] -#[zeroize(drop)] -#[repr(align(8))] -struct AlignedKeccakState([u8; 200]); - -/// A Strobe context for the 128-bit security level. -/// -/// Only `meta-AD`, `AD`, `KEY`, and `PRF` operations are supported. -#[derive(Clone, Zeroize)] -pub struct Strobe128 { - state: AlignedKeccakState, - pos: u8, - pos_begin: u8, - cur_flags: u8, -} - -impl ::core::fmt::Debug for Strobe128 { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - // Ensure that the Strobe state isn't accidentally logged - write!(f, "Strobe128: STATE OMITTED") - } -} - -impl Strobe128 { - pub fn new(protocol_label: &[u8]) -> Strobe128 { - let initial_state = { - let mut st = AlignedKeccakState([0u8; 200]); - st[0..6].copy_from_slice(&[1, STROBE_R + 2, 1, 0, 1, 96]); - st[6..18].copy_from_slice(b"STROBEv1.0.2"); - keccak::f1600(transmute_state(&mut st)); - - st - }; - - let mut strobe = Strobe128 { - state: initial_state, - pos: 0, - pos_begin: 0, - cur_flags: 0, - }; - - strobe.meta_ad(protocol_label, false); - - strobe - } - - pub fn meta_ad(&mut self, data: &[u8], more: bool) { - self.begin_op(FLAG_M | FLAG_A, more); - self.absorb(data); - } - - pub fn ad(&mut self, data: &[u8], more: bool) { - self.begin_op(FLAG_A, more); - self.absorb(data); - } - - pub fn prf(&mut self, data: &mut [u8], more: bool) { - self.begin_op(FLAG_I | FLAG_A | FLAG_C, more); - self.squeeze(data); - } - - pub fn key(&mut self, data: &[u8], more: bool) { - self.begin_op(FLAG_A | FLAG_C, more); - self.overwrite(data); - } -} - -impl Strobe128 { - fn run_f(&mut self) { - self.state[self.pos as usize] ^= self.pos_begin; - self.state[(self.pos + 1) as usize] ^= 0x04; - self.state[(STROBE_R + 1) as usize] ^= 0x80; - keccak::f1600(transmute_state(&mut self.state)); - self.pos = 0; - self.pos_begin = 0; - } - - fn absorb(&mut self, data: &[u8]) { - for byte in data { - self.state[self.pos as usize] ^= byte; - self.pos += 1; - if self.pos == STROBE_R { - self.run_f(); - } - } - } - - fn overwrite(&mut self, data: &[u8]) { - for byte in data { - self.state[self.pos as usize] = *byte; - self.pos += 1; - if self.pos == STROBE_R { - self.run_f(); - } - } - } - - fn squeeze(&mut self, data: &mut [u8]) { - for byte in data { - *byte = self.state[self.pos as usize]; - self.state[self.pos as usize] = 0; - self.pos += 1; - if self.pos == STROBE_R { - self.run_f(); - } - } - } - - fn begin_op(&mut self, flags: u8, more: bool) { - // Check if we're continuing an operation - if more { - assert_eq!( - self.cur_flags, flags, - "You tried to continue op {:#b} but changed flags to {:#b}", - self.cur_flags, flags, - ); - return; - } - - // Skip adjusting direction information (we just use AD, PRF) - assert_eq!( - flags & FLAG_T, - 0u8, - "You used the T flag, which this implementation doesn't support" - ); - - let old_begin = self.pos_begin; - self.pos_begin = self.pos + 1; - self.cur_flags = flags; - - self.absorb(&[old_begin, flags]); - - // Force running F if C or K is set - let force_f = 0 != (flags & (FLAG_C | FLAG_K)); - - if force_f && self.pos != 0 { - self.run_f(); - } - } -} - -impl Deref for AlignedKeccakState { - type Target = [u8; 200]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for AlignedKeccakState { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -#[cfg(test)] -mod tests { - use strobe_rs::{self, SecParam}; - - #[test] - fn test_conformance() { - let mut s1 = super::Strobe128::new(b"Conformance Test Protocol"); - let mut s2 = strobe_rs::Strobe::new(b"Conformance Test Protocol", SecParam::B128); - - // meta-AD(b"msg"); AD(msg) - - let msg = [99u8; 1024]; - - s1.meta_ad(b"ms", false); - s1.meta_ad(b"g", true); - s1.ad(&msg, false); - - s2.meta_ad(b"ms", false); - s2.meta_ad(b"g", true); - s2.ad(&msg, false); - - // meta-AD(b"prf"); PRF() - - let mut prf1 = [0u8; 32]; - s1.meta_ad(b"prf", false); - s1.prf(&mut prf1, false); - - let mut prf2 = [0u8; 32]; - s2.meta_ad(b"prf", false); - s2.prf(&mut prf2, false); - - assert_eq!(prf1, prf2); - - // meta-AD(b"key"); KEY(prf output) - - s1.meta_ad(b"key", false); - s1.key(&prf1, false); - - s2.meta_ad(b"key", false); - s2.key(&prf2, false); - - // meta-AD(b"prf"); PRF() - - let mut prf1 = [0u8; 32]; - s1.meta_ad(b"prf", false); - s1.prf(&mut prf1, false); - - let mut prf2 = [0u8; 32]; - s2.meta_ad(b"prf", false); - s2.prf(&mut prf2, false); - - assert_eq!(prf1, prf2); - } -}