finish u32e_backend variant for bootloader use

This commit is contained in:
bunnie 2021-07-11 02:03:00 +08:00
parent 053d65f3a7
commit 03e91fefce
10 changed files with 13 additions and 168 deletions

View file

@ -81,7 +81,7 @@ std = ["alloc", "subtle/std", "rand_core/std"]
alloc = ["zeroize/alloc"]
# The u32 backend uses u32s with u64 products.
u32_backend = ["utralib"]
u32_backend = []
# The u32e backend uses u32s with u64 products + field25519 accelerator.
u32e_backend = ["engine25519-as", "utralib"]
# The u64 backend uses u64s with u128 products.

View file

@ -27,9 +27,6 @@ use subtle::ConditionallySelectable;
use zeroize::Zeroize;
#[macro_use]
use debug;
/// A `FieldElement2625` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
///
@ -218,9 +215,7 @@ impl<'a, 'b> Mul<&'b FieldElement2625> for &'a FieldElement2625 {
//
// So z[0] fits into a u64 if 51 + 2*b + lg(249) < 64
// if b < 2.5.
let ret = FieldElement2625::reduce([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]);
//println!("a:{:?}\n\rb:{:?}\n\rout:{:?}", self.to_bytes(), _rhs.to_bytes(), ret.to_bytes());
ret
FieldElement2625::reduce([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9])
}
}

View file

@ -16,7 +16,6 @@
//! implementation, and was then rewritten to use unsigned limbs instead
//! of signed limbs.
use core::fmt::Debug;
use core::ops::Neg;
use core::ops::{Add, AddAssign};
use core::ops::{Mul, MulAssign};
@ -50,17 +49,10 @@ use zeroize::Zeroize;
/// The backend-specific type `Engine25519` should not be used
/// outside of the `curve25519_dalek::field` module.
//#[macro_use]
//mod debug;
#[macro_use]
use debug;
#[derive(Copy, Clone, Debug)]
pub struct Engine25519(
pub (crate) [u8; 32]
);
#[derive(Debug)]
pub(crate) enum EngineOp {
Mul,
Add,
@ -68,7 +60,6 @@ pub(crate) enum EngineOp {
}
pub(crate) fn engine(a: &[u8; 32], b: &[u8; 32], op: EngineOp) -> Engine25519 {
use core::convert::TryInto;
use utralib::generated::*;
let mut engine = utralib::CSR::new(utra::engine::HW_ENGINE_BASE as *mut u32);
let mcode: &'static mut [u32] = unsafe{ core::slice::from_raw_parts_mut(utralib::HW_ENGINE_MEM as *mut u32, 1024) };
@ -121,12 +112,17 @@ pub(crate) fn engine(a: &[u8; 32], b: &[u8; 32], op: EngineOp) -> Engine25519 {
}
// copy a arg
for (src, dst) in a.chunks_exact(4).zip(rf[0].iter_mut()) {
unsafe{ (dst as *mut u32).write_volatile(u32::from_le_bytes(src[0..4].try_into().unwrap()));}
let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]];
unsafe{ (dst as *mut u32).write_volatile(u32::from_le_bytes(bytes));}
/* this is a bad idea: src[0..4].try_into().unwrap()
because "unwrap()" adds in a whole bunch of string formatting stuff, adds +16k or so to the binary size
*/
}
// copy b arg
for (src, dst) in b.chunks_exact(4).zip(rf[1].iter_mut()) {
unsafe{ (dst as *mut u32).write_volatile(u32::from_le_bytes(src[0..4].try_into().unwrap()));}
let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]];
unsafe{ (dst as *mut u32).write_volatile(u32::from_le_bytes(bytes));}
}
engine.wfo(utra::engine::CONTROL_GO, 1);
@ -192,7 +188,6 @@ impl<'a, 'b> Mul<&'b Engine25519> for &'a Engine25519 {
type Output = Engine25519;
fn mul(self, _rhs: &'b Engine25519) -> Engine25519 {
let ret = engine(&self.0, &_rhs.0, EngineOp::Mul);
//println!("a:{:?}\n\rb:{:?}\n\rout:{:?}", self.0, _rhs.0, ret.0);
ret
}
}

View file

@ -10,7 +10,6 @@
//! -0x1ffffffe00000008 (62 bits with sign bit) to
//! 0x43fffffbc0000011 (63 bits), which is still safe.
use core::fmt::Debug;
use core::ops::{Index, IndexMut};
use zeroize::Zeroize;

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

