mirror of
https://github.com/saymrwulf/risc0-curve25519-dalek-source.git
synced 2026-09-04 20:03:40 +00:00
Add #![no_std]
Use ::core in lieu of ::std, allowing this crate to be usable in #![no_std] environments. Gates features that presently depend on ::std (presently just rand) behind a "std" cargo feature, which is enabled by default. Switches from the "rust-crypto" crate (which is not #![no_std] compatible) to the sha2 crate, which is factored out of the original "rust-crypto" project and being actively maintained.
This commit is contained in:
parent
6269edb266
commit
4f81231dc2
3 changed files with 46 additions and 25 deletions
18
Cargo.toml
18
Cargo.toml
|
|
@ -11,10 +11,20 @@ exclude = [ ".gitignore", "TESTVECTORS" ]
|
|||
|
||||
|
||||
[dependencies]
|
||||
arrayref = "0.3.2"
|
||||
rust-crypto = "^0.2"
|
||||
rand = "^0.3"
|
||||
curve25519-dalek = "^0.3"
|
||||
arrayref = "0.3.3"
|
||||
sha2 = "^0.4"
|
||||
|
||||
[dependencies.curve25519-dalek]
|
||||
version = "^0.3"
|
||||
default-features = false
|
||||
|
||||
[dependencies.rand]
|
||||
optional = true
|
||||
version = "^0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-serialize = "0.3"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["rand"]
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
//! A Rust implementation of ed25519 key generation, signing, and verification.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use core::fmt::Debug;
|
||||
|
||||
use crypto::digest::Digest;
|
||||
use crypto::sha2::Sha512;
|
||||
use sha2::{Digest, Sha512};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use rand::Rng;
|
||||
|
||||
use curve25519_dalek::curve;
|
||||
|
|
@ -24,6 +24,7 @@ use curve25519_dalek::curve::ProjectivePoint;
|
|||
use curve25519_dalek::scalar::Scalar;
|
||||
use curve25519_dalek::util::arrays_equal_ct;
|
||||
|
||||
pub const SIGNATURE_LENGTH: usize = 64;
|
||||
|
||||
/// An ed25519 signature.
|
||||
///
|
||||
|
|
@ -33,14 +34,14 @@ use curve25519_dalek::util::arrays_equal_ct;
|
|||
/// "detached"—that is, they do **not** include a copy of the message which
|
||||
/// has been signed.
|
||||
#[derive(Copy)]
|
||||
pub struct Signature(pub [u8; 64]);
|
||||
pub struct Signature(pub [u8; SIGNATURE_LENGTH]);
|
||||
|
||||
impl Clone for Signature {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
|
||||
impl Debug for Signature {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
write!(f, "Signature: {:?}", &self.0[..])
|
||||
}
|
||||
}
|
||||
|
|
@ -68,16 +69,16 @@ impl PartialEq for Signature {
|
|||
}
|
||||
|
||||
impl Signature {
|
||||
/// View this signature as an array of 32 bytes.
|
||||
/// View this signature as an array of 64 bytes.
|
||||
#[inline]
|
||||
pub fn to_bytes(&self) -> [u8; 64] {
|
||||
pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Construct a `Signature` from a slice of bytes.
|
||||
#[inline]
|
||||
pub fn from_bytes(bytes: &[u8]) -> Signature {
|
||||
Signature(*array_ref!(bytes, 0, 64))
|
||||
Signature(*array_ref!(bytes, 0, SIGNATURE_LENGTH))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ impl Signature {
|
|||
pub struct SecretKey(pub [u8; 64]);
|
||||
|
||||
impl Debug for SecretKey {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
write!(f, "SecretKey: {:?}", &self.0[..])
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +137,7 @@ impl SecretKey {
|
|||
pub fn sign(&self, message: &[u8]) -> Signature {
|
||||
let mut h: Sha512 = Sha512::new();
|
||||
let mut hash: [u8; 64] = [0u8; 64];
|
||||
let signature_bytes: Vec<u8>;
|
||||
let mut signature_bytes: [u8; 64] = [0u8; SIGNATURE_LENGTH];
|
||||
let mut expanded_key_secret: Scalar;
|
||||
let mesg_digest: Scalar;
|
||||
let hram_digest: Scalar;
|
||||
|
|
@ -148,34 +149,35 @@ impl SecretKey {
|
|||
let public_key: &[u8; 32] = array_ref!(&self.0, 32, 32);
|
||||
|
||||
h.input(secret_key);
|
||||
h.result(&mut hash);
|
||||
hash.copy_from_slice(h.result().as_slice());
|
||||
|
||||
expanded_key_secret = Scalar(*array_ref!(&hash, 0, 32));
|
||||
expanded_key_secret[0] &= 248;
|
||||
expanded_key_secret[31] &= 63;
|
||||
expanded_key_secret[31] |= 64;
|
||||
|
||||
h.reset();
|
||||
h = Sha512::new();
|
||||
h.input(&hash[32..]);
|
||||
h.input(&message);
|
||||
h.result(&mut hash);
|
||||
hash.copy_from_slice(h.result().as_slice());
|
||||
|
||||
mesg_digest = Scalar::reduce(&hash);
|
||||
|
||||
r = ExtendedPoint::basepoint_mult(&mesg_digest);
|
||||
|
||||
h.reset();
|
||||
h = Sha512::new();
|
||||
h.input(&r.compress().to_bytes()[..]);
|
||||
h.input(public_key);
|
||||
h.input(&message);
|
||||
h.result(&mut hash);
|
||||
hash.copy_from_slice(h.result().as_slice());
|
||||
|
||||
hram_digest = Scalar::reduce(&hash);
|
||||
|
||||
s = Scalar::multiply_add(&hram_digest, &expanded_key_secret, &mesg_digest);
|
||||
t = r.compress();
|
||||
|
||||
signature_bytes = [t.0, s.0].concat();
|
||||
signature_bytes[..32].copy_from_slice(&t.0);
|
||||
signature_bytes[32..64].copy_from_slice(&s.0);
|
||||
Signature(*array_ref!(&signature_bytes, 0, 64))
|
||||
}
|
||||
}
|
||||
|
|
@ -185,8 +187,8 @@ impl SecretKey {
|
|||
pub struct PublicKey(pub CompressedEdwardsY);
|
||||
|
||||
impl Debug for PublicKey {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
write!(f, "PublicKey( CompressedEdwardsY( {:?} ))", self.0)
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
write!(f, "PublicKey( CompressedPoint( {:?} ))", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +269,7 @@ impl PublicKey {
|
|||
h.input(&bottom_half[..]);
|
||||
h.input(&self.to_bytes());
|
||||
h.input(&message);
|
||||
h.result(&mut digest);
|
||||
digest.copy_from_slice(h.result().as_slice());
|
||||
|
||||
digest_reduced = Scalar::reduce(&digest);
|
||||
r = curve::double_scalar_mult_vartime(&digest_reduced, &a, &Scalar(*top_half));
|
||||
|
|
@ -297,6 +299,7 @@ impl Keypair {
|
|||
/// A CSPRING with a `fill_bytes()` method, e.g. the one returned
|
||||
/// from `rand::OsRng::new()` (in the `rand` crate).
|
||||
// we reassign 0 bytes to the temp variable t to overwrite it
|
||||
#[cfg(feature = "std")]
|
||||
#[allow(unused_assignments)]
|
||||
pub fn generate<T: Rng>(cspring: &mut T) -> Keypair {
|
||||
let mut h: Sha512 = Sha512::new();
|
||||
|
|
@ -309,7 +312,7 @@ impl Keypair {
|
|||
cspring.fill_bytes(&mut t);
|
||||
|
||||
h.input(&t);
|
||||
h.result(&mut hash);
|
||||
hash.copy_from_slice(h.result().as_slice());
|
||||
|
||||
digest = array_mut_ref!(&mut hash, 0, 32);
|
||||
digest[0] &= 248;
|
||||
|
|
@ -346,6 +349,8 @@ mod test {
|
|||
use std::io::BufReader;
|
||||
use std::io::BufRead;
|
||||
use std::fs::File;
|
||||
use std::string::String;
|
||||
use std::vec::Vec;
|
||||
use test::Bencher;
|
||||
use curve25519_dalek::curve::ExtendedPoint;
|
||||
use rand::OsRng;
|
||||
|
|
|
|||
|
|
@ -58,16 +58,22 @@
|
|||
//! assert!(verified);
|
||||
//! ```
|
||||
|
||||
#![no_std]
|
||||
#![feature(rand)]
|
||||
#![allow(unused_features)]
|
||||
#![feature(test)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate arrayref;
|
||||
extern crate crypto;
|
||||
extern crate sha2;
|
||||
extern crate curve25519_dalek;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate rand;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue