Move 32/64-bit code into submodules in a backend module.

See the doc comment in `backend/mod.rs` for motivation on naming.
This commit is contained in:
Henry de Valence 2017-11-16 16:07:55 -08:00
parent 6ce7a4ee2d
commit e196f8347c
14 changed files with 147 additions and 92 deletions

View file

@ -24,39 +24,26 @@ use std::path::Path;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
extern crate serde; extern crate serde;
#[path="src/field.rs"] // Public modules
mod field;
#[cfg(not(feature="radix_51"))]
#[path="src/field_32bit.rs"]
mod field_32bit;
#[cfg(feature="radix_51")]
#[path="src/field_64bit.rs"]
mod field_64bit;
#[path="src/scalar.rs"] #[path="src/scalar.rs"]
mod scalar; mod scalar;
#[cfg(not(feature="radix_51"))]
#[path="src/scalar_32bit.rs"]
mod scalar_32bit;
#[cfg(feature="radix_51")]
#[path="src/scalar_64bit.rs"]
mod scalar_64bit;
#[path="src/montgomery.rs"] #[path="src/montgomery.rs"]
mod montgomery; mod montgomery;
#[path="src/edwards.rs"] #[path="src/edwards.rs"]
mod edwards; mod edwards;
#[path="src/ristretto.rs"] #[path="src/ristretto.rs"]
mod ristretto; mod ristretto;
#[path="src/constants.rs"] #[path="src/constants.rs"]
mod constants; mod constants;
#[cfg(not(feature="radix_51"))]
#[path="src/constants_32bit.rs"] // Internal modules
mod constants_32bit;
#[cfg(feature="radix_51")] #[path="src/field.rs"]
#[path="src/constants_64bit.rs"] mod field;
mod constants_64bit;
#[path="src/backend/mod.rs"]
mod backend;
use edwards::EdwardsBasepointTable; use edwards::EdwardsBasepointTable;
@ -73,10 +60,10 @@ fn main() {
f.write_all(format!("\n f.write_all(format!("\n
#[cfg(feature=\"radix_51\")] #[cfg(feature=\"radix_51\")]
use field_64bit::FieldElement64; use backend::u64::field::FieldElement64;
#[cfg(not(feature=\"radix_51\"))] #[cfg(not(feature=\"radix_51\"))]
use field_32bit::FieldElement32; use backend::u32::field::FieldElement32;
use edwards::AffineNielsPoint; use edwards::AffineNielsPoint;
use edwards::EdwardsBasepointTable; use edwards::EdwardsBasepointTable;

32
src/backend/mod.rs Normal file
View file

@ -0,0 +1,32 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
//! This module contains "backends" that contain different
//! implementations of common code for different architectures.
//!
//! The naming of the `u32` and `u64` modules is somewhat unfortunate,
//! since these are also the names of primitive types. Since types have
//! a different namespace than modules, this isn't a problem to the
//! compiler, but it could cause confusion.
//!
//! However, it's unlikely that the names of those modules would be
//! brought into scope directly, instead of used as
//! `backend::u32::field` or similar. Unfortunately we can't use
//! `32bit` since identifiers can't start with letters, and the backends
//! do use `u32`/`u64`, so this seems like a least-bad option.
/// Code using `u32`s and a `(u32, u32) -> u64` multiplier.
#[cfg(not(feature="radix_51"))]
pub mod u32;
/// Code using `u64`s and a `(u64, u64) -> u128` multiplier.
#[cfg(feature="radix_51")]
pub mod u64;

View file

@ -12,8 +12,8 @@
//! and useful field elements like `sqrt(-1)`), as well as //! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points. //! lookup tables of pre-computed points.
use field_32bit::FieldElement32; use backend::u32::field::FieldElement32;
use scalar_32bit::Scalar32; use backend::u32::scalar::Scalar32;
use edwards::ExtendedPoint; use edwards::ExtendedPoint;
/// Edwards `d` value, equal to `-121665/121666 mod p`. /// Edwards `d` value, equal to `-121665/121666 mod p`.

15
src/backend/u32/mod.rs Normal file
View file

@ -0,0 +1,15 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
pub mod field;
pub mod scalar;
pub mod constants;

View file

@ -12,8 +12,8 @@
//! and useful field elements like `sqrt(-1)`), as well as //! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points. //! lookup tables of pre-computed points.
use field_64bit::FieldElement64; use backend::u64::field::FieldElement64;
use scalar_64bit::Scalar64; use backend::u64::scalar::Scalar64;
use edwards::ExtendedPoint; use edwards::ExtendedPoint;
/// Edwards `d` value, equal to `-121665/121666 mod p`. /// Edwards `d` value, equal to `-121665/121666 mod p`.

View file

@ -25,10 +25,6 @@ use core::ops::Neg;
use subtle::ConditionallyAssignable; use subtle::ConditionallyAssignable;
/// In the 64-bit implementation, field elements are represented in
/// radix 2^51 as five `u64`s.
pub type Limb = u64;
/// A `FieldElement64` represents an element of the field GF(2^255 - 19). /// A `FieldElement64` represents an element of the field GF(2^255 - 19).
/// ///
/// In the 64-bit implementation, a `FieldElement` is represented in /// In the 64-bit implementation, a `FieldElement` is represented in

15
src/backend/u64/mod.rs Normal file
View file

@ -0,0 +1,15 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
pub mod field;
pub mod scalar;
pub mod constants;

View file

@ -36,9 +36,9 @@ use montgomery::CompressedMontgomeryU;
use scalar::Scalar; use scalar::Scalar;
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
pub use constants_64bit::*; pub use backend::u64::constants::*;
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
pub use constants_32bit::*; pub use backend::u32::constants::*;
/// Basepoint has y = 4/5. /// Basepoint has y = 4/5.
/// ///
@ -138,7 +138,7 @@ mod test {
#[test] #[test]
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
fn sqrt_minus_aplus2() { fn sqrt_minus_aplus2() {
use field_64bit::FieldElement64; use backend::u64::field::FieldElement64;
let minus_aplus2 = -&FieldElement64([486664,0,0,0,0]); let minus_aplus2 = -&FieldElement64([486664,0,0,0,0]);
let sqrt = constants::SQRT_MINUS_APLUS2; let sqrt = constants::SQRT_MINUS_APLUS2;
let sq = &sqrt * &sqrt; let sq = &sqrt * &sqrt;
@ -150,7 +150,7 @@ mod test {
#[test] #[test]
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
fn sqrt_minus_aplus2() { fn sqrt_minus_aplus2() {
use field_32bit::FieldElement32; use backend::u32::field::FieldElement32;
let minus_aplus2 = -&FieldElement32([486664,0,0,0,0,0,0,0,0,0]); let minus_aplus2 = -&FieldElement32([486664,0,0,0,0,0,0,0,0,0]);
let sqrt = constants::SQRT_MINUS_APLUS2; let sqrt = constants::SQRT_MINUS_APLUS2;
let sq = &sqrt * &sqrt; let sq = &sqrt * &sqrt;
@ -180,7 +180,7 @@ mod test {
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
#[test] #[test]
fn test_d_vs_ratio() { fn test_d_vs_ratio() {
use field_32bit::FieldElement32; use backend::u32::field::FieldElement32;
let a = -&FieldElement32([121665,0,0,0,0,0,0,0,0,0]); let a = -&FieldElement32([121665,0,0,0,0,0,0,0,0,0]);
let b = FieldElement32([121666,0,0,0,0,0,0,0,0,0]); let b = FieldElement32([121666,0,0,0,0,0,0,0,0,0]);
let d = &a * &b.invert(); let d = &a * &b.invert();
@ -193,7 +193,7 @@ mod test {
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
#[test] #[test]
fn test_d_vs_ratio() { fn test_d_vs_ratio() {
use field_64bit::FieldElement64; use backend::u64::field::FieldElement64;
let a = -&FieldElement64([121665,0,0,0,0]); let a = -&FieldElement64([121665,0,0,0,0]);
let b = FieldElement64([121666,0,0,0,0]); let b = FieldElement64([121666,0,0,0,0]);
let d = &a * &b.invert(); let d = &a * &b.invert();

View file

@ -27,17 +27,19 @@ use subtle::ConditionallyNegatable;
use subtle::Equal; use subtle::Equal;
use constants; use constants;
use backend;
#[cfg(feature="radix_51")]
pub use backend::u64::field::*;
/// A `FieldElement` represents an element of the field GF(2^255 - 19). /// A `FieldElement` represents an element of the field GF(2^255 - 19).
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
pub type FieldElement = FieldElement64; pub type FieldElement = backend::u64::field::FieldElement64;
#[cfg(not(feature="radix_51"))]
pub use backend::u32::field::*;
/// A `FieldElement` represents an element of the field GF(2^255 - 19). /// A `FieldElement` represents an element of the field GF(2^255 - 19).
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
pub type FieldElement = FieldElement32; pub type FieldElement = backend::u32::field::FieldElement32;
#[cfg(feature="radix_51")]
pub use field_64bit::*;
#[cfg(not(feature="radix_51"))]
pub use field_32bit::*;
impl Eq for FieldElement {} impl Eq for FieldElement {}
impl PartialEq for FieldElement { impl PartialEq for FieldElement {

View file

@ -35,22 +35,9 @@
//! hatred of the Daleks. Rusty destroys the other Daleks and departs the //! hatred of the Daleks. Rusty destroys the other Daleks and departs the
//! ship, determined to track down and bring an end to the Dalek race. //! ship, determined to track down and bring an end to the Dalek race.
#[cfg(all(test, feature = "bench"))] //------------------------------------------------------------------------
extern crate test; // External dependencies:
//------------------------------------------------------------------------
// this appears to only be used for serde support right now?
#[cfg(feature = "serde")]
#[macro_use]
extern crate arrayref;
extern crate generic_array;
extern crate digest;
extern crate subtle;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(all(test, feature = "serde"))]
extern crate serde_cbor;
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate core; extern crate core;
@ -61,29 +48,51 @@ extern crate rand;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
extern crate alloc; extern crate alloc;
// Modules for low-level operations directly on field elements and curve points. #[cfg(all(test, feature = "bench"))]
extern crate test;
pub mod field; // The `Digest` trait is implemented using `generic_array`, so we need it too. Hopefully we can eliminate `generic_array` from `Digest` once const generics land.
#[cfg(not(feature="radix_51"))] extern crate digest;
mod field_32bit; extern crate generic_array;
#[cfg(feature="radix_51")]
mod field_64bit;
// Used for traits related to constant-time code.
extern crate subtle;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(all(test, feature = "serde"))]
extern crate serde_cbor;
// this appears to only be used for serde support right now?
// XXX let's eliminate this dep
#[cfg(feature = "serde")]
#[macro_use]
extern crate arrayref;
//------------------------------------------------------------------------
// curve25519-dalek public modules
//------------------------------------------------------------------------
// Scalar arithmetic mod l = 2^252 + ..., the order of the Ristretto group
pub mod scalar; pub mod scalar;
#[cfg(not(feature="radix_51"))] // Point operations on the Montgomery form of Curve25519
mod scalar_32bit;
#[cfg(feature="radix_51")]
mod scalar_64bit;
pub mod edwards;
pub mod montgomery; pub mod montgomery;
// Point operations on the Edwards form of Curve25519
pub mod edwards;
// Group operations on the Ristretto group
pub mod ristretto; pub mod ristretto;
// Useful constants, like the Ed25519 basepoint
// Low-level curve and point constants, as well as pre-computed curve group elements.
pub mod constants; pub mod constants;
#[cfg(not(feature="radix_51"))]
mod constants_32bit; //------------------------------------------------------------------------
#[cfg(feature="radix_51")] // curve25519-dalek internal modules
mod constants_64bit; //------------------------------------------------------------------------
// Finite field arithmetic mod p = 2^255 - 19
pub(crate) mod field;
// Arithmetic backends (using u32, u64, etc) live here
pub(crate) mod backend;
// Internal curve models which are not part of the public API.
//mod curve_models;

View file

@ -46,6 +46,17 @@ use subtle::slices_equal;
use subtle::ConditionallyAssignable; use subtle::ConditionallyAssignable;
use subtle::Equal; use subtle::Equal;
use backend;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
#[cfg(feature="radix_51")]
type UnpackedScalar = backend::u64::scalar::Scalar64;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
#[cfg(not(feature="radix_51"))]
type UnpackedScalar = backend::u32::scalar::Scalar32;
/// The `Scalar` struct represents an element in /l, where /// The `Scalar` struct represents an element in /l, where
/// ///
/// l = 2^252 + 27742317777372353535851937790883648493 /// l = 2^252 + 27742317777372353535851937790883648493
@ -227,18 +238,6 @@ impl<'de> Deserialize<'de> for Scalar {
} }
} }
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
#[cfg(feature="radix_51")]
type UnpackedScalar = Scalar64;
#[cfg(feature="radix_51")]
use scalar_64bit::*;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
#[cfg(not(feature="radix_51"))]
type UnpackedScalar = Scalar32;
#[cfg(not(feature="radix_51"))]
use scalar_32bit::*;
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.
/// ///