wip: remove betrusted feature

This commit is contained in:
David Kotval 2024-01-12 02:10:08 +00:00
parent 55c5a33411
commit 81f9189d2f
6 changed files with 48 additions and 151 deletions

View file

@ -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 = []

View file

@ -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]);

View file

@ -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<u8> {
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)+)
});
}

View file

@ -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;
//------------------------------------------------------------------------

View file

@ -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(&copy_from_rf(25, &result_rf));
x0.W = FieldElement::from_bytes(&copy_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.

View file

@ -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<Item = bool> + '_ {
(0..256).map(|i| {
// As i runs from 0..256, the bottom 3 bits index the bit, while the upper bits index