mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Merge branch 'develop' into feature/compressed-try-from
This commit is contained in:
commit
d52ab8bb6f
11 changed files with 96 additions and 58 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -2,12 +2,7 @@
|
|||
|
||||
Entries are listed in reverse chronological order.
|
||||
|
||||
## 2.0.0-alpha.1
|
||||
|
||||
* Update `README.md` for `2.x` series.
|
||||
* Fix a `Zeroize`-related build issue in the AVX2 backend.
|
||||
|
||||
## 2.0.0-alpha.0
|
||||
## 2.0.0
|
||||
|
||||
* Fix a data modeling error in the `serde` feature pointed out by Trevor Perrin
|
||||
which caused points and scalars to be serialized with length fields rather
|
||||
|
|
@ -15,6 +10,11 @@ Entries are listed in reverse chronological order.
|
|||
compatibility with `serde-json` and ensures that the `serde-bincode` encoding
|
||||
matches the conventional encoding for X/Ed25519.
|
||||
* Update `rand_core` to `0.5`, allowing use with new `rand` versions.
|
||||
* Switch from `clear_on_drop` to `zeroize` (by Tony Arcieri).
|
||||
* Require `subtle = ^2.2.1` and remove the note advising nightly Rust, which is
|
||||
no longer required as of that version of `subtle`. See the `subtle`
|
||||
changelog for more details.
|
||||
* Update `README.md` for `2.x` series.
|
||||
* Remove the `build.rs` hack which loaded the entire crate into its own
|
||||
`build.rs` to generate constants, and keep the constants in the source code.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "curve25519-dalek"
|
||||
version = "2.0.0-alpha.1"
|
||||
version = "2.0.0"
|
||||
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>",
|
||||
"Henry de Valence <hdevalence@hdevalence.ca>"]
|
||||
readme = "README.md"
|
||||
|
|
@ -26,7 +26,6 @@ features = ["nightly", "simd_backend"]
|
|||
travis-ci = { repository = "dalek-cryptography/curve25519-dalek", branch = "master"}
|
||||
|
||||
[dev-dependencies]
|
||||
rand_os = "0.2"
|
||||
sha2 = { version = "0.8", default-features = false }
|
||||
bincode = "1"
|
||||
criterion = "0.2"
|
||||
|
|
@ -40,7 +39,7 @@ harness = false
|
|||
rand_core = { version = "0.5", default-features = false }
|
||||
byteorder = { version = "^1.2.3", default-features = false, features = ["i128"] }
|
||||
digest = { version = "0.8", default-features = false }
|
||||
subtle = { version = "2", default-features = false }
|
||||
subtle = { version = "^2.2.1", default-features = false }
|
||||
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
|
||||
packed_simd = { version = "0.3", features = ["into_bits"], optional = true }
|
||||
zeroize = { version = "1", default-features = false }
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -63,7 +63,8 @@ See `CHANGELOG.md` for more details.
|
|||
# Backends and Features
|
||||
|
||||
The `nightly` feature enables features available only when using a Rust nightly
|
||||
compiler. **It is recommended for security**.
|
||||
compiler. In particular, it is required for rendering documentation and for
|
||||
the SIMD backends.
|
||||
|
||||
Curve arithmetic is implemented using one of the following backends:
|
||||
|
||||
|
|
@ -103,11 +104,10 @@ unless specifically marked as being variable-time code.
|
|||
We believe that our constant-time logic is lowered to constant-time
|
||||
assembly, at least on `x86_64` targets.
|
||||
|
||||
As an additional guard against possible future compiler optimizations, the
|
||||
`nightly` feature places an optimization barrier before every
|
||||
As an additional guard against possible future compiler optimizations,
|
||||
the `subtle` crate places an optimization barrier before every
|
||||
conditional move or assignment. More details can be found in [the
|
||||
documentation for the `subtle` crate][subtle_doc]. This is
|
||||
recommended, but not required.
|
||||
documentation for the `subtle` crate][subtle_doc].
|
||||
|
||||
Some functionality (e.g., multiscalar multiplication or batch
|
||||
inversion) requires heap allocation for temporary buffers. All
|
||||
|
|
@ -124,9 +124,9 @@ functions in other crates.
|
|||
|
||||
The implementation is memory-safe, and contains no significant
|
||||
`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
|
||||
intrinsics. These are marked `unsafe` because invoking them on an
|
||||
intrinsics. These are marked `unsafe` only because invoking them on an
|
||||
inappropriate CPU would cause `SIGILL`, but the entire backend is only
|
||||
compiled with appropriate `target_feature`s.
|
||||
compiled with appropriate `target_feature`s, so this cannot occur.
|
||||
|
||||
# Performance
|
||||
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ mod ristretto_benches {
|
|||
c.bench_function_over_inputs(
|
||||
"Batch Ristretto double-and-encode",
|
||||
|b, &&size| {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut rng = OsRng;
|
||||
let points: Vec<RistrettoPoint> = (0..size)
|
||||
.map(|_| RistrettoPoint::random(&mut rng))
|
||||
.collect();
|
||||
|
|
@ -299,7 +299,7 @@ mod scalar_benches {
|
|||
c.bench_function_over_inputs(
|
||||
"Batch scalar inversion",
|
||||
|b, &&size| {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut rng = OsRng;
|
||||
let scalars: Vec<Scalar> = (0..size).map(|_| Scalar::random(&mut rng)).collect();
|
||||
b.iter(|| {
|
||||
let mut s = scalars.clone();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
|
|||
// We sum right-to-left.
|
||||
|
||||
// Unwrap first loop iteration to save computing 16*identity
|
||||
let mut tmp2 = ProjectivePoint::identity();
|
||||
let mut tmp2;
|
||||
let mut tmp3 = EdwardsPoint::identity();
|
||||
let mut tmp1 = &tmp3 + &lookup_table.select(scalar_digits[63]);
|
||||
// Now tmp1 = s_63*P in P1xP1 coords
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ use backend::serial::u32::scalar::Scalar29;
|
|||
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
||||
use window::{LookupTable, NafLookupTable8};
|
||||
|
||||
/// The value of minus one, equal to `-&FieldElement::one()`
|
||||
pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625([
|
||||
67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431
|
||||
]);
|
||||
|
||||
/// Edwards `d` value, equal to `-121665/121666 mod p`.
|
||||
pub(crate) const EDWARDS_D: FieldElement2625 = FieldElement2625([
|
||||
56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, 48412415, 21499315,
|
||||
|
|
@ -28,6 +33,16 @@ pub(crate) const EDWARDS_D2: FieldElement2625 = FieldElement2625([
|
|||
45281625, 27714825, 36363642, 13898781, 229458, 15978800, 54557047, 27058993, 29715967, 9444199,
|
||||
]);
|
||||
|
||||
/// One minus edwards `d` value squared, equal to `(1 - (-121665/121666) mod p) pow 2`
|
||||
pub(crate) const ONE_MINUS_EDWARDS_D_SQUARED: FieldElement2625 = FieldElement2625([
|
||||
6275446, 16937061, 44170319, 29780721, 11667076, 7397348, 39186143, 1766194, 42675006, 672202
|
||||
]);
|
||||
|
||||
/// Edwards `d` value minus one squared, equal to `(((-121665/121666) mod p) - 1) pow 2`
|
||||
pub(crate) const EDWARDS_D_MINUS_ONE_SQUARED: FieldElement2625 = FieldElement2625([
|
||||
15551776, 22456977, 53683765, 23429360, 55212328, 10178283, 40474537, 4729243, 61826754, 23438029
|
||||
]);
|
||||
|
||||
/// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
|
||||
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement2625 = FieldElement2625([
|
||||
24849947, 33400850, 43495378, 6347714, 46036536, 32887293, 41837720, 18186727, 66238516,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,15 @@ use backend::serial::u64::scalar::Scalar52;
|
|||
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
||||
use window::{LookupTable, NafLookupTable8};
|
||||
|
||||
/// The value of minus one, equal to `-&FieldElement::one()`
|
||||
pub(crate) const MINUS_ONE: FieldElement51 = FieldElement51([
|
||||
2251799813685228,
|
||||
2251799813685247,
|
||||
2251799813685247,
|
||||
2251799813685247,
|
||||
2251799813685247
|
||||
]);
|
||||
|
||||
/// Edwards `d` value, equal to `-121665/121666 mod p`.
|
||||
pub(crate) const EDWARDS_D: FieldElement51 = FieldElement51([
|
||||
929955233495203,
|
||||
|
|
@ -34,6 +43,24 @@ pub(crate) const EDWARDS_D2: FieldElement51 = FieldElement51([
|
|||
633789495995903,
|
||||
]);
|
||||
|
||||
/// One minus edwards `d` value squared, equal to `(1 - (-121665/121666) mod p) pow 2`
|
||||
pub(crate) const ONE_MINUS_EDWARDS_D_SQUARED: FieldElement51 = FieldElement51([
|
||||
1136626929484150,
|
||||
1998550399581263,
|
||||
496427632559748,
|
||||
118527312129759,
|
||||
45110755273534
|
||||
]);
|
||||
|
||||
/// Edwards `d` value minus one squared, equal to `(((-121665/121666) mod p) - 1) pow 2`
|
||||
pub(crate) const EDWARDS_D_MINUS_ONE_SQUARED: FieldElement51 = FieldElement51([
|
||||
1507062230895904,
|
||||
1572317787530805,
|
||||
683053064812840,
|
||||
317374165784489,
|
||||
1572899562415810
|
||||
]);
|
||||
|
||||
/// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
|
||||
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement51 = FieldElement51([
|
||||
2241493124984347,
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@ extern crate packed_simd;
|
|||
extern crate byteorder;
|
||||
pub extern crate digest;
|
||||
extern crate rand_core;
|
||||
#[cfg(test)]
|
||||
extern crate rand_os;
|
||||
extern crate zeroize;
|
||||
|
||||
// Used for traits related to constant-time code.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
//! Montgomery arithmetic works not on the curve itself, but on the
|
||||
//! \\(u\\)-line, which discards sign information and unifies the curve
|
||||
//! and its quadratic twist. See [_Montgomery curves and their
|
||||
//! arithmetic_][costello-smith] by Costello and Smith for more details.
|
||||
//! arithmetic_][costello-smith] by Costello and Smith for more details.
|
||||
//!
|
||||
//! The `MontgomeryPoint` struct contains the affine \\(u\\)-coordinate
|
||||
//! \\(u\_0(P)\\) of a point \\(P\\) on either the curve or the twist.
|
||||
|
|
@ -62,6 +62,8 @@ use subtle::Choice;
|
|||
use subtle::ConditionallySelectable;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use zeroize::Zeroize;
|
||||
|
||||
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
|
||||
/// Curve25519 or its twist.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
@ -110,6 +112,12 @@ impl ValidityCheck for MontgomeryPoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl Zeroize for MontgomeryPoint {
|
||||
fn zeroize(&mut self) {
|
||||
self.0.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
impl MontgomeryPoint {
|
||||
/// View this `MontgomeryPoint` as an array of bytes.
|
||||
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
||||
|
|
@ -352,8 +360,7 @@ mod test {
|
|||
use constants;
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
use rand_os::OsRng;
|
||||
use rand_core::OsRng;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
@ -399,7 +406,7 @@ mod test {
|
|||
#[test]
|
||||
fn montgomery_to_edwards_rejects_twist() {
|
||||
let one = FieldElement::one();
|
||||
|
||||
|
||||
// u = 2 corresponds to a point on the twist.
|
||||
let two = MontgomeryPoint((&one+&one).to_bytes());
|
||||
|
||||
|
|
@ -422,10 +429,9 @@ mod test {
|
|||
assert_eq!(u18, u18_unred);
|
||||
}
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
#[test]
|
||||
fn montgomery_ladder_matches_edwards_scalarmult() {
|
||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
let s: Scalar = Scalar::random(&mut csprng);
|
||||
let p_edwards: EdwardsPoint = &constants::ED25519_BASEPOINT_TABLE * &s;
|
||||
|
|
|
|||
|
|
@ -490,13 +490,13 @@ impl RistrettoPoint {
|
|||
/// ```
|
||||
/// # extern crate curve25519_dalek;
|
||||
/// # use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
/// extern crate rand_os;
|
||||
/// use rand_os::OsRng;
|
||||
/// extern crate rand_core;
|
||||
/// use rand_core::OsRng;
|
||||
///
|
||||
/// # // Need fn main() here in comment so the doctest compiles
|
||||
/// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
|
||||
/// # fn main() {
|
||||
/// let mut rng = OsRng::new().unwrap();
|
||||
/// let mut rng = OsRng;
|
||||
/// let points: Vec<RistrettoPoint> =
|
||||
/// (0..32).map(|_| RistrettoPoint::random(&mut rng)).collect();
|
||||
///
|
||||
|
|
@ -603,14 +603,16 @@ impl RistrettoPoint {
|
|||
/// This method is not public because it's just used for hashing
|
||||
/// to a point -- proper elligator support is deferred for now.
|
||||
pub(crate) fn elligator_ristretto_flavor(r_0: &FieldElement) -> RistrettoPoint {
|
||||
let (i, d) = (&constants::SQRT_M1, &constants::EDWARDS_D);
|
||||
let i = &constants::SQRT_M1;
|
||||
let d = &constants::EDWARDS_D;
|
||||
let one_minus_d_sq = &constants::ONE_MINUS_EDWARDS_D_SQUARED;
|
||||
let d_minus_one_sq = &constants::EDWARDS_D_MINUS_ONE_SQUARED;
|
||||
let mut c = constants::MINUS_ONE;
|
||||
|
||||
let one = FieldElement::one();
|
||||
let one_minus_d_sq = &one - &d.square();
|
||||
let d_minus_one_sq = (d - &one).square();
|
||||
|
||||
let r = i * &r_0.square();
|
||||
let N_s = &(&r + &one) * &one_minus_d_sq;
|
||||
let mut c = -&one;
|
||||
let D = &(&c - &(d * &r)) * &(&r + d);
|
||||
|
||||
let (Ns_D_is_sq, mut s) = FieldElement::sqrt_ratio_i(&N_s, &D);
|
||||
|
|
@ -1087,8 +1089,7 @@ impl Debug for RistrettoPoint {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[cfg(feature = "rand")]
|
||||
use rand_os::OsRng;
|
||||
use rand_core::OsRng;
|
||||
|
||||
use scalar::Scalar;
|
||||
use constants;
|
||||
|
|
@ -1236,10 +1237,9 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
#[test]
|
||||
fn four_torsion_random() {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut rng = OsRng;
|
||||
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
||||
let P = B * &Scalar::random(&mut rng);
|
||||
let P_coset = P.coset4();
|
||||
|
|
@ -1299,10 +1299,9 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
#[test]
|
||||
fn random_roundtrip() {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut rng = OsRng;
|
||||
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
||||
for _ in 0..100 {
|
||||
let P = B * &Scalar::random(&mut rng);
|
||||
|
|
@ -1312,10 +1311,9 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
#[test]
|
||||
fn double_and_compress_1024_random_points() {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut rng = OsRng;
|
||||
|
||||
let points: Vec<RistrettoPoint> =
|
||||
(0..1024).map(|_| RistrettoPoint::random(&mut rng)).collect();
|
||||
|
|
@ -1327,19 +1325,6 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
#[test]
|
||||
fn random_is_valid() {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
for _ in 0..100 {
|
||||
let P = RistrettoPoint::random(&mut rng);
|
||||
// Check that P is on the curve
|
||||
assert!(P.0.is_valid());
|
||||
// Check that P is in the image of the ristretto map
|
||||
P.compress();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vartime_precomputed_vs_nonprecomputed_multiscalar() {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ use subtle::Choice;
|
|||
use subtle::ConditionallySelectable;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use backend;
|
||||
use constants;
|
||||
|
||||
|
|
@ -522,6 +524,12 @@ impl From<u128> for Scalar {
|
|||
}
|
||||
}
|
||||
|
||||
impl Zeroize for Scalar {
|
||||
fn zeroize(&mut self) {
|
||||
self.bytes.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
impl Scalar {
|
||||
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
|
||||
///
|
||||
|
|
@ -536,15 +544,15 @@ impl Scalar {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// extern crate rand_os;
|
||||
/// extern crate rand_core;
|
||||
/// # extern crate curve25519_dalek;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// use curve25519_dalek::scalar::Scalar;
|
||||
///
|
||||
/// use rand_os::OsRng;
|
||||
/// use rand_core::OsRng;
|
||||
///
|
||||
/// let mut csprng: OsRng = OsRng::new().unwrap();
|
||||
/// let mut csprng = OsRng;
|
||||
/// let a: Scalar = Scalar::random(&mut csprng);
|
||||
/// # }
|
||||
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
|
|
|
|||
Loading…
Reference in a new issue