Merge remote-tracking branch 'isis/develop' into develop

This commit is contained in:
Henry de Valence 2017-08-02 18:03:59 -07:00
commit 9d20a4aca0
9 changed files with 129 additions and 159 deletions

View file

@ -1,10 +1,10 @@
[package] [package]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "0.9.3" version = "0.10.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"
license = "CC0-1.0" license = "BSD-3-Clause"
repository = "https://github.com/isislovecruft/curve25519-dalek" repository = "https://github.com/isislovecruft/curve25519-dalek"
homepage = "https://code.ciph.re/isis/curve25519-dalek" homepage = "https://code.ciph.re/isis/curve25519-dalek"
documentation = "https://docs.rs/curve25519-dalek" documentation = "https://docs.rs/curve25519-dalek"
@ -33,7 +33,7 @@ version = "0.3"
version = "0.6" version = "0.6"
[dependencies.subtle] [dependencies.subtle]
version = "^0.1" version = "^0.2"
default-features = false default-features = false
[dependencies.generic-array] [dependencies.generic-array]
@ -47,7 +47,7 @@ version = "0.6"
version = "0.6" version = "0.6"
[features] [features]
nightly = ["radix_51"] nightly = ["radix_51", "subtle/nightly"]
default = ["std"] default = ["std"]
std = ["rand", "subtle/std"] std = ["rand", "subtle/std"]
alloc = [] alloc = []

169
LICENSE
View file

