mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Unify alloc and std cargo features
This change provides a common convention for using allocator-dependent
features with:
#![cfg(feature = "alloc")]
When available, `Vec` is imported consistently as `prelude::Vec`, which
means modules that need access to `Vec` can simply do:
use prelude::*;
and if an allocator is available, `Vec` will be in the crate prelude.
This allows all `alloc` vs `std` gating to be handled in `lib.rs`,
`build.rs`, and `prelude.rs` so the rest of the codebase doesn't have to
do any gating whatsoever.
This commit is contained in:
parent
f675f4cd2b
commit
10e8abf926
13 changed files with 66 additions and 21 deletions
|
|
@ -15,16 +15,18 @@ env:
|
||||||
- TEST_COMMAND=test EXTRA_FLAGS='' FEATURES='serde'
|
- TEST_COMMAND=test EXTRA_FLAGS='' FEATURES='serde'
|
||||||
# Tests building without std. We have to select a backend, so we select the one
|
# Tests building without std. We have to select a backend, so we select the one
|
||||||
# most likely to be useful in an embedded environment.
|
# most likely to be useful in an embedded environment.
|
||||||
- TEST_COMMAND=build EXTRA_FLAGS=--no-default-features FEATURES='u32_backend'
|
- TEST_COMMAND=build EXTRA_FLAGS='--no-default-features' FEATURES='u32_backend'
|
||||||
|
# Tests no_std+alloc usage using the most embedded-friendly backend
|
||||||
|
- TEST_COMMAND=test EXTRA_FLAGS='--lib --no-default-features' FEATURES='alloc u32_backend'
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
exclude:
|
exclude:
|
||||||
# Test the avx2 backend only on nightly
|
# Test the avx2 backend only on nightly
|
||||||
- rust: stable
|
- rust: stable
|
||||||
env: TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std avx2_backend'
|
env: TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std avx2_backend'
|
||||||
# Test no_std only on nightly.
|
# Test no_std+alloc only on nightly
|
||||||
- rust: stable
|
- rust: stable
|
||||||
env: TEST_COMMAND=build EXTRA_FLAGS=--no-default-features FEATURES='u32_backend'
|
env: TEST_COMMAND=test EXTRA_FLAGS='--lib --no-default-features' FEATURES='alloc u32_backend'
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cargo $TEST_COMMAND --features="$FEATURES" $EXTRA_FLAGS
|
- cargo $TEST_COMMAND --features="$FEATURES" $EXTRA_FLAGS
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ serde = { version = "1.0", optional = true }
|
||||||
[features]
|
[features]
|
||||||
nightly = ["subtle/nightly", "clear_on_drop/nightly"]
|
nightly = ["subtle/nightly", "clear_on_drop/nightly"]
|
||||||
default = ["std", "u64_backend"]
|
default = ["std", "u64_backend"]
|
||||||
std = ["subtle/std", "rand/std"]
|
std = ["alloc", "subtle/std", "rand/std"]
|
||||||
alloc = []
|
alloc = []
|
||||||
yolocrypto = []
|
yolocrypto = []
|
||||||
|
|
||||||
|
|
|
||||||
5
build.rs
5
build.rs
|
|
@ -1,9 +1,12 @@
|
||||||
|
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
|
||||||
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
||||||
#![cfg_attr(all(feature = "nightly", feature = "avx2_backend"), feature(stdsimd))]
|
#![cfg_attr(all(feature = "nightly", feature = "avx2_backend"), feature(stdsimd))]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
|
extern crate alloc;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate clear_on_drop;
|
extern crate clear_on_drop;
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
@ -53,6 +56,8 @@ mod field;
|
||||||
mod curve_models;
|
mod curve_models;
|
||||||
#[path = "src/backend/mod.rs"]
|
#[path = "src/backend/mod.rs"]
|
||||||
mod backend;
|
mod backend;
|
||||||
|
#[path = "src/prelude.rs"]
|
||||||
|
mod prelude;
|
||||||
#[path = "src/scalar_mul/mod.rs"]
|
#[path = "src/scalar_mul/mod.rs"]
|
||||||
mod scalar_mul;
|
mod scalar_mul;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ use scalar::Scalar;
|
||||||
use scalar_mul::window::{LookupTable, NafLookupTable5};
|
use scalar_mul::window::{LookupTable, NafLookupTable5};
|
||||||
use traits::{Identity, MultiscalarMul, VartimeMultiscalarMul};
|
use traits::{Identity, MultiscalarMul, VartimeMultiscalarMul};
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
/// Multiscalar multiplication using interleaved window / Straus'
|
/// Multiscalar multiplication using interleaved window / Straus'
|
||||||
/// method. See the `Straus` struct in the serial backend for more
|
/// method. See the `Straus` struct in the serial backend for more
|
||||||
/// details.
|
/// details.
|
||||||
|
|
@ -30,7 +33,7 @@ use traits::{Identity, MultiscalarMul, VartimeMultiscalarMul};
|
||||||
/// point representation on the fly.
|
/// point representation on the fly.
|
||||||
pub struct Straus {}
|
pub struct Straus {}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl MultiscalarMul for Straus {
|
impl MultiscalarMul for Straus {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
@ -68,7 +71,7 @@ impl MultiscalarMul for Straus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl VartimeMultiscalarMul for Straus {
|
impl VartimeMultiscalarMul for Straus {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,12 @@
|
||||||
//! `32bit` since identifiers can't start with letters, and the backends
|
//! `32bit` since identifiers can't start with letters, and the backends
|
||||||
//! do use `u32`/`u64`, so this seems like a least-bad option.
|
//! do use `u32`/`u64`, so this seems like a least-bad option.
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "u32_backend", feature = "u64_backend", feature = "avx2_backend")))]
|
||||||
|
compile_error!(
|
||||||
|
"no curve25519-dalek backend cargo feature enabled! \
|
||||||
|
please enable one of: u32_backend, u64_backend, avx2_backend"
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "u32_backend")]
|
#[cfg(feature = "u32_backend")]
|
||||||
pub mod u32;
|
pub mod u32;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ use curve_models::CompletedPoint;
|
||||||
use curve_models::AffineNielsPoint;
|
use curve_models::AffineNielsPoint;
|
||||||
use curve_models::ProjectiveNielsPoint;
|
use curve_models::ProjectiveNielsPoint;
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
use scalar_mul::window::LookupTable;
|
use scalar_mul::window::LookupTable;
|
||||||
|
|
||||||
use traits::{Identity, IsIdentity};
|
use traits::{Identity, IsIdentity};
|
||||||
|
|
@ -540,7 +543,7 @@ impl<'a, 'b> Mul<&'b EdwardsPoint> for &'a Scalar {
|
||||||
// These use the iterator's size hint and the target settings to
|
// These use the iterator's size hint and the target settings to
|
||||||
// forward to a specific backend implementation.
|
// forward to a specific backend implementation.
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl MultiscalarMul for EdwardsPoint {
|
impl MultiscalarMul for EdwardsPoint {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
@ -569,7 +572,7 @@ impl MultiscalarMul for EdwardsPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl VartimeMultiscalarMul for EdwardsPoint {
|
impl VartimeMultiscalarMul for EdwardsPoint {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ impl FieldElement {
|
||||||
/// Given a slice of public `FieldElements`, replace each with its inverse.
|
/// Given a slice of public `FieldElements`, replace each with its inverse.
|
||||||
///
|
///
|
||||||
/// All input `FieldElements` **MUST** be nonzero.
|
/// All input `FieldElements` **MUST** be nonzero.
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn batch_invert(inputs: &mut [FieldElement]) {
|
pub fn batch_invert(inputs: &mut [FieldElement]) {
|
||||||
// Montgomery’s Trick and Fast Implementation of Masked AES
|
// Montgomery’s Trick and Fast Implementation of Masked AES
|
||||||
// Genelle, Prouff and Quisquater
|
// Genelle, Prouff and Quisquater
|
||||||
|
|
|
||||||
17
src/lib.rs
17
src/lib.rs
|
|
@ -8,10 +8,9 @@
|
||||||
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
|
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
|
||||||
// - Henry de Valence <hdevalence@hdevalence.ca>
|
// - Henry de Valence <hdevalence@hdevalence.ca>
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![no_std]
|
||||||
|
|
||||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
|
||||||
|
|
||||||
|
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
|
||||||
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
||||||
#![cfg_attr(feature = "nightly", feature(external_doc))]
|
#![cfg_attr(feature = "nightly", feature(external_doc))]
|
||||||
#![cfg_attr(all(feature = "nightly", feature = "avx2_backend"), feature(stdsimd))]
|
#![cfg_attr(all(feature = "nightly", feature = "avx2_backend"), feature(stdsimd))]
|
||||||
|
|
@ -32,11 +31,14 @@
|
||||||
// External dependencies:
|
// External dependencies:
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
extern crate core;
|
#[macro_use]
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate clear_on_drop;
|
extern crate clear_on_drop;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
|
@ -94,5 +96,8 @@ pub(crate) mod backend;
|
||||||
// Internal curve models which are not part of the public API.
|
// Internal curve models which are not part of the public API.
|
||||||
pub(crate) mod curve_models;
|
pub(crate) mod curve_models;
|
||||||
|
|
||||||
|
// Crate-local prelude (for alloc-dependent features like `Vec`)
|
||||||
|
pub(crate) mod prelude;
|
||||||
|
|
||||||
// Implementations of scalar mul algorithms live here
|
// Implementations of scalar mul algorithms live here
|
||||||
pub(crate) mod scalar_mul;
|
pub(crate) mod scalar_mul;
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,7 @@ mod test {
|
||||||
use constants;
|
use constants;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
/// Test Montgomery -> Edwards on the X/Ed25519 basepoint
|
/// Test Montgomery -> Edwards on the X/Ed25519 basepoint
|
||||||
|
|
@ -343,6 +344,7 @@ mod test {
|
||||||
assert_eq!(u18, u18_unred);
|
assert_eq!(u18, u18_unred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
#[test]
|
#[test]
|
||||||
fn montgomery_ladder_matches_edwards_scalarmult() {
|
fn montgomery_ladder_matches_edwards_scalarmult() {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
|
|
|
||||||
8
src/prelude.rs
Normal file
8
src/prelude.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//! Crate-local prelude (for alloc-dependent features like `Vec`)
|
||||||
|
|
||||||
|
// TODO: switch to alloc::prelude
|
||||||
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
|
pub use alloc::vec::Vec;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub use std::vec::Vec;
|
||||||
|
|
@ -178,6 +178,9 @@ use subtle::Choice;
|
||||||
use edwards::EdwardsPoint;
|
use edwards::EdwardsPoint;
|
||||||
use edwards::EdwardsBasepointTable;
|
use edwards::EdwardsBasepointTable;
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
use scalar::Scalar;
|
use scalar::Scalar;
|
||||||
|
|
||||||
use curve_models::CompletedPoint;
|
use curve_models::CompletedPoint;
|
||||||
|
|
@ -418,7 +421,7 @@ impl RistrettoPoint {
|
||||||
/// }
|
/// }
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn double_and_compress_batch<'a, I>(points: I) -> Vec<CompressedRistretto>
|
pub fn double_and_compress_batch<'a, I>(points: I) -> Vec<CompressedRistretto>
|
||||||
where I: IntoIterator<Item = &'a RistrettoPoint>
|
where I: IntoIterator<Item = &'a RistrettoPoint>
|
||||||
{
|
{
|
||||||
|
|
@ -798,7 +801,7 @@ define_mul_variants!(LHS = Scalar, RHS = RistrettoPoint, Output = RistrettoPoint
|
||||||
// These use iterator combinators to unwrap the underlying points and
|
// These use iterator combinators to unwrap the underlying points and
|
||||||
// forward to the EdwardsPoint implementations.
|
// forward to the EdwardsPoint implementations.
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl MultiscalarMul for RistrettoPoint {
|
impl MultiscalarMul for RistrettoPoint {
|
||||||
type Point = RistrettoPoint;
|
type Point = RistrettoPoint;
|
||||||
|
|
||||||
|
|
@ -816,7 +819,7 @@ impl MultiscalarMul for RistrettoPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl VartimeMultiscalarMul for RistrettoPoint {
|
impl VartimeMultiscalarMul for RistrettoPoint {
|
||||||
type Point = RistrettoPoint;
|
type Point = RistrettoPoint;
|
||||||
|
|
||||||
|
|
@ -955,6 +958,7 @@ impl Debug for RistrettoPoint {
|
||||||
|
|
||||||
#[cfg(all(test, feature = "stage2_build"))]
|
#[cfg(all(test, feature = "stage2_build"))]
|
||||||
mod test {
|
mod test {
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
use scalar::Scalar;
|
use scalar::Scalar;
|
||||||
|
|
@ -1090,6 +1094,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
#[test]
|
#[test]
|
||||||
fn four_torsion_random() {
|
fn four_torsion_random() {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().unwrap();
|
||||||
|
|
@ -1152,6 +1157,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
#[test]
|
#[test]
|
||||||
fn random_roundtrip() {
|
fn random_roundtrip() {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().unwrap();
|
||||||
|
|
@ -1164,6 +1170,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
#[test]
|
#[test]
|
||||||
fn double_and_compress_1024_random_points() {
|
fn double_and_compress_1024_random_points() {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().unwrap();
|
||||||
|
|
@ -1178,6 +1185,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
#[test]
|
#[test]
|
||||||
fn random_is_valid() {
|
fn random_is_valid() {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -725,7 +725,7 @@ impl Scalar {
|
||||||
/// assert_eq!(scalars[3], Scalar::from(11u64).invert());
|
/// assert_eq!(scalars[3], Scalar::from(11u64).invert());
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn batch_invert(inputs: &mut [Scalar]) -> Scalar {
|
pub fn batch_invert(inputs: &mut [Scalar]) -> Scalar {
|
||||||
// This code is essentially identical to the FieldElement
|
// This code is essentially identical to the FieldElement
|
||||||
// implementation, and is documented there. Unfortunately,
|
// implementation, and is documented there. Unfortunately,
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ use traits::MultiscalarMul;
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
use traits::VartimeMultiscalarMul;
|
use traits::VartimeMultiscalarMul;
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
/// Perform multiscalar multiplication by the interleaved window
|
/// Perform multiscalar multiplication by the interleaved window
|
||||||
/// method, also known as Straus' method (since it was apparently
|
/// method, also known as Straus' method (since it was apparently
|
||||||
/// [first published][solution] by Straus in 1964, as a solution to [a
|
/// [first published][solution] by Straus in 1964, as a solution to [a
|
||||||
|
|
@ -48,7 +51,7 @@ use traits::VartimeMultiscalarMul;
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub struct Straus {}
|
pub struct Straus {}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl MultiscalarMul for Straus {
|
impl MultiscalarMul for Straus {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
@ -145,7 +148,7 @@ impl MultiscalarMul for Straus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(feature = "alloc")]
|
||||||
impl VartimeMultiscalarMul for Straus {
|
impl VartimeMultiscalarMul for Straus {
|
||||||
type Point = EdwardsPoint;
|
type Point = EdwardsPoint;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue