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")]
extern crate serde;
#[path="src/field.rs"]
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;
// Public modules
#[path="src/scalar.rs"]
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"]
mod montgomery;
#[path="src/edwards.rs"]
mod edwards;
#[path="src/ristretto.rs"]
mod ristretto;
#[path="src/constants.rs"]
mod constants;
#[cfg(not(feature="radix_51"))]
#[path="src/constants_32bit.rs"]
mod constants_32bit;
#[cfg(feature="radix_51")]
#[path="src/constants_64bit.rs"]
mod constants_64bit;
// Internal modules
#[path="src/field.rs"]
mod field;
#[path="src/backend/mod.rs"]
mod backend;
use edwards::EdwardsBasepointTable;
@ -73,10 +60,10 @@ fn main() {
f.write_all(format!("\n
#[cfg(feature=\"radix_51\")]
use field_64bit::FieldElement64;
use backend::u64::field::FieldElement64;
#[cfg(not(feature=\"radix_51\"))]
use field_32bit::FieldElement32;
use backend::u32::field::FieldElement32;
use edwards::AffineNielsPoint;
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
//! lookup tables of pre-computed points.
use field_32bit::FieldElement32;
use scalar_32bit::Scalar32;
use backend::u32::field::FieldElement32;
use backend::u32::scalar::Scalar32;
use edwards::ExtendedPoint;
/// 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
//! lookup tables of pre-computed points.
use field_64bit::FieldElement64;
use scalar_64bit::Scalar64;
use backend::u64::field::FieldElement64;
use backend::u64::scalar::Scalar64;
use edwards::ExtendedPoint;
/// Edwards `d` value, equal to `-121665/121666 mod p`.

View file

@ -25,10 +25,6 @@ use core::ops::Neg;
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).
///
/// 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;
#[cfg(feature="radix_51")]
pub use constants_64bit::*;
pub use backend::u64::constants::*;
#[cfg(not(feature="radix_51"))]
pub use constants_32bit::*;
pub use backend::u32::constants::*;
/// Basepoint has y = 4/5.
///
@ -138,7 +138,7 @@ mod test {
#[test]
#[cfg(feature="radix_51")]
fn sqrt_minus_aplus2() {
use field_64bit::FieldElement64;
use backend::u64::field::FieldElement64;
let minus_aplus2 = -&FieldElement64([486664,0,0,0,0]);
let sqrt = constants::SQRT_MINUS_APLUS2;
let sq = &sqrt * &sqrt;
@ -150,7 +150,7 @@ mod test {
#[test]
#[cfg(not(feature="radix_51"))]
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 sqrt = constants::SQRT_MINUS_APLUS2;
let sq = &sqrt * &sqrt;
@ -180,7 +180,7 @@ mod test {
#[cfg(not(feature="radix_51"))]
#[test]
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 b = FieldElement32([121666,0,0,0,0,0,0,0,0,0]);
let d = &a * &b.invert();
@ -193,7 +193,7 @@ mod test {
#[cfg(feature="radix_51")]
#[test]
fn test_d_vs_ratio() {
use field_64bit::FieldElement64;
use backend::u64::field::FieldElement64;
let a = -&FieldElement64([121665,0,0,0,0]);
let b = FieldElement64([121666,0,0,0,0]);
let d = &a * &b.invert();

View file

@ -27,17 +27,19 @@ use subtle::ConditionallyNegatable;
use subtle::Equal;
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).
#[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).
#[cfg(not(feature="radix_51"))]
pub type FieldElement = FieldElement32;
#[cfg(feature="radix_51")]
pub use field_64bit::*;
#[cfg(not(feature="radix_51"))]
pub use field_32bit::*;
pub type FieldElement = backend::u32::field::FieldElement32;
impl Eq for FieldElement {}
impl PartialEq for FieldElement {

View file

@ -35,22 +35,9 @@
//! 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.
#[cfg(all(test, feature = "bench"))]
extern crate test;
// 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;
//------------------------------------------------------------------------
// External dependencies:
//------------------------------------------------------------------------
#[cfg(feature = "std")]
extern crate core;
@ -61,29 +48,51 @@ extern crate rand;
#[cfg(feature = "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;
#[cfg(not(feature="radix_51"))]
mod field_32bit;
#[cfg(feature="radix_51")]
mod field_64bit;
// 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.
extern crate digest;
extern crate generic_array;
// 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;
#[cfg(not(feature="radix_51"))]
mod scalar_32bit;
#[cfg(feature="radix_51")]
mod scalar_64bit;
pub mod edwards;
// Point operations on the Montgomery form of Curve25519
pub mod montgomery;
// Point operations on the Edwards form of Curve25519
pub mod edwards;
// Group operations on the Ristretto group
pub mod ristretto;
// Low-level curve and point constants, as well as pre-computed curve group elements.
// Useful constants, like the Ed25519 basepoint
pub mod constants;
#[cfg(not(feature="radix_51"))]
mod constants_32bit;
#[cfg(feature="radix_51")]
mod constants_64bit;
//------------------------------------------------------------------------
// curve25519-dalek internal modules
//------------------------------------------------------------------------
// 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::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
///
/// 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 {
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
///