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.
|
Entries are listed in reverse chronological order.
|
||||||
|
|
||||||
## 2.0.0-alpha.1
|
## 2.0.0
|
||||||
|
|
||||||
* Update `README.md` for `2.x` series.
|
|
||||||
* Fix a `Zeroize`-related build issue in the AVX2 backend.
|
|
||||||
|
|
||||||
## 2.0.0-alpha.0
|
|
||||||
|
|
||||||
* Fix a data modeling error in the `serde` feature pointed out by Trevor Perrin
|
* 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
|
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
|
compatibility with `serde-json` and ensures that the `serde-bincode` encoding
|
||||||
matches the conventional encoding for X/Ed25519.
|
matches the conventional encoding for X/Ed25519.
|
||||||
* Update `rand_core` to `0.5`, allowing use with new `rand` versions.
|
* 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
|
* 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.
|
`build.rs` to generate constants, and keep the constants in the source code.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "curve25519-dalek"
|
name = "curve25519-dalek"
|
||||||
version = "2.0.0-alpha.1"
|
version = "2.0.0"
|
||||||
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>",
|
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>",
|
||||||
"Henry de Valence <hdevalence@hdevalence.ca>"]
|
"Henry de Valence <hdevalence@hdevalence.ca>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
@ -26,7 +26,6 @@ features = ["nightly", "simd_backend"]
|
||||||
travis-ci = { repository = "dalek-cryptography/curve25519-dalek", branch = "master"}
|
travis-ci = { repository = "dalek-cryptography/curve25519-dalek", branch = "master"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand_os = "0.2"
|
|
||||||
sha2 = { version = "0.8", default-features = false }
|
sha2 = { version = "0.8", default-features = false }
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
criterion = "0.2"
|
criterion = "0.2"
|
||||||
|
|
@ -40,7 +39,7 @@ harness = false
|
||||||
rand_core = { version = "0.5", default-features = false }
|
rand_core = { version = "0.5", default-features = false }
|
||||||
byteorder = { version = "^1.2.3", default-features = false, features = ["i128"] }
|
byteorder = { version = "^1.2.3", default-features = false, features = ["i128"] }
|
||||||
digest = { version = "0.8", default-features = false }
|
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"] }
|
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
|
||||||
packed_simd = { version = "0.3", features = ["into_bits"], optional = true }
|
packed_simd = { version = "0.3", features = ["into_bits"], optional = true }
|
||||||
zeroize = { version = "1", default-features = false }
|
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
|
# Backends and Features
|
||||||
|
|
||||||
The `nightly` feature enables features available only when using a Rust nightly
|
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:
|
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
|
We believe that our constant-time logic is lowered to constant-time
|
||||||
assembly, at least on `x86_64` targets.
|
assembly, at least on `x86_64` targets.
|
||||||
|
|
||||||
As an additional guard against possible future compiler optimizations, the
|
As an additional guard against possible future compiler optimizations,
|
||||||
`nightly` feature places an optimization barrier before every
|
the `subtle` crate places an optimization barrier before every
|
||||||
conditional move or assignment. More details can be found in [the
|
conditional move or assignment. More details can be found in [the
|
||||||
documentation for the `subtle` crate][subtle_doc]. This is
|
documentation for the `subtle` crate][subtle_doc].
|
||||||
recommended, but not required.
|
|
||||||
|
|
||||||
Some functionality (e.g., multiscalar multiplication or batch
|
Some functionality (e.g., multiscalar multiplication or batch
|
||||||
inversion) requires heap allocation for temporary buffers. All
|
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
|
The implementation is memory-safe, and contains no significant
|
||||||
`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
|
`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
|
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
|
# Performance
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ mod ristretto_benches {
|
||||||
c.bench_function_over_inputs(
|
c.bench_function_over_inputs(
|
||||||
"Batch Ristretto double-and-encode",
|
"Batch Ristretto double-and-encode",
|
||||||
|b, &&size| {
|
|b, &&size| {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng;
|
||||||
let points: Vec<RistrettoPoint> = (0..size)
|
let points: Vec<RistrettoPoint> = (0..size)
|
||||||
.map(|_| RistrettoPoint::random(&mut rng))
|
.map(|_| RistrettoPoint::random(&mut rng))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -299,7 +299,7 @@ mod scalar_benches {
|
||||||
c.bench_function_over_inputs(
|
c.bench_function_over_inputs(
|
||||||
"Batch scalar inversion",
|
"Batch scalar inversion",
|
||||||
|b, &&size| {
|
|b, &&size| {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng;
|
||||||
let scalars: Vec<Scalar> = (0..size).map(|_| Scalar::random(&mut rng)).collect();
|
let scalars: Vec<Scalar> = (0..size).map(|_| Scalar::random(&mut rng)).collect();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut s = scalars.clone();
|
let mut s = scalars.clone();
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
|
||||||
// We sum right-to-left.
|
// We sum right-to-left.
|
||||||
|
|
||||||
// Unwrap first loop iteration to save computing 16*identity
|
// Unwrap first loop iteration to save computing 16*identity
|
||||||
let mut tmp2 = ProjectivePoint::identity();
|
let mut tmp2;
|
||||||
let mut tmp3 = EdwardsPoint::identity();
|
let mut tmp3 = EdwardsPoint::identity();
|
||||||
let mut tmp1 = &tmp3 + &lookup_table.select(scalar_digits[63]);
|
let mut tmp1 = &tmp3 + &lookup_table.select(scalar_digits[63]);
|
||||||
// Now tmp1 = s_63*P in P1xP1 coords
|
// Now tmp1 = s_63*P in P1xP1 coords
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@ use backend::serial::u32::scalar::Scalar29;
|
||||||
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
||||||
use window::{LookupTable, NafLookupTable8};
|
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`.
|
/// Edwards `d` value, equal to `-121665/121666 mod p`.
|
||||||
pub(crate) const EDWARDS_D: FieldElement2625 = FieldElement2625([
|
pub(crate) const EDWARDS_D: FieldElement2625 = FieldElement2625([
|
||||||
56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, 48412415, 21499315,
|
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,
|
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.
|
/// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
|
||||||
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement2625 = FieldElement2625([
|
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement2625 = FieldElement2625([
|
||||||
24849947, 33400850, 43495378, 6347714, 46036536, 32887293, 41837720, 18186727, 66238516,
|
24849947, 33400850, 43495378, 6347714, 46036536, 32887293, 41837720, 18186727, 66238516,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@ use backend::serial::u64::scalar::Scalar52;
|
||||||
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
use edwards::{EdwardsBasepointTable, EdwardsPoint};
|
||||||
use window::{LookupTable, NafLookupTable8};
|
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`.
|
/// Edwards `d` value, equal to `-121665/121666 mod p`.
|
||||||
pub(crate) const EDWARDS_D: FieldElement51 = FieldElement51([
|
pub(crate) const EDWARDS_D: FieldElement51 = FieldElement51([
|
||||||
929955233495203,
|
929955233495203,
|
||||||
|
|
@ -34,6 +43,24 @@ pub(crate) const EDWARDS_D2: FieldElement51 = FieldElement51([
|
||||||
633789495995903,
|
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.
|
/// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
|
||||||
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement51 = FieldElement51([
|
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement51 = FieldElement51([
|
||||||
2241493124984347,
|
2241493124984347,
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,6 @@ extern crate packed_simd;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
pub extern crate digest;
|
pub extern crate digest;
|
||||||
extern crate rand_core;
|
extern crate rand_core;
|
||||||
#[cfg(test)]
|
|
||||||
extern crate rand_os;
|
|
||||||
extern crate zeroize;
|
extern crate zeroize;
|
||||||
|
|
||||||
// Used for traits related to constant-time code.
|
// Used for traits related to constant-time code.
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
//! Montgomery arithmetic works not on the curve itself, but on the
|
//! Montgomery arithmetic works not on the curve itself, but on the
|
||||||
//! \\(u\\)-line, which discards sign information and unifies the curve
|
//! \\(u\\)-line, which discards sign information and unifies the curve
|
||||||
//! and its quadratic twist. See [_Montgomery curves and their
|
//! 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
|
//! The `MontgomeryPoint` struct contains the affine \\(u\\)-coordinate
|
||||||
//! \\(u\_0(P)\\) of a point \\(P\\) on either the curve or the twist.
|
//! \\(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::ConditionallySelectable;
|
||||||
use subtle::ConstantTimeEq;
|
use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
|
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
|
||||||
/// Curve25519 or its twist.
|
/// Curve25519 or its twist.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[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 {
|
impl MontgomeryPoint {
|
||||||
/// View this `MontgomeryPoint` as an array of bytes.
|
/// View this `MontgomeryPoint` as an array of bytes.
|
||||||
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
||||||
|
|
@ -352,8 +360,7 @@ mod test {
|
||||||
use constants;
|
use constants;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
use rand_core::OsRng;
|
||||||
use rand_os::OsRng;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
|
|
@ -399,7 +406,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn montgomery_to_edwards_rejects_twist() {
|
fn montgomery_to_edwards_rejects_twist() {
|
||||||
let one = FieldElement::one();
|
let one = FieldElement::one();
|
||||||
|
|
||||||
// u = 2 corresponds to a point on the twist.
|
// u = 2 corresponds to a point on the twist.
|
||||||
let two = MontgomeryPoint((&one+&one).to_bytes());
|
let two = MontgomeryPoint((&one+&one).to_bytes());
|
||||||
|
|
||||||
|
|
@ -422,10 +429,9 @@ 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;
|
||||||
|
|
||||||
let s: Scalar = Scalar::random(&mut csprng);
|
let s: Scalar = Scalar::random(&mut csprng);
|
||||||
let p_edwards: EdwardsPoint = &constants::ED25519_BASEPOINT_TABLE * &s;
|
let p_edwards: EdwardsPoint = &constants::ED25519_BASEPOINT_TABLE * &s;
|
||||||
|
|
|
||||||
|
|
@ -490,13 +490,13 @@ impl RistrettoPoint {
|
||||||
/// ```
|
/// ```
|
||||||
/// # extern crate curve25519_dalek;
|
/// # extern crate curve25519_dalek;
|
||||||
/// # use curve25519_dalek::ristretto::RistrettoPoint;
|
/// # use curve25519_dalek::ristretto::RistrettoPoint;
|
||||||
/// extern crate rand_os;
|
/// extern crate rand_core;
|
||||||
/// use rand_os::OsRng;
|
/// use rand_core::OsRng;
|
||||||
///
|
///
|
||||||
/// # // Need fn main() here in comment so the doctest compiles
|
/// # // Need fn main() here in comment so the doctest compiles
|
||||||
/// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
|
/// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let mut rng = OsRng::new().unwrap();
|
/// let mut rng = OsRng;
|
||||||
/// let points: Vec<RistrettoPoint> =
|
/// let points: Vec<RistrettoPoint> =
|
||||||
/// (0..32).map(|_| RistrettoPoint::random(&mut rng)).collect();
|
/// (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
|
/// This method is not public because it's just used for hashing
|
||||||
/// to a point -- proper elligator support is deferred for now.
|
/// to a point -- proper elligator support is deferred for now.
|
||||||
pub(crate) fn elligator_ristretto_flavor(r_0: &FieldElement) -> RistrettoPoint {
|
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 = 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 r = i * &r_0.square();
|
||||||
let N_s = &(&r + &one) * &one_minus_d_sq;
|
let N_s = &(&r + &one) * &one_minus_d_sq;
|
||||||
let mut c = -&one;
|
|
||||||
let D = &(&c - &(d * &r)) * &(&r + d);
|
let D = &(&c - &(d * &r)) * &(&r + d);
|
||||||
|
|
||||||
let (Ns_D_is_sq, mut s) = FieldElement::sqrt_ratio_i(&N_s, &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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[cfg(feature = "rand")]
|
use rand_core::OsRng;
|
||||||
use rand_os::OsRng;
|
|
||||||
|
|
||||||
use scalar::Scalar;
|
use scalar::Scalar;
|
||||||
use constants;
|
use constants;
|
||||||
|
|
@ -1236,10 +1237,9 @@ 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;
|
||||||
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
||||||
let P = B * &Scalar::random(&mut rng);
|
let P = B * &Scalar::random(&mut rng);
|
||||||
let P_coset = P.coset4();
|
let P_coset = P.coset4();
|
||||||
|
|
@ -1299,10 +1299,9 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn random_roundtrip() {
|
fn random_roundtrip() {
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng;
|
||||||
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
let P = B * &Scalar::random(&mut rng);
|
let P = B * &Scalar::random(&mut rng);
|
||||||
|
|
@ -1312,10 +1311,9 @@ 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;
|
||||||
|
|
||||||
let points: Vec<RistrettoPoint> =
|
let points: Vec<RistrettoPoint> =
|
||||||
(0..1024).map(|_| RistrettoPoint::random(&mut rng)).collect();
|
(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]
|
#[test]
|
||||||
fn vartime_precomputed_vs_nonprecomputed_multiscalar() {
|
fn vartime_precomputed_vs_nonprecomputed_multiscalar() {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,8 @@ use subtle::Choice;
|
||||||
use subtle::ConditionallySelectable;
|
use subtle::ConditionallySelectable;
|
||||||
use subtle::ConstantTimeEq;
|
use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
use backend;
|
use backend;
|
||||||
use constants;
|
use constants;
|
||||||
|
|
||||||
|
|
@ -522,6 +524,12 @@ impl From<u128> for Scalar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Zeroize for Scalar {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.bytes.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Scalar {
|
impl Scalar {
|
||||||
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
|
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
|
||||||
///
|
///
|
||||||
|
|
@ -536,15 +544,15 @@ impl Scalar {
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// extern crate rand_os;
|
/// extern crate rand_core;
|
||||||
/// # extern crate curve25519_dalek;
|
/// # extern crate curve25519_dalek;
|
||||||
/// #
|
/// #
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// use curve25519_dalek::scalar::Scalar;
|
/// 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);
|
/// let a: Scalar = Scalar::random(&mut csprng);
|
||||||
/// # }
|
/// # }
|
||||||
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue