Separate RNG library (#470)

* seperates the RNG library

* fixes crypto tests

* adds rng256 workflow

* fixes formatting
This commit is contained in:
kaczmarczyck
2022-04-28 11:36:43 +02:00
committed by GitHub
parent 360efa4eaf
commit 4782d7e186
23 changed files with 96 additions and 26 deletions

View File

@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::super::rng256::Rng256;
use super::int256::{Digit, Int256};
use core::ops::Mul;
use rng256::Rng256;
use subtle::{self, Choice, ConditionallySelectable, CtOption};
// An exponent on the elliptic curve, that is an element modulo the curve order N.

View File

@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::super::rng256::Rng256;
use alloc::vec;
use alloc::vec::Vec;
use arrayref::{array_mut_ref, array_ref};
use byteorder::{BigEndian, ByteOrder};
use core::ops::{Add, AddAssign, Sub, SubAssign};
use rng256::Rng256;
use subtle::{self, Choice, ConditionallySelectable, ConstantTimeEq};
const BITS_PER_DIGIT: usize = 32;

View File

@@ -16,7 +16,7 @@ use super::ec::exponent256::NonZeroExponentP256;
use super::ec::int256;
use super::ec::int256::Int256;
use super::ec::point::PointP256;
use super::rng256::Rng256;
use rng256::Rng256;
pub const NBYTES: usize = int256::NBYTES;
@@ -98,8 +98,8 @@ impl PubKey {
#[cfg(test)]
mod test {
use super::super::rng256::ThreadRng256;
use super::*;
use rng256::ThreadRng256;
// Run more test iterations in release mode, as the code should be faster.
#[cfg(not(debug_assertions))]

View File

@@ -17,7 +17,6 @@ use super::ec::int256;
use super::ec::int256::Int256;
use super::ec::point::PointP256;
use super::hmac::hmac_256;
use super::rng256::Rng256;
use super::Hash256;
use alloc::vec;
use alloc::vec::Vec;
@@ -25,6 +24,7 @@ use alloc::vec::Vec;
use arrayref::array_mut_ref;
use arrayref::{array_ref, mut_array_refs};
use core::marker::PhantomData;
use rng256::Rng256;
pub const NBYTES: usize = int256::NBYTES;
@@ -347,9 +347,9 @@ where
#[cfg(test)]
mod test {
use super::super::rng256::ThreadRng256;
use super::super::sha256::Sha256;
use super::*;
use rng256::ThreadRng256;
// Run more test iterations in release mode, as the code should be faster.
#[cfg(not(debug_assertions))]

View File

@@ -24,7 +24,6 @@ pub mod ecdh;
pub mod ecdsa;
pub mod hkdf;
pub mod hmac;
pub mod rng256;
pub mod sha256;
pub mod util;

View File

@@ -1,92 +0,0 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use arrayref::array_ref;
use libtock_drivers::rng;
// Lightweight RNG trait to generate uniformly distributed 256 bits.
pub trait Rng256 {
fn gen_uniform_u8x32(&mut self) -> [u8; 32];
fn gen_uniform_u32x8(&mut self) -> [u32; 8] {
bytes_to_u32(self.gen_uniform_u8x32())
}
}
// The TockOS rng driver fills a buffer of bytes, but we need 32-bit words for ECDSA.
// This function does the conversion in safe Rust, using the native endianness to avoid unnecessary
// instructions.
// An unsafe one-line equivalent could be implemented with mem::transmute, but let's use safe Rust
// when possible.
fn bytes_to_u32(bytes: [u8; 32]) -> [u32; 8] {
let mut result: [u32; 8] = [Default::default(); 8];
for (i, r) in result.iter_mut().enumerate() {
*r = u32::from_ne_bytes(*array_ref![bytes, 4 * i, 4]);
}
result
}
// RNG backed by the TockOS rng driver.
pub struct TockRng256 {}
impl Rng256 for TockRng256 {
fn gen_uniform_u8x32(&mut self) -> [u8; 32] {
let mut buf: [u8; 32] = [Default::default(); 32];
rng::fill_buffer(&mut buf);
buf
}
}
// For tests on the desktop, we use the cryptographically secure thread rng as entropy source.
#[cfg(feature = "std")]
pub struct ThreadRng256 {}
#[cfg(feature = "std")]
impl Rng256 for ThreadRng256 {
fn gen_uniform_u8x32(&mut self) -> [u8; 32] {
use rand::Rng;
let mut rng = rand::thread_rng();
let mut result = [Default::default(); 32];
rng.fill(&mut result);
result
}
}
#[cfg(test)]
pub mod test {
use super::*;
#[test]
fn test_bytes_to_u32() {
// This tests that all bytes of the input are indeed used in the output, once each.
// Otherwise the result of gen_uniform_u32x8 wouldn't be uniformly distributed.
let bytes = b"\x00\x01\x02\x03\x04\x05\x06\x07\
\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\
\x10\x11\x12\x13\x14\x15\x16\x17\
\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
#[cfg(target_endian = "big")]
let expected = [
0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b,
0x1c1d1e1f,
];
#[cfg(target_endian = "little")]
let expected = [
0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514, 0x1b1a1918,
0x1f1e1d1c,
];
assert_eq!(bytes_to_u32(*bytes), expected);
}
}