From ed11f440ce0118123a066b01904069492479aa0d Mon Sep 17 00:00:00 2001 From: Tomas Krnak <15908613+jarys@users.noreply.github.com> Date: Fri, 6 May 2022 16:57:45 +0200 Subject: [PATCH] Add `no-std` support (#11) * Add no_std support * Update CHANGELOG * Remove unused alloc feature flag * Remove a forgotten comment Co-authored-by: str4d * Make zeroize dependency optional * Add alloc feature flag * Clean the code by outer attributes * use 2021 edition Co-authored-by: str4d Co-authored-by: Conrado Gouvea --- CHANGELOG.md | 3 +++ Cargo.toml | 27 +++++++++++++++++---------- src/batch.rs | 5 +++-- src/error.rs | 20 +++++++++++++++----- src/frost.rs | 1 + src/hash.rs | 2 +- src/lib.rs | 19 ++++++++++++++++++- src/messages.rs | 1 + src/orchard.rs | 23 +++++++++++++++-------- src/scalar_mul.rs | 3 ++- src/signature.rs | 2 +- src/signing_key.rs | 2 +- src/verification_key.rs | 2 +- tests/batch.rs | 2 ++ tests/bincode.rs | 4 ++-- tests/frost.rs | 2 ++ tests/librustzcash_vectors.rs | 2 +- tests/proptests.rs | 2 +- tests/smallorder.rs | 2 +- 19 files changed, 88 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc37dde..0a6f8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Entries are listed in reverse chronological order. ## Unreleased * Migrate to `group` 0.12, `jubjub` 0.9, `pasta_curves` 0.4 +* Added support for `no-std` builds, via new (default-enabled) `std` and `alloc` + feature flags. Module `batch` is supported on `alloc` feature only. Module + `frost` is supported on `std` feature only. ## 0.2.0 diff --git a/Cargo.toml b/Cargo.toml index 05f8e32..676d2d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reddsa" -edition = "2018" +edition = "2021" # When releasing to crates.io: # - Update html_root_url # - Update CHANGELOG.md @@ -23,15 +23,19 @@ description = "A standalone implementation of the RedDSA signature scheme." features = ["nightly"] [dependencies] -blake2b_simd = "1" -byteorder = "1.4" -group = "0.12" -jubjub = "0.9" -pasta_curves = "0.4" -rand_core = "0.6" +blake2b_simd = { version = "1", default-features = false } +byteorder = { version = "1.4", default-features = false } +group = { version = "0.12", default-features = false } +jubjub = { version = "0.9", default-features = false } +pasta_curves = { version = "0.4", default-features = false, features = ["alloc"] } +rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, features = ["derive"] } -thiserror = "1.0" -zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } +thiserror = { version = "1.0", optional = true } + +[dependencies.zeroize] +version = "1" +features = ["zeroize_derive"] +optional = true [dev-dependencies] bincode = "1" @@ -44,8 +48,11 @@ rand_chacha = "0.3" serde_json = "1.0" [features] +std = ["blake2b_simd/std", "thiserror", "zeroize", "alloc", + "serde"] # conditional compilation for serde not complete (issue #9) +alloc = [] nightly = [] -default = ["serde"] +default = ["std"] [[bench]] name = "bench" diff --git a/src/batch.rs b/src/batch.rs index e092d21..1d0a3d0 100644 --- a/src/batch.rs +++ b/src/batch.rs @@ -18,7 +18,8 @@ //! and loss of the ability to easily pinpoint failing signatures. //! -use std::convert::TryFrom; +use alloc::vec::Vec; +use core::convert::TryFrom; use group::{ cofactor::CofactorGroup, @@ -246,7 +247,7 @@ impl> Verifier // - Henry de Valence -use thiserror::Error; +use core::fmt; /// An error related to RedDSA signatures. -#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Error { /// The encoding of a signing key was malformed. - #[error("Malformed signing key encoding.")] MalformedSigningKey, /// The encoding of a verification key was malformed. - #[error("Malformed verification key encoding.")] MalformedVerificationKey, /// Signature verification failed. - #[error("Invalid signature.")] InvalidSignature, } + +#[cfg(feature = "std")] +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::MalformedSigningKey => write!(f, "Malformed signing key encoding."), + Self::MalformedVerificationKey => write!(f, "Malformed verification key encoding."), + Self::InvalidSignature => write!(f, "Invalid signature."), + } + } +} diff --git a/src/frost.rs b/src/frost.rs index 21f169f..6ed8c4d 100644 --- a/src/frost.rs +++ b/src/frost.rs @@ -23,6 +23,7 @@ //! Internally, keygen_with_dealer generates keys using Verifiable Secret //! Sharing, where shares are generated using Shamir Secret Sharing. +use alloc::vec::Vec; use std::{ collections::HashMap, convert::{TryFrom, TryInto}, diff --git a/src/hash.rs b/src/hash.rs index d73f822..a6d52a7 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -8,7 +8,7 @@ // - Deirdre Connolly // - Henry de Valence -use std::marker::PhantomData; +use core::marker::PhantomData; use blake2b_simd::{Params, State}; diff --git a/src/lib.rs b/src/lib.rs index 2e3723a..dd40311 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,19 +8,30 @@ // - Deirdre Connolly // - Henry de Valence +#![no_std] #![deny(missing_docs)] #![doc = include_str!("../README.md")] //! Docs require the `nightly` feature until RFC 1990 lands. +#[cfg(feature = "alloc")] +#[macro_use] +extern crate alloc; +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "alloc")] pub mod batch; mod constants; mod error; +#[cfg(feature = "std")] pub mod frost; mod hash; +#[cfg(feature = "std")] mod messages; pub mod orchard; pub mod sapling; +#[cfg(feature = "alloc")] mod scalar_mul; pub(crate) mod signature; mod signing_key; @@ -74,12 +85,18 @@ pub(crate) mod private { } pub trait Sealed: - Copy + Clone + Default + Eq + PartialEq + std::fmt::Debug + Copy + Clone + Default + Eq + PartialEq + core::fmt::Debug { const H_STAR_PERSONALIZATION: &'static [u8; 16]; type Scalar: group::ff::PrimeField + SealedScalar; + + // `Point: VartimeMultiscalarMul` is conditioned by `alloc` feature flag + // This is fine because `Sealed` is an internal trait. + #[cfg(feature = "alloc")] type Point: group::cofactor::CofactorCurve + scalar_mul::VartimeMultiscalarMul; + #[cfg(not(feature = "alloc"))] + type Point: group::cofactor::CofactorCurve; fn basepoint() -> T::Point; } diff --git a/src/messages.rs b/src/messages.rs index 170d924..67e0f2a 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -6,6 +6,7 @@ use crate::{frost, signature, verification_key, SpendAuth}; use group::GroupEncoding; use serde::{Deserialize, Serialize}; +use alloc::vec::Vec; use std::{collections::BTreeMap, convert::TryInto}; #[cfg(test)] diff --git a/src/orchard.rs b/src/orchard.rs index 4a64661..0ff57e9 100644 --- a/src/orchard.rs +++ b/src/orchard.rs @@ -1,15 +1,19 @@ //! Signature types for the Orchard protocol. -use std::borrow::Borrow; - -use group::{ff::PrimeField, Group, GroupEncoding}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +#[cfg(feature = "alloc")] +use core::borrow::Borrow; + +use group::GroupEncoding; +#[cfg(feature = "alloc")] +use group::{ff::PrimeField, Group}; use pasta_curves::pallas; -use crate::{ - private, - scalar_mul::{LookupTable5, NonAdjacentForm, VartimeMultiscalarMul}, - SigType, -}; +use crate::{private, SigType}; + +#[cfg(feature = "alloc")] +use crate::scalar_mul::{LookupTable5, NonAdjacentForm, VartimeMultiscalarMul}; /// The byte-encoding of the basepoint for `OrchardSpendAuthSig`. const ORCHARD_SPENDAUTHSIG_BASEPOINT_BYTES: [u8; 32] = [ @@ -74,6 +78,7 @@ impl private::Sealed for Binding { } } +#[cfg(feature = "alloc")] impl NonAdjacentForm for pallas::Scalar { /// Compute a width-\\(w\\) "Non-Adjacent Form" of this scalar. /// @@ -136,6 +141,7 @@ impl NonAdjacentForm for pallas::Scalar { } } +#[cfg(feature = "alloc")] impl<'a> From<&'a pallas::Point> for LookupTable5 { #[allow(non_snake_case)] fn from(A: &'a pallas::Point) -> Self { @@ -149,6 +155,7 @@ impl<'a> From<&'a pallas::Point> for LookupTable5 { } } +#[cfg(feature = "alloc")] impl VartimeMultiscalarMul for pallas::Point { type Scalar = pallas::Scalar; type Point = pallas::Point; diff --git a/src/scalar_mul.rs b/src/scalar_mul.rs index a62248c..29585db 100644 --- a/src/scalar_mul.rs +++ b/src/scalar_mul.rs @@ -10,7 +10,8 @@ // - Henry de Valence // - Deirdre Connolly -use std::{borrow::Borrow, fmt::Debug}; +use alloc::vec::Vec; +use core::{borrow::Borrow, fmt::Debug}; use jubjub::{ExtendedNielsPoint, ExtendedPoint}; diff --git a/src/signature.rs b/src/signature.rs index 93ac7b0..9236ef1 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -8,7 +8,7 @@ // - Henry de Valence //! RedDSA Signatures -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::SigType; diff --git a/src/signing_key.rs b/src/signing_key.rs index 2fe88ab..dfe7219 100644 --- a/src/signing_key.rs +++ b/src/signing_key.rs @@ -8,7 +8,7 @@ // - Deirdre Connolly // - Henry de Valence -use std::{ +use core::{ convert::{TryFrom, TryInto}, marker::PhantomData, }; diff --git a/src/verification_key.rs b/src/verification_key.rs index 02966d9..3915d7c 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -8,7 +8,7 @@ // - Deirdre Connolly // - Henry de Valence -use std::{ +use core::{ convert::{TryFrom, TryInto}, hash::{Hash, Hasher}, marker::PhantomData, diff --git a/tests/batch.rs b/tests/batch.rs index b7d62bc..6baada1 100644 --- a/tests/batch.rs +++ b/tests/batch.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "alloc")] + use rand::thread_rng; use reddsa::*; diff --git a/tests/bincode.rs b/tests/bincode.rs index e482130..e2bbb36 100644 --- a/tests/bincode.rs +++ b/tests/bincode.rs @@ -1,8 +1,8 @@ -use std::convert::TryFrom; +#![cfg(feature = "std")] use proptest::prelude::*; - use reddsa::*; +use std::convert::TryFrom; proptest! { #[test] diff --git a/tests/frost.rs b/tests/frost.rs index e4be0a4..3fd2906 100644 --- a/tests/frost.rs +++ b/tests/frost.rs @@ -1,3 +1,5 @@ +#![cfg(all(feature = "std", feature = "serde"))] + use rand::thread_rng; use std::collections::HashMap; diff --git a/tests/librustzcash_vectors.rs b/tests/librustzcash_vectors.rs index 6dc2d04..b6f59d9 100644 --- a/tests/librustzcash_vectors.rs +++ b/tests/librustzcash_vectors.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; #[macro_use] extern crate lazy_static; diff --git a/tests/proptests.rs b/tests/proptests.rs index 9ffe0ee..6037111 100644 --- a/tests/proptests.rs +++ b/tests/proptests.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; use proptest::prelude::*; use rand_core::{CryptoRng, RngCore}; diff --git a/tests/smallorder.rs b/tests/smallorder.rs index 7efbdf7..650f053 100644 --- a/tests/smallorder.rs +++ b/tests/smallorder.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; use jubjub::{AffinePoint, Fq};