KaTeXify some backend documentation

This commit is contained in:
Henry de Valence 2017-12-01 11:46:36 -08:00
parent 58cf210882
commit c0633ae2d7
8 changed files with 92 additions and 80 deletions

View file

@ -22,11 +22,9 @@
//! `32bit` since identifiers can't start with letters, and the backends //! `32bit` since identifiers can't start with letters, and the backends
//! do use `u32`/`u64`, so this seems like a least-bad option. //! 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"))] #[cfg(not(feature="radix_51"))]
pub mod u32; pub mod u32;
/// Code using `u64`s and a `(u64, u64) -> u128` multiplier.
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
pub mod u64; pub mod u64;

View file

@ -8,19 +8,12 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! Field arithmetic for /(2²⁵⁵-19), using 32-bit arithmetic with //! Field arithmetic modulo \\(p = 2\^{255} - 19\\), using \\(32\\)-bit
//! 64-bit products. //! limbs with \\(64\\)-bit products.
//! //!
//! This code was originally derived from Adam Langley's //! This code was originally derived from Adam Langley's Golang ed25519
//! curve25519-donna and (Golang) ed25519 implementations. //! implementation, and was then rewritten to use unsigned limbs instead
//! //! of signed limbs.
//! This implementation is intended for platforms that can multiply
//! 32-bit inputs to produce 64-bit outputs.
//!
//! This implementation is not preferred for use on x86_64, since the
//! 64-bit implementation is both much simpler and much faster.
//! However, that implementation requires Rust's `u128`, which is not
//! yet stable.
use core::fmt::Debug; use core::fmt::Debug;
use core::ops::{Add, AddAssign}; use core::ops::{Add, AddAssign};
@ -30,28 +23,28 @@ use core::ops::Neg;
use subtle::ConditionallyAssignable; use subtle::ConditionallyAssignable;
/// A `FieldElement32` represents an element of the field GF(2^255 - 19). /// A `FieldElement32` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
/// ///
/// In the 32-bit implementation, a `FieldElement32` is represented in /// In the 32-bit implementation, a `FieldElement` is represented in
/// radix 2^25.5 as ten `u32`s, so that an element t, entries /// radix \\(2\^{25.5}\\) as ten `u32`s. This means that a field
/// t[0],...,t[9], represents `sum(t[i]*2^ceil(i*51/2))`. /// element \\(x\\) is represented as
/// $$
/// x = \sum\_{i=0}\^9 x\_i 2\^{\lceil i \frac {51} 2 \rceil}
/// = x\_0 + x\_1 2\^{26} + x\_2 2\^{51} + x\_3 2\^{77} + \cdots + x\_9 2\^{230};
/// $$
/// the coefficients are alternately bounded by \\(2\^{25}\\) and
/// \\(2\^{26}\\). The limbs are allowed to grow between reductions up
/// to \\(2\^{25+b}\\) or \\(2\^{26+b}\\), where \\(b = 1.75\\).
/// ///
/// The coefficients t[i] are allowed to grow between multiplications. /// # Note
/// ///
/// XXX document by how much /// The `curve25519_dalek::field` module provides a type alias
/// /// `curve25519_dalek::field::FieldElement` to either `FieldElement64`
/// # Warning /// or `FieldElement32`.
/// ///
/// You almost certainly do not want to use `FieldElement32` directly. Consider /// The backend-specific type `FieldElement32` should not be used
/// using `curve25519_dalek::field::FieldElement`, which will automatically /// outside of the `curve25519_dalek::field` module.
/// 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 (crate) [u32; 10]); pub struct FieldElement32(pub (crate) [u32; 10]);

View file

@ -8,8 +8,14 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! The `u32` backend uses `u32`s and a `(u32, u32) -> u64` multiplier.
//!
//! This code is intended to be portable, but it requires that
//! multiplication of two \\(32\\)-bit values to a \\(64\\)-bit result
//! is constant-time on the target platform.
pub mod field; pub mod field;
pub mod scalar; pub mod scalar;
pub mod constants; pub mod constants;

View file

