diff --git a/build.rs b/build.rs index ee90958..fe4b1fe 100644 --- a/build.rs +++ b/build.rs @@ -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; diff --git a/src/backend/mod.rs b/src/backend/mod.rs new file mode 100644 index 0000000..3947fb9 --- /dev/null +++ b/src/backend/mod.rs @@ -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 +// - Henry de Valence + +//! 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; + diff --git a/src/constants_32bit.rs b/src/backend/u32/constants.rs similarity index 98% rename from src/constants_32bit.rs rename to src/backend/u32/constants.rs index 740abc5..2600c64 100644 --- a/src/constants_32bit.rs +++ b/src/backend/u32/constants.rs @@ -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`. diff --git a/src/field_32bit.rs b/src/backend/u32/field.rs similarity index 100% rename from src/field_32bit.rs rename to src/backend/u32/field.rs diff --git a/src/backend/u32/mod.rs b/src/backend/u32/mod.rs new file mode 100644 index 0000000..fa54a15 --- /dev/null +++ b/src/backend/u32/mod.rs @@ -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 +// - Henry de Valence + +pub mod field; + +pub mod scalar; + +pub mod constants; \ No newline at end of file diff --git a/src/scalar_32bit.rs b/src/backend/u32/scalar.rs similarity index 100% rename from src/scalar_32bit.rs rename to src/backend/u32/scalar.rs diff --git a/src/constants_64bit.rs b/src/backend/u64/constants.rs similarity index 98% rename from src/constants_64bit.rs rename to src/backend/u64/constants.rs index c9d6b4a..3af570c 100644 --- a/src/constants_64bit.rs +++ b/src/backend/u64/constants.rs @@ -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`. diff --git a/src/field_64bit.rs b/src/backend/u64/field.rs similarity index 99% rename from src/field_64bit.rs rename to src/backend/u64/field.rs index 807bba8..3c6d4f0 100644 --- a/src/field_64bit.rs +++ b/src/backend/u64/field.rs @@ -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 diff --git a/src/backend/u64/mod.rs b/src/backend/u64/mod.rs new file mode 100644 index 0000000..fa54a15 --- /dev/null +++ b/src/backend/u64/mod.rs @@ -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 +// - Henry de Valence + +pub mod field; + +pub mod scalar; + +pub mod constants; \ No newline at end of file diff --git a/src/scalar_64bit.rs b/src/backend/u64/scalar.rs similarity index 100% rename from src/scalar_64bit.rs rename to src/backend/u64/scalar.rs diff --git a/src/constants.rs b/src/constants.rs index 6434f89..3ba6ce4 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -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(); diff --git a/src/field.rs b/src/field.rs index 9464fa3..86f9aad 100644 --- a/src/field.rs +++ b/src/field.rs @@ -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 { diff --git a/src/lib.rs b/src/lib.rs index 38593c4..1834835 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; \ No newline at end of file diff --git a/src/scalar.rs b/src/scalar.rs index c793cc3..e5fa102 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -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. ///