From d08bc7395e812e1303e89d087bc713086a7a5c27 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2017 17:43:08 -0800 Subject: [PATCH] Add #![no_std] (fixes #16) 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. --- Cargo.toml | 13 ++++++++++--- src/curve.rs | 20 ++++++++++---------- src/field.rs | 18 +++++++++--------- src/lib.rs | 2 ++ src/scalar.rs | 6 ++++-- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 014cce1..8e901c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,16 @@ exclude = [ ".gitignore" ] -[dependencies] -rand = "0.3" -arrayref = "0.3.2" +[dependencies.arrayref] +version = "0.3.3" + +[dependencies.rand] +optional = true +version = "0.3" + +[features] +default = ["std"] +std = ["rand"] # The development profile, used for `cargo build`. [profile.dev] diff --git a/src/curve.rs b/src/curve.rs index 971cdb5..df9de53 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -77,10 +77,10 @@ // affine and projective cakes and eat both of them too. #![allow(non_snake_case)] -use std::fmt::Debug; -use std::iter::Iterator; -use std::ops::{Add, Sub, Neg, Index}; -use std::cmp::{PartialEq, Eq}; +use core::fmt::Debug; +use core::iter::Iterator; +use core::ops::{Add, Sub, Neg, Index}; +use core::cmp::{PartialEq, Eq}; use constants; use field::FieldElement; @@ -100,7 +100,7 @@ use util::bytes_equal_ct; pub struct CompressedPoint(pub [u8; 32]); impl Debug for CompressedPoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "CompressedPoint: {:?}", &self.0[..]) } } @@ -763,35 +763,35 @@ impl ExtendedPoint { // ------------------------------------------------------------------------ impl Debug for ExtendedPoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "ExtendedPoint(\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?},\n\tT: {:?}\n)", &self.X, &self.Y, &self.Z, &self.T) } } impl Debug for ProjectivePoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "ProjectivePoint(\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?}\n)", &self.X, &self.Y, &self.Z) } } impl Debug for CompletedPoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "CompletedPoint(\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?},\n\tT: {:?}\n)", &self.X, &self.Y, &self.Z, &self.T) } } impl Debug for PreComputedPoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "PreComputedPoint(\n\ty_plus_x: {:?},\n\ty_minus_x: {:?},\n\txy2d: {:?}\n)", &self.y_plus_x, &self.y_minus_x, &self.xy2d) } } impl Debug for CachedPoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "CachedPoint(\n\tY_plus_X: {:?},\n\tY_minus_X: {:?},\n\tZ: {:?},\n\tT2d: {:?}\n)", &self.Y_plus_X, &self.Y_minus_X, &self.Z, &self.T2d) } diff --git a/src/field.rs b/src/field.rs index 2f1301f..d248c91 100644 --- a/src/field.rs +++ b/src/field.rs @@ -15,14 +15,14 @@ //! Based on Adam Langley's curve25519-donna and (Golang) ed25519 //! implementations. -use std::clone::Clone; -use std::fmt::Debug; -use std::ops::{Add, AddAssign}; -use std::ops::{Sub, SubAssign}; -use std::ops::{Mul, MulAssign}; -use std::ops::{Index, IndexMut}; -use std::cmp::{Eq, PartialEq}; -use std::ops::Neg; +use core::clone::Clone; +use core::fmt::Debug; +use core::ops::{Add, AddAssign}; +use core::ops::{Sub, SubAssign}; +use core::ops::{Mul, MulAssign}; +use core::ops::{Index, IndexMut}; +use core::cmp::{Eq, PartialEq}; +use core::ops::Neg; use util::byte_is_nonzero; @@ -65,7 +65,7 @@ impl PartialEq for FieldElement { impl Eq for FieldElement {} impl Debug for FieldElement { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "FieldElement: {:?}", &self.0[..]) } } diff --git a/src/lib.rs b/src/lib.rs index 9253c39..3145f88 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ // - Isis Agora Lovecruft // - Henry de Valence +#![no_std] #![allow(unused_features)] #![feature(test)] #![deny(missing_docs)] // refuse to compile if documentation is missing @@ -37,6 +38,7 @@ extern crate test; #[macro_use] extern crate arrayref; +#[cfg(feature = "std")] extern crate rand; // Modules for low-level operations directly on field elements and curve points. diff --git a/src/scalar.rs b/src/scalar.rs index 294f127..e22fc8d 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -26,9 +26,10 @@ //! However, in contrast to `FieldElement`s, `Scalar`s are stored in //! memory as bytes, allowing easy access to the bits of the `Scalar`. -use std::clone::Clone; -use std::ops::{Index, IndexMut}; +use core::clone::Clone; +use core::ops::{Index, IndexMut}; +#[cfg(feature = "std")] use rand::Rng; use field::{load3, load4}; @@ -73,6 +74,7 @@ impl Scalar { /// # Returns /// /// A random scalar within ℤ/lℤ. + #[cfg(feature = "std")] pub fn random(csprng: &mut T) -> Self { let mut scalar_bytes = [0u8; 64]; csprng.fill_bytes(&mut scalar_bytes);