@ -8,9 +8,7 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! This module contains various constants (such as curve parameters //! This module contains backend-specific constant values, such as the 64-bit limbs of curve constants.
//! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points.
use backend::u64::field::FieldElement64; use backend::u64::field::FieldElement64;
use backend::u64::scalar::Scalar64; use backend::u64::scalar::Scalar64;

View file

@ -8,14 +8,8 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! Field arithmetic for /(2²⁵⁵-19), using 64-bit arithmetic wuth //! Field arithmetic modulo \\(p = 2\^{255} - 19\\), using \\(64\\)-bit
//! 128-bit products. //! limbs with \\(128\\)-bit products.
//!
//! On x86_64, the multiplications lower to `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.
use core::fmt::Debug; use core::fmt::Debug;
use core::ops::{Add, AddAssign}; use core::ops::{Add, AddAssign};
@ -25,25 +19,21 @@ use core::ops::Neg;
use subtle::ConditionallyAssignable; use subtle::ConditionallyAssignable;
/// A `FieldElement64` represents an element of the field GF(2^255 - 19). /// A `FieldElement64` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
/// ///
/// 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
/// to 2^54 between reductions mod `p`. /// grow up to \\(2\^{54}\\) between reductions modulo \\(p\\).
/// ///
/// # Warning /// # Note
/// ///
/// You almost certainly do not want to use `FieldElement64` directly. Consider /// The `curve25519_dalek::field` module provides a type alias
/// using `curve25519_dalek::field::FieldElement`, which will automatically /// `curve25519_dalek::field::FieldElement` to either `FieldElement64`
/// select between `FieldElement32` and `FieldElement64` depending on whether /// or `FieldElement32`.
/// curve25519-dalek was compiled with `--features="nightly"`. ///
/// /// The backend-specific type `FieldElement64` should not be used
/// This implementation, `FieldElement64`, is intended for x64_64 platforms, /// outside of the `curve25519_dalek::field` module.
/// 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 (crate) [u64; 5]); pub struct FieldElement64(pub (crate) [u64; 5]);

View file

@ -8,8 +8,19 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! The `u64` backend uses `u64`s and a `(u64, u64) -> u128` multiplier.
//!
//! On x86_64, the idiom `(x as u128) * (y as u128)` lowers to `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 extension provides `MULX`, and on
//! Broadwell and newer, the ADX extension provides `ADCX` and `ADOX`
//! (allowing the CPU to compute two carry chains in parallel). These
//! will be used if available.
pub mod field; pub mod field;
pub mod scalar; pub mod scalar;
pub mod constants; pub mod constants;

View file

@ -1,19 +1,23 @@
//! Arithmetic mod 2^252 + 27742317777372353535851937790883648493 //! Arithmetic mod \\(2\^{252} + 27742317777372353535851937790883648493\\)
//! with 5 52-bit unsigned limbs. 51-bit limbs would cover the //! with five \\(52\\)-bit unsigned limbs.
//! desired bit range (253 bits), but isn't large enough to reduce
//! a 512 bit number with Montgomery multiplication, so 52 bits is
//! used instead
//! //!
//! To see that this is safe for intermediate results, note that //! \\(51\\)-bit limbs would cover the desired bit range (\\(253\\)
//! the largest limb in a 5 by 5 product of 52-bit limbs will be //! bits), but isn't large enough to reduce a \\(512\\)-bit number with
//! Montgomery multiplication, so \\(52\\) bits is used instead. To see
//! that this is safe for intermediate results, note that the largest
//! limb in a \\(5\times 5\\) product of \\(52\\)-bit limbs will be
//!
//! ```text
//! (0xfffffffffffff^2) * 5 = 0x4ffffffffffff60000000000005 (107 bits). //! (0xfffffffffffff^2) * 5 = 0x4ffffffffffff60000000000005 (107 bits).
//! ```
use core::fmt::Debug; use core::fmt::Debug;
use core::ops::{Index, IndexMut}; use core::ops::{Index, IndexMut};
use constants; use constants;
/// The `Scalar64` struct represents an element in /l as 5 52-bit limbs /// The `Scalar64` struct represents an element in
/// \\(\mathbb Z / \ell \mathbb Z\\) as 5 \\(52\\)-bit limbs.
#[derive(Copy,Clone)] #[derive(Copy,Clone)]
pub struct Scalar64(pub [u64; 5]); pub struct Scalar64(pub [u64; 5]);

View file

@ -8,15 +8,19 @@
// - Isis Agora Lovecruft <isis@patternsinthevoid.net> // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
//! Field arithmetic for /(2²⁵⁵-19). //! Field arithmetic modulo \\(p = 2\^{255} - 19\\).
//! //!
//! Partially based on Adam Langley's curve25519-donna and (Golang) //! The `curve25519_dalek::field` module provides a type alias
//! ed25519 implementations, with other techniques inspired by Mike //! `curve25519_dalek::field::FieldElement` to a field element type
//! Hamburg's code. //! defined in the `backend` module; either `FieldElement64` or
//! `FieldElement32`.
//! //!
//! This module re-exports either the 32-bit or 64-bit implementation, //! Field operations defined in terms of machine
//! and implements functions that are generic with respect to the //! operations, such as field multiplication or squaring, are defined in
//! basic operations, such as inverses and square roots. //! the backend implementation.
//!
//! Field operations defined in terms of other field operations, such as
//! field inversion or square roots, are defined here.
use core::cmp::{Eq, PartialEq}; use core::cmp::{Eq, PartialEq};
@ -31,13 +35,21 @@ use backend;
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
pub use backend::u64::field::*; 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
/// \\( \mathbb Z / (2\^{255} - 19)\\).
///
/// The `FieldElement` type is an alias for one of the platform-specific
/// implementations.
#[cfg(feature="radix_51")] #[cfg(feature="radix_51")]
pub type FieldElement = backend::u64::field::FieldElement64; pub type FieldElement = backend::u64::field::FieldElement64;
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
pub use backend::u32::field::*; 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
/// \\( \mathbb Z / (2\^{255} - 19)\\).
///
/// The `FieldElement` type is an alias for one of the platform-specific
/// implementations.
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
pub type FieldElement = backend::u32::field::FieldElement32; pub type FieldElement = backend::u32::field::FieldElement32;