@ -1,129 +1,64 @@
To the extent possible under law, the author(s) have waived all copyright and related or Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
neighboring rights to curve25519-dalek, using the Creative Commons "CC0" public domain dedication.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Creative Commons CC0 1.0 Universal 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL 3. Neither the name of the copyright holder nor the names of its
SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT contributors may be used to endorse or promote products derived from
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" this software without specific prior written permission.
BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT
OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR
DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER.
Statement of Purpose THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The laws of most jurisdictions throughout the world automatically confer ========================================================================
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the Portions of curve25519-dalek were originally derived from Adam Langley's
purpose of contributing to a commons of creative, cultural and scientific Go ed25519 implementation, found at <https://github.com/agl/ed25519/>,
works ("Commons") that the public can reliably and without fear of later under the following licence:
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation ========================================================================
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be Copyright (c) 2012 The Go Authors. All rights reserved.
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, Redistribution and use in source and binary forms, with or without
communicate, and translate a Work; modification, are permitted provided that the following conditions are
met:
ii. moral rights retained by the original author(s) and/or performer(s); * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
iii. publicity and privacy rights pertaining to a person's image or THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
likeness depicted in a Work; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
iv. rights protecting against unfair competition in regards to a Work, PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
subject to the limitations in paragraph 4(a), below; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
v. rights protecting the extraction, dissemination, use and reuse of data PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
in a Work; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
vi. database rights (such as those arising under Directive 96/9/EC of the NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
European Parliament and of the Council of 11 March 1996 on the legal SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations
thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied, statutory
or otherwise, including without limitation warranties of title,
merchantability, fitness for a particular purpose, non infringement, or
the absence of latent or other defects, accuracy, or the present or
absence of errors, whether or not discoverable, all to the greatest
extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the
Work. Further, Affirmer disclaims responsibility for obtaining any
necessary consents, permissions or other rights required for any use of
the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View file

@ -44,7 +44,7 @@ Extensive documentation is available [here](https://docs.rs/curve25519-dalek).
To install, add the following to the dependencies section of your project's To install, add the following to the dependencies section of your project's
`Cargo.toml`: `Cargo.toml`:
curve25519-dalek = "^0.9" curve25519-dalek = "^0.10"
Then, in your library or executable source, add: Then, in your library or executable source, add:
@ -56,7 +56,7 @@ fast.
## TODO ## TODO
We intend to stabilise the following before curve25519-dalek-1.0.0:
* Implement hashing to a point on the curve (Elligator). * Implement hashing to a point on the curve (Elligator).
* Make a new `mask` type in `subtle.rs` and return that instead of `u8`s. * Finish Ristretto (Decaf for curve25519) implementation.
* Implement all utilities in Golang's `crypto/subtle` package, and
move the module to its own crate.

View file

@ -90,11 +90,12 @@ use core::ops::Index;
use constants; use constants;
use field::FieldElement; use field::FieldElement;
use scalar::Scalar; use scalar::Scalar;
use subtle::arrays_equal;
use subtle::slices_equal;
use subtle::bytes_equal; use subtle::bytes_equal;
use subtle::CTAssignable; use subtle::ConditionallyAssignable;
use subtle::CTEq; use subtle::ConditionallyNegatable;
use subtle::CTNegatable; use subtle::Equal;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Compressed points // Compressed points
@ -486,7 +487,7 @@ impl ValidityCheck for ExtendedPoint {
// Constant-time assignment // Constant-time assignment
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl CTAssignable for ProjectiveNielsPoint { impl ConditionallyAssignable for ProjectiveNielsPoint {
fn conditional_assign(&mut self, other: &ProjectiveNielsPoint, choice: u8) { fn conditional_assign(&mut self, other: &ProjectiveNielsPoint, choice: u8) {
self.Y_plus_X.conditional_assign(&other.Y_plus_X, choice); self.Y_plus_X.conditional_assign(&other.Y_plus_X, choice);
self.Y_minus_X.conditional_assign(&other.Y_minus_X, choice); self.Y_minus_X.conditional_assign(&other.Y_minus_X, choice);
@ -495,7 +496,7 @@ impl CTAssignable for ProjectiveNielsPoint {
} }
} }
impl CTAssignable for AffineNielsPoint { impl ConditionallyAssignable for AffineNielsPoint {
fn conditional_assign(&mut self, other: &AffineNielsPoint, choice: u8) { fn conditional_assign(&mut self, other: &AffineNielsPoint, choice: u8) {
// PreComputedGroupElementCMove() // PreComputedGroupElementCMove()
self.y_plus_x.conditional_assign(&other.y_plus_x, choice); self.y_plus_x.conditional_assign(&other.y_plus_x, choice);
@ -504,7 +505,7 @@ impl CTAssignable for AffineNielsPoint {
} }
} }
impl CTAssignable for ExtendedPoint { impl ConditionallyAssignable for ExtendedPoint {
fn conditional_assign(&mut self, other: &ExtendedPoint, choice: u8) { fn conditional_assign(&mut self, other: &ExtendedPoint, choice: u8) {
self.X.conditional_assign(&other.X, choice); self.X.conditional_assign(&other.X, choice);
self.Y.conditional_assign(&other.Y, choice); self.Y.conditional_assign(&other.Y, choice);
@ -517,9 +518,9 @@ impl CTAssignable for ExtendedPoint {
// Constant-time Equality // Constant-time Equality
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl CTEq for ExtendedPoint { impl Equal for ExtendedPoint {
fn ct_eq(&self, other: &ExtendedPoint) -> u8 { fn ct_eq(&self, other: &ExtendedPoint) -> u8 {
arrays_equal(self.compress_edwards().as_bytes(), slices_equal(self.compress_edwards().as_bytes(),
other.compress_edwards().as_bytes()) other.compress_edwards().as_bytes())
} }
} }
@ -533,7 +534,7 @@ pub trait IsIdentity {
/// Implement generic identity equality testing for a point representations /// Implement generic identity equality testing for a point representations
/// which have constant-time equality testing and a defined identity /// which have constant-time equality testing and a defined identity
/// constructor. /// constructor.
impl<T> IsIdentity for T where T: CTEq + Identity { impl<T> IsIdentity for T where T: Equal + Identity {
fn is_identity(&self) -> bool { fn is_identity(&self) -> bool {
self.ct_eq(&T::identity()) == 1u8 self.ct_eq(&T::identity()) == 1u8
} }
@ -1156,7 +1157,7 @@ impl ExtendedPoint {
/// x ≤ 8`, compute `x * B` in constant time, i.e., without branching /// x ≤ 8`, compute `x * B` in constant time, i.e., without branching
/// on x or using it as an array index. /// on x or using it as an array index.
fn select_precomputed_point<T>(x: i8, points: &[T; 8]) -> T fn select_precomputed_point<T>(x: i8, points: &[T; 8]) -> T
where T: Identity + CTAssignable, for<'a> &'a T: Neg<Output=T> where T: Identity + ConditionallyAssignable, for<'a> &'a T: Neg<Output=T>
{ {
debug_assert!(x >= -8); debug_assert!(x <= 8); debug_assert!(x >= -8); debug_assert!(x <= 8);
@ -1371,7 +1372,7 @@ mod test {
use decaf::DecafPoint; use decaf::DecafPoint;
use field::FieldElement; use field::FieldElement;
use scalar::Scalar; use scalar::Scalar;
use subtle::CTAssignable; use subtle::ConditionallyAssignable;
use constants; use constants;
use super::*; use super::*;

View file

@ -32,8 +32,6 @@ use generic_array::typenum::U32;
use constants; use constants;
use field::FieldElement; use field::FieldElement;
use subtle::CTAssignable;
use subtle::CTNegatable;
use core::ops::{Add, Sub, Neg}; use core::ops::{Add, Sub, Neg};
use core::ops::{AddAssign, SubAssign}; use core::ops::{AddAssign, SubAssign};
@ -46,6 +44,9 @@ use curve::EdwardsBasepointTable;
use curve::Identity; use curve::Identity;
use scalar::Scalar; use scalar::Scalar;
use subtle::ConditionallyAssignable;
use subtle::ConditionallyNegatable;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Compressed points // Compressed points
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -58,6 +59,11 @@ pub struct CompressedDecaf(pub [u8; 32]);
/// The result of compressing a `DecafPoint`. /// The result of compressing a `DecafPoint`.
impl CompressedDecaf { impl CompressedDecaf {
/// Convert this `CompressedDecaf` to an array of bytes.
pub fn to_bytes(&self) -> [u8; 32] {
self.0
}
/// View this `CompressedDecaf` as an array of bytes. /// View this `CompressedDecaf` 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] {
&self.0 &self.0
@ -631,7 +637,7 @@ impl DecafBasepointTable {
// Constant-time conditional assignment // Constant-time conditional assignment
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl CTAssignable for DecafPoint { impl ConditionallyAssignable for DecafPoint {
/// Conditionally assign `other` to `self`, if `choice == 1u8`. /// Conditionally assign `other` to `self`, if `choice == 1u8`.
/// ///
/// # Example /// # Example
@ -640,7 +646,7 @@ impl CTAssignable for DecafPoint {
/// # extern crate subtle; /// # extern crate subtle;
/// # extern crate curve25519_dalek; /// # extern crate curve25519_dalek;
/// # /// #
/// # use subtle::CTAssignable; /// # use subtle::ConditionallyAssignable;
/// # /// #
/// # use curve25519_dalek::curve::Identity; /// # use curve25519_dalek::curve::Identity;
/// # use curve25519_dalek::decaf::DecafPoint; /// # use curve25519_dalek::decaf::DecafPoint;

View file

@ -22,10 +22,10 @@
use core::cmp::{Eq, PartialEq}; use core::cmp::{Eq, PartialEq};
use subtle::arrays_equal; use subtle::slices_equal;
use subtle::byte_is_nonzero; use subtle::byte_is_nonzero;
use subtle::CTAssignable; use subtle::ConditionallyAssignable;
use subtle::CTEq; use subtle::Equal;
use constants; use constants;
@ -62,7 +62,7 @@ impl PartialEq for FieldElement {
} }
} }
impl CTEq for FieldElement { impl Equal for FieldElement {
/// Test equality between two `FieldElement`s. Since the /// Test equality between two `FieldElement`s. Since the
/// internal representation is not canonical, the field elements /// internal representation is not canonical, the field elements
/// are normalized to wire format before comparison. /// are normalized to wire format before comparison.
@ -71,7 +71,7 @@ impl CTEq for FieldElement {
/// ///
/// `1u8` if the two `FieldElement`s are equal, and `0u8` otherwise. /// `1u8` if the two `FieldElement`s are equal, and `0u8` otherwise.
fn ct_eq(&self, other: &FieldElement) -> u8 { fn ct_eq(&self, other: &FieldElement) -> u8 {
arrays_equal(&self.to_bytes(), &other.to_bytes()) slices_equal(&self.to_bytes(), &other.to_bytes())
} }
} }
@ -323,7 +323,7 @@ impl FieldElement {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use field::*; use field::*;
use subtle::CTNegatable; use subtle::ConditionallyNegatable;
/// Random element a of GF(2^255-19), from Sage /// Random element a of GF(2^255-19), from Sage
/// a = 1070314506888354081329385823235218444233221\ /// a = 1070314506888354081329385823235218444233221\

View file

@ -30,7 +30,7 @@ use core::ops::{Sub, SubAssign};
use core::ops::{Mul, MulAssign}; use core::ops::{Mul, MulAssign};
use core::ops::Neg; use core::ops::Neg;
use subtle::CTAssignable; use subtle::ConditionallyAssignable;
use utils::{load3, load4}; use utils::{load3, load4};
@ -44,6 +44,19 @@ use utils::{load3, load4};
/// The coefficients t[i] are allowed to grow between multiplications. /// The coefficients t[i] are allowed to grow between multiplications.
/// ///
/// XXX document by how much /// XXX document by how much
///
/// # Warning
///
/// You almost certainly do not want to use `FieldElement32` directly. Consider
/// using `curve25519_dalek::field::FieldElement`, which will automatically
/// select between `FieldElement32` and `FieldElement64` depending on whether
/// curve25519-dalek was compiled with `--features="nightly"`.
///
/// This implementation, `FieldElement32`, is intended for platforms that can
/// multiply 32-bit inputs to produce 64-bit outputs, and is not preferred for
/// use on x86_64, since the 64-bit implementation is both much simpler and much
/// faster. However, the `FieldElement64` implementation requires Rust's
/// `u128`, which is not yet stable.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct FieldElement32(pub [i32; 10]); pub struct FieldElement32(pub [i32; 10]);
@ -189,7 +202,7 @@ impl<'a> Neg for &'a FieldElement32 {
} }
} }
impl CTAssignable for FieldElement32 { impl ConditionallyAssignable for FieldElement32 {
fn conditional_assign(&mut self, f: &FieldElement32, choice: u8) { fn conditional_assign(&mut self, f: &FieldElement32, choice: u8) {
let mask = -(choice as i32); let mask = -(choice as i32);
for i in 0..10 { for i in 0..10 {

View file

@ -25,7 +25,7 @@ use core::ops::{Sub, SubAssign};
use core::ops::{Mul, MulAssign}; use core::ops::{Mul, MulAssign};
use core::ops::Neg; use core::ops::Neg;
use subtle::CTAssignable; use subtle::ConditionallyAssignable;
use utils::load8; use utils::load8;
@ -38,6 +38,20 @@ pub type Limb = u64;
/// In the 64-bit implementation, a `FieldElement` is represented in /// In the 64-bit implementation, a `FieldElement` is represented in
/// radix 2^51 as five `u64`s; the coefficients are allowed to grow up /// radix 2^51 as five `u64`s; the coefficients are allowed to grow up
/// to 2^54 between reductions mod `p`. /// to 2^54 between reductions mod `p`.
///
/// # Warning
///
/// You almost certainly do not want to use `FieldElement64` directly. Consider
/// using `curve25519_dalek::field::FieldElement`, which will automatically
/// select between `FieldElement32` and `FieldElement64` depending on whether
/// curve25519-dalek was compiled with `--features="nightly"`.
///
/// This implementation, `FieldElement64`, is intended for x64_64 platforms,
/// which have the `MUL` instructions taking 64-bit inputs and producing 128-bit
/// outputs. On other platforms, this implementation is not recommended. On
/// Haswell and newer, the BMI2 instruction set provides `MULX` and friends,
/// which gives even better performance. This implementation requires Rust's
/// `u128`, which is not yet stable.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct FieldElement64(pub [u64; 5]); pub struct FieldElement64(pub [u64; 5]);
@ -166,7 +180,7 @@ impl<'a> Neg for &'a FieldElement64 {
} }
} }
impl CTAssignable for FieldElement64 { impl ConditionallyAssignable for FieldElement64 {
fn conditional_assign(&mut self, f: &FieldElement64, choice: u8) { fn conditional_assign(&mut self, f: &FieldElement64, choice: u8) {
let mask = (-(choice as i64)) as u64; let mask = (-(choice as i64)) as u64;
for i in 0..5 { for i in 0..5 {

View file

@ -45,9 +45,10 @@ use generic_array::typenum::U64;
use constants; use constants;
use utils::{load3, load4}; use utils::{load3, load4};
use subtle::CTAssignable;
use subtle::CTEq; use subtle::slices_equal;
use subtle::arrays_equal; use subtle::ConditionallyAssignable;
use subtle::Equal;
/// The `Scalar` struct represents an element in /l, where /// The `Scalar` struct represents an element in /l, where
/// ///
@ -76,18 +77,18 @@ impl PartialEq for Scalar {
/// ///
/// True if they are equal, and false otherwise. /// True if they are equal, and false otherwise.
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
arrays_equal(&self.0, &other.0) == 1u8 slices_equal(&self.0, &other.0) == 1u8
} }
} }
impl CTEq for Scalar { impl Equal for Scalar {
/// Test equality between two `Scalar`s in constant time. /// Test equality between two `Scalar`s in constant time.
/// ///
/// # Returns /// # Returns
/// ///
/// `1u8` if they are equal, and `0u8` otherwise. /// `1u8` if they are equal, and `0u8` otherwise.
fn ct_eq(&self, other: &Self) -> u8 { fn ct_eq(&self, other: &Self) -> u8 {
arrays_equal(&self.0, &other.0) slices_equal(&self.0, &other.0)
} }
} }
@ -154,14 +155,14 @@ impl<'a> Neg for &'a Scalar {
} }
} }
impl CTAssignable for Scalar { impl ConditionallyAssignable for Scalar {
/// Conditionally assign another Scalar to this one. /// Conditionally assign another Scalar to this one.
/// ///
/// ``` /// ```
/// # extern crate curve25519_dalek; /// # extern crate curve25519_dalek;
/// # extern crate subtle; /// # extern crate subtle;
/// # use curve25519_dalek::scalar::Scalar; /// # use curve25519_dalek::scalar::Scalar;
/// # use subtle::CTAssignable; /// # use subtle::ConditionallyAssignable;
/// # fn main() { /// # fn main() {
/// let a = Scalar([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /// let a = Scalar([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/// 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]); /// 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);