From 81f9189d2fb6003441cdbeee8a517477a3c4b82b Mon Sep 17 00:00:00 2001 From: David Kotval Date: Fri, 12 Jan 2024 02:10:08 +0000 Subject: [PATCH] wip: remove betrusted feature --- curve25519-dalek/Cargo.toml | 29 +---- .../src/backend/serial/u32/constants.rs | 3 +- .../src/backend/serial/u32e/field/debug.rs | 104 ------------------ curve25519-dalek/src/lib.rs | 17 ++- curve25519-dalek/src/montgomery.rs | 42 ++++--- curve25519-dalek/src/scalar.rs | 4 +- 6 files changed, 48 insertions(+), 151 deletions(-) delete mode 100644 curve25519-dalek/src/backend/serial/u32e/field/debug.rs diff --git a/curve25519-dalek/Cargo.toml b/curve25519-dalek/Cargo.toml index aebc5e6..b28ef70 100644 --- a/curve25519-dalek/Cargo.toml +++ b/curve25519-dalek/Cargo.toml @@ -57,27 +57,10 @@ serde = { version = "1.0", default-features = false, optional = true, features = zeroize = { version = "1", default-features = false, optional = true } # Betrusted/Precursor dependency set -log = { version = "0.4", optional = true } -[dependencies.engine-25519] -git = "https://github.com/betrusted-io/xous-engine-25519.git" -rev = "63d3d1f30736022e791deaacf4dd62c00b42fe2e" -optional = true - -[dependencies.utralib] -version = "0.1.0" # this is bogus -- must be patched in the invoking build environment -#path="../betrusted-soc/boot/utralib/" -optional = true - -[dependencies.engine25519-as] -git = "https://github.com/betrusted-io/engine25519-as.git" -rev = "d249c967556b02ab5439eacb5078fa00c60b93d6" -default-features = false -features = [] -optional = true - -[dev-dependencies.engine25519-as] -git = "https://github.com/betrusted-io/engine25519-as.git" -rev = "d249c967556b02ab5439eacb5078fa00c60b93d6" +[target.'cfg(curve25519_dalek_backend = "u32e_backend")'.dependencies] +engine25519-as = {git = "https://github.com/betrusted-io/engine25519-as.git", rev = "d249c967556b02ab5439eacb5078fa00c60b93d6", default-features = false, features = [], optional = true} +engine-25519 = { git = "https://github.com/betrusted-io/xous-engine-25519.git", rev = "63d3d1f30736022e791deaacf4dd62c00b42fe2e", optional = true} +utralib = {version = "0.1.0", optional = true} # this is bogus -- must be patched in the invoking build environment TODO: if this builds, it seems a crate has been released as version 0.1.23 that could replace this [target.'cfg(target_arch = "x86_64")'.dependencies] cpufeatures = "0.2.6" @@ -86,9 +69,7 @@ cpufeatures = "0.2.6" fiat-crypto = { version = "0.2.1", default-features = false } [features] -default = ["alloc", "precomputed-tables", "zeroize", "betrusted", "u32e_backend"] -betrusted = ["engine-25519", "engine25519-as", "log"] -u32e_backend = ["engine25519-as", "utralib"] +default = ["alloc", "precomputed-tables", "zeroize"] alloc = ["zeroize?/alloc"] precomputed-tables = [] legacy_compatibility = [] diff --git a/curve25519-dalek/src/backend/serial/u32/constants.rs b/curve25519-dalek/src/backend/serial/u32/constants.rs index 71fdcd3..b5e6dcc 100644 --- a/curve25519-dalek/src/backend/serial/u32/constants.rs +++ b/curve25519-dalek/src/backend/serial/u32/constants.rs @@ -68,7 +68,8 @@ pub(crate) const SQRT_M1: FieldElement2625 = FieldElement2625::from_limbs([ ]); /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) -#[cfg(not(feature = "betrusted"))] +/// The u32e backend uses hardware acceleration for this. +#[cfg(curve_dalek_backend != "u32e_backend")] pub(crate) const APLUS2_OVER_FOUR: FieldElement2625 = FieldElement2625::from_limbs([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]); diff --git a/curve25519-dalek/src/backend/serial/u32e/field/debug.rs b/curve25519-dalek/src/backend/serial/u32e/field/debug.rs deleted file mode 100644 index bde1e14..0000000 --- a/curve25519-dalek/src/backend/serial/u32e/field/debug.rs +++ /dev/null @@ -1,104 +0,0 @@ -use utralib::generated::*; -pub struct Uart { - // pub base: *mut u32, -} - -impl Uart { - fn put_digit(&mut self, d: u8) { - let nyb = d & 0xF; - if nyb < 10 { - self.putc(nyb + 0x30); - } else { - self.putc(nyb + 0x61 - 10); - } - } - pub fn put_hex(&mut self, c: u8) { - self.put_digit(c >> 4); - self.put_digit(c & 0xF); - } - pub fn newline(&mut self) { - self.putc(0xa); - self.putc(0xd); - } - pub fn print_hex_word(&mut self, word: u32) { - for &byte in word.to_be_bytes().iter() { - self.put_hex(byte); - } - } - - pub fn putc(&self, c: u8) { - let base = utra::uart::HW_UART_BASE as *mut u32; - let mut uart = CSR::new(base); - // Wait until TXFULL is `0` - while uart.r(utra::uart::TXFULL) != 0 {} - uart.wo(utra::uart::RXTX, c as u32) - } - - pub fn getc(&self) -> Option { - let base = utra::uart::HW_UART_BASE as *mut u32; - let mut uart = CSR::new(base); - match uart.rf(utra::uart::EV_PENDING_RX) { - 0 => None, - ack => { - let c = Some(uart.rf(utra::uart::RXTX_RXTX) as u8); - uart.wfo(utra::uart::EV_PENDING_RX, ack); - c - } - } - } - - pub fn tiny_write_str(&mut self, s: &str) { - for c in s.bytes() { - self.putc(c); - } - } - -} - -use core::fmt::{Error, Write}; -impl Write for Uart { - fn write_str(&mut self, s: &str) -> Result<(), Error> { - for c in s.bytes() { - self.putc(c); - } - Ok(()) - } -} - -#[macro_use] -pub mod debug_print_hardware { - #[macro_export] - macro_rules! print - { - ($($args:tt)+) => ({ - use core::fmt::Write; - let _ = write!(debug::Uart {}, $($args)+); - }); - } -} - -#[macro_use] -#[cfg(test)] -mod debug_print_hardware { - #[macro_export] - #[allow(unused_variables)] - macro_rules! print { - ($($args:tt)+) => ({ - std::print!($($args)+) - }); - } -} - -#[macro_export] -macro_rules! println -{ - () => ({ - $crate::print!("\r\n") - }); - ($fmt:expr) => ({ - $crate::print!(concat!($fmt, "\r\n")) - }); - ($fmt:expr, $($args:tt)+) => ({ - $crate::print!(concat!($fmt, "\r\n"), $($args)+) - }); -} diff --git a/curve25519-dalek/src/lib.rs b/curve25519-dalek/src/lib.rs index 47cf1a9..aa930a6 100644 --- a/curve25519-dalek/src/lib.rs +++ b/curve25519-dalek/src/lib.rs @@ -36,7 +36,7 @@ unused_qualifications )] -// needed for engine25519-as. +// needed for engine25519-as. #![recursion_limit="512"] //------------------------------------------------------------------------ @@ -60,14 +60,23 @@ pub use digest; #[macro_use] pub(crate) mod macros; +//To consider upstreaming, we likely can't do this. Consider the "panic_on_sw_eval" feature #[allow(unused_imports)] -#[cfg(any(feature = "betrusted", test, curve25519_dalek_backend = "u32e_backend"))] +#[cfg(any(test, curve25519_dalek_backend = "u32e_backend"))] #[macro_use] extern crate engine25519_as; -#[cfg(feature = "betrusted")] +#[cfg(curve25519_dalek_backend = "u32e_backend")] //this is the binding for betrusted, so it should be gated + //with a "betrusted" flag, but we gate it with the backend + //flag for now. We'd need to refactor this to be + //make it easier to support other platforms, + //though there are no other platforms. For + //upstreaming this might be diserable, but for + //now, we'll leave it as a TODO. extern crate engine_25519; -#[cfg(curve25519_dalek_backend = "u32e_backend")] +#[cfg(curve25519_dalek_backend = "u32e_backend")] //while this is specific to betrusted, any other + //use of this hardware would likely also need + //utralib, at least that would be easiest. extern crate utralib; //------------------------------------------------------------------------ diff --git a/curve25519-dalek/src/montgomery.rs b/curve25519-dalek/src/montgomery.rs index 3506bee..ce3ee8a 100644 --- a/curve25519-dalek/src/montgomery.rs +++ b/curve25519-dalek/src/montgomery.rs @@ -54,14 +54,13 @@ use core::{ ops::{Mul, MulAssign}, }; -#[cfg(not(feature = "betrusted"))] -use constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG}; -#[cfg(feature = "betrusted")] -use constants::{MONTGOMERY_A, MONTGOMERY_A_NEG}; // eliminate constants absorbed into the microcode engine +#[cfg(not(curve25519_dalek_backend = "u32e_backend"))] +use crate::constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG}; +#[cfg(curve25519_dalek_backend = "u32e_backend")] +use crate::constants::{MONTGOMERY_A, MONTGOMERY_A_NEG}; // eliminate constants absorbed into the microcode engine -use edwards::{CompressedEdwardsY, EdwardsPoint}; -use field::FieldElement; -use scalar::Scalar; +use crate::edwards::{CompressedEdwardsY, EdwardsPoint}; +use crate::field::FieldElement; use crate::scalar::{clamp_integer, Scalar}; use crate::traits::Identity; @@ -156,6 +155,8 @@ impl MontgomeryPoint { Self::mul_base(&s) } + //TODO: understand _clamped multiplication_ and ensure we are doing it correctly and + //compatibily as this has changed since our fork. /// Given `self` \\( = u\_0(P) \\), and a big-endian bit representation of an integer /// \\(n\\), return \\( u\_0(\[n\]P) \\). This is constant time in the length of `bits`. /// @@ -324,15 +325,17 @@ impl ProjectivePoint { /// /// * \\( u = U / W \\) if \\( W \neq 0 \\); /// * \\( 0 \\) if \\( W \eq 0 \\); - #[cfg(not(feature = "betrusted"))] + #[cfg(not(curve25519_dalek_backend = "u32e_backend"))] pub fn as_affine(&self) -> MontgomeryPoint { - #[cfg(all(not(test),feature="betrusted"))] // due to issue https://github.com/rust-lang/rust/issues/59168, you will have to manually comment this out when running a test on the full system and not just this crate. + //TODO: consider making this a seperate feature. Something like "panic_on_sw_eval" which would + //be ameniable to upstreaming + #[cfg(all(not(test),curve25519_dalek_backend = "u32e_backend"))] // due to issue https://github.com/rust-lang/rust/issues/59168, you will have to manually comment this out when running a test on the full system and not just this crate. log::warn!("sw as_affine being used - check for build config errors!"); let u = &self.U * &self.W.invert(); MontgomeryPoint(u.as_bytes()) } #[allow(dead_code)] - #[cfg(feature = "betrusted")] + #[cfg(curve25519_dalek_backend = "u32e_backend")] pub fn as_affine(&self) -> MontgomeryPoint { let mcode = assemble_engine25519!( start: @@ -496,7 +499,7 @@ impl ProjectivePoint { /// $$ /// (U\_Q : W\_Q) \gets u(P + Q). /// $$ -#[cfg(not(feature = "betrusted"))] +#[cfg(not(curve25519_dalek_backend = "u32e_backend"))] #[rustfmt::skip] // keep alignment of explanatory comments pub(crate) fn differential_add_and_double( P: &mut ProjectivePoint, @@ -538,7 +541,7 @@ pub(crate) fn differential_add_and_double( Q.W = t17; // W_{Q'} = U_D * 4 (W_P U_Q - U_P W_Q)^2 } -#[cfg(feature = "betrusted")] +#[cfg(curve25519_dalek_backend = "u32e_backend")] fn copy_to_rf(bytes: [u8; 32], register: usize, rf: &mut [u32; engine_25519::RF_SIZE_IN_U32]) { use core::convert::TryInto; for (byte, rf_dst) in bytes.chunks_exact(4).zip(rf[register * 8..(register+1)*8].iter_mut()) { @@ -546,7 +549,7 @@ fn copy_to_rf(bytes: [u8; 32], register: usize, rf: &mut [u32; engine_25519::RF_ } } -#[cfg(feature = "betrusted")] +#[cfg(curve25519_dalek_backend = "u32e_backend")] fn copy_from_rf(register: usize, rf: &[u32; engine_25519::RF_SIZE_IN_U32]) -> [u8; 32] { let mut ret: [u8; 32] = [0; 32]; @@ -560,7 +563,7 @@ fn copy_from_rf(register: usize, rf: &[u32; engine_25519::RF_SIZE_IN_U32]) -> [u } #[allow(dead_code)] // absorbed into mul, but might be useful later on as a subroutine for something else -#[cfg(feature = "betrusted")] +#[cfg(curve25519_dalek_backend = "u32e_backend")] pub(crate) fn differential_add_and_double_hw( P: &mut ProjectivePoint, Q: &mut ProjectivePoint, @@ -700,7 +703,7 @@ impl Mul<&Scalar> for &MontgomeryPoint { type Output = MontgomeryPoint; /// Given `self` \\( = u\_0(P) \\), and a `Scalar` \\(n\\), return \\( u\_0([n]P) \\). - #[cfg(feature = "betrusted")] + #[cfg(curve25519_dalek_backend = "u32e_backend")] fn mul(self, scalar: &Scalar) -> MontgomeryPoint { log::debug!("hw mont"); // Algorithm 8 of Costello-Smith 2017 @@ -1014,6 +1017,10 @@ impl Mul<&Scalar> for &MontgomeryPoint { if false { // unmerged affine path x0.U = FieldElement::from_bytes(©_from_rf(25, &result_rf)); x0.W = FieldElement::from_bytes(©_from_rf(26, &result_rf)); + + //Note: is seems this TODO has been handled as ProjectivePoint's as_affine already + //has an accelerated version. Should this be removed or is there further + //optimization work to be done. If so, what is that work? // TODO: optimize this relatively innocuous looking call. // this consumes about 100ms runtime -- need to implement this using @@ -1038,9 +1045,10 @@ impl Mul<&Scalar> for &MontgomeryPoint { } /// Given `self` \\( = u\_0(P) \\), and a `Scalar` \\(n\\), return \\( u\_0(\[n\]P) \\) - #[cfg(not(feature = "betrusted"))] + #[cfg(not(curve25519_dalek_backend = "u32e_backend"))] fn mul(self, scalar: &Scalar) -> MontgomeryPoint { - #[cfg(all(not(test),feature="betrusted"))] // due to issue https://github.com/rust-lang/rust/issues/59168, you will have to manually comment this out when running a test on the full system and not just this crate. + // TODO: consider feature "panic_on_sw_eval" + #[cfg(all(not(test),curve25519_dalek_backend = "u32e_backend"))] // due to issue https://github.com/rust-lang/rust/issues/59168, you will have to manually comment this out when running a test on the full system and not just this crate. log::warn!("sw montgomery multiply being used - check for build config errors!"); // We multiply by the integer representation of the given Scalar. By scalar invariant #1, // the MSB is 0, so we can skip it. diff --git a/curve25519-dalek/src/scalar.rs b/curve25519-dalek/src/scalar.rs index cde4b1c..cc01275 100644 --- a/curve25519-dalek/src/scalar.rs +++ b/curve25519-dalek/src/scalar.rs @@ -157,6 +157,8 @@ cfg_if! { /// /// This is a type alias for one of the scalar types in the `backend` /// module. + //TODO: this should be the same as the u32 backend such that we don't even need to have + //backend/serial/scalar.rs defined. Double check that to simplify the code. type UnpackedScalar = backend::serial::u32::scalar::Scalar29; } else if #[cfg(curve25519_dalek_backend = "fiat")] { @@ -846,7 +848,7 @@ impl Scalar { } /// Get the bits of the scalar, in little-endian order - #[cfg(not(feature = "betrusted"))] + #[cfg(not(curve25519_dalek_backend = "u32e_backend"))] pub(crate) fn bits_le(&self) -> impl DoubleEndedIterator + '_ { (0..256).map(|i| { // As i runs from 0..256, the bottom 3 bits index the bit, while the upper bits index