@ -172,9 +172,6 @@ impl Debug for CompressedEdwardsY {
}
}
#[macro_use]
use debug;
impl CompressedEdwardsY {
/// View this `CompressedEdwardsY` as an array of bytes.
pub fn as_bytes(&self) -> &[u8; 32] {
@ -191,36 +188,21 @@ impl CompressedEdwardsY {
/// Returns `None` if the input is not the \\(y\\)-coordinate of a
/// curve point.
pub fn decompress(&self) -> Option<EdwardsPoint> {
println!("self.bytes: {:?}", self.as_bytes());
let Y = FieldElement::from_bytes(self.as_bytes());
println!("Y: {:?}", Y.to_bytes());
let Z = FieldElement::one();
println!("Z: {:?}", Z.to_bytes());
let YY = Y.square();
println!("YY: {:?}", YY.to_bytes());
let u = &YY - &Z; // u = y²-1
println!("u: {:?}", u.to_bytes());
let v = &(&YY * &constants::EDWARDS_D) + &Z; // v = dy²+1
println!("v: {:?}", v.to_bytes());
let (is_valid_y_coord, mut X) = FieldElement::sqrt_ratio_i(&u, &v);
println!("isvalid: {:?}", is_valid_y_coord);
println!("X: {:?}", X.to_bytes());
if is_valid_y_coord.unwrap_u8() != 1u8 { return None; }
println!("valid");
// FieldElement::sqrt_ratio_i always returns the nonnegative square root,
// so we negate according to the supplied sign bit.
let compressed_sign_bit = Choice::from(self.as_bytes()[31] >> 7);
X.conditional_negate(compressed_sign_bit);
println!("negate");
println!("X: {:?}", X.to_bytes());
println!("Y: {:?}", Y.to_bytes());
println!("Z: {:?}", Z.to_bytes());
let t = &X * &Y;
println!("T: {:?}", t.to_bytes());
Some(EdwardsPoint{ X, Y, Z, T: t })
Some(EdwardsPoint{ X, Y, Z, T: &X * &Y })
}
}

View file

@ -94,8 +94,6 @@ impl ConstantTimeEq for FieldElement {
self.to_bytes().ct_eq(&other.to_bytes())
}
}
#[macro_use]
use debug;
impl FieldElement {
/// Determine if this `FieldElement` is negative, in the sense
@ -264,41 +262,25 @@ impl FieldElement {
// If v is zero, r is also zero.
let v3 = &v.square() * v;
println!("v3: {:?}", v3.to_bytes());
let v7 = &v3.square() * v;
println!("v7: {:?}", v7.to_bytes());
let mut r = &(u * &v3) * &(u * &v7).pow_p58();
println!("r: {:?}", r.to_bytes());
let check = v * &r.square();
println!("check: {:?}", check.to_bytes());
let i = &constants::SQRT_M1;
println!("i: {:?}", i.to_bytes());
let correct_sign_sqrt = check.ct_eq( u);
let flipped_sign_sqrt = check.ct_eq( &(-u));
let flipped_sign_sqrt_i = check.ct_eq(&(&(-u)*i));
println!("correct_sign_sqrt: {:?}", correct_sign_sqrt);
println!("u: {:?}", u.to_bytes());
println!("flipped_sign_sqrt: {:?}", flipped_sign_sqrt);
println!("-u: {:?}", &(-u).to_bytes());
println!("flipped_sign_sqrt_i: {:?}", flipped_sign_sqrt_i);
println!("-u * i: {:?}", &(&(-u)*i));
let r_prime = &constants::SQRT_M1 * &r;
println!("r_prime: {:?}", r_prime.to_bytes());
r.conditional_assign(&r_prime, flipped_sign_sqrt | flipped_sign_sqrt_i);
println!("r_assign1: {:?}", r.to_bytes());
// Choose the nonnegative square root.
let r_is_negative = r.is_negative();
r.conditional_negate(r_is_negative);
println!("r_assign2: {:?}", r.to_bytes());
let was_nonzero_square = correct_sign_sqrt | flipped_sign_sqrt;
println!("final r: {:?}", r.to_bytes());
(was_nonzero_square, r)
}

View file

@ -73,13 +73,9 @@ extern crate engine25519_as;
#[cfg(feature = "betrusted")]
extern crate engine_25519;
//#[cfg(feature = "u32e_backend")]
#[cfg(feature = "u32e_backend")]
extern crate utralib;
//#[cfg(feature = "u32e_backend")]
#[macro_use]
mod debug;
//------------------------------------------------------------------------
// curve25519-dalek public modules
//------------------------------------------------------------------------

View file

@ -194,7 +194,7 @@ use traits::{MultiscalarMul, VartimeMultiscalarMul, VartimePrecomputedMultiscala
feature = "simd_backend",
any(target_feature = "avx2", target_feature = "avx512ifma")
)))]
#[cfg(not(feature = "betrusted"))]
#[cfg(all(not(feature = "betrusted"), not(feature = "u32e_backend")))]
use backend::serial::scalar_mul;
#[cfg(all(
feature = "simd_backend",

View file

@ -1018,7 +1018,7 @@ impl Scalar {
/// Returns a size hint indicating how many entries of the return
/// value of `to_radix_2w` are nonzero.
#[cfg(not(feature = "betrusted"))]
#[cfg(all(not(feature = "betrusted"), not(feature = "u32e_backend")))]
pub(crate) fn to_radix_2w_size_hint(w: usize) -> usize {
debug_assert!(w >= 4);
debug_assert!(w <= 8);