Merge pull request #342 from huitseeker/fiat4_with_u32

Serial backends w/formally-verified field arithmetic for 32 & 64 bits
This commit is contained in:
isis agora lovecruft 2021-04-13 23:23:41 +00:00 committed by GitHub
commit cecc821f40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 623 additions and 7 deletions

View file

@ -9,6 +9,10 @@ env:
- TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std u32_backend'
# Tests the u64 backend
- TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std u64_backend'
# Tests the fiat_u32 backend
- TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std fiat_u32_backend'
# Tests the fiat_u64 backend
- TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std fiat_u64_backend'
# Tests the simd backend
- TEST_COMMAND=test EXTRA_FLAGS='--no-default-features' FEATURES='std simd_backend'
# Tests serde support and default feature selection

View file

@ -50,6 +50,7 @@ serde = { version = "1.0", default-features = false, optional = true, features =
# https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161
packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"], optional = true }
zeroize = { version = "1", default-features = false }
fiat-crypto = { version = "0.1.6", optional = true}
[features]
nightly = ["subtle/nightly"]
@ -61,6 +62,10 @@ alloc = ["zeroize/alloc"]
u32_backend = []
# The u64 backend uses u64s with u128 products.
u64_backend = []
# fiat-u64 backend (with formally-verified field arith) uses u64s with u128 products.
fiat_u64_backend = ["fiat-crypto"]
# fiat-u32 backend (with formally-verified field arith) uses u32s with u64 products.
fiat_u32_backend = ["fiat-crypto"]
# The SIMD backend uses parallel formulas, using either AVX2 or AVX512-IFMA.
simd_backend = ["nightly", "u64_backend", "packed_simd"]
# DEPRECATED: this is now an alias for `simd_backend` and may be removed

View file

@ -37,11 +37,13 @@
#[cfg(not(any(
feature = "u32_backend",
feature = "u64_backend",
feature = "fiat_u32_backend",
feature = "fiat_u64_backend",
feature = "simd_backend",
)))]
compile_error!(
"no curve25519-dalek backend cargo feature enabled! \
please enable one of: u32_backend, u64_backend, simd_backend"
please enable one of: u32_backend, u64_backend, fiat_u32_backend, fiat_u64_backend, simd_backend"
);
pub mod serial;

View file

@ -0,0 +1,260 @@
// -*- mode: rust; coding: utf-8; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
//! Field arithmetic modulo \\(p = 2\^{255} - 19\\), using \\(32\\)-bit
//! limbs with \\(64\\)-bit products.
//!
//! This code was originally derived from Adam Langley's Golang ed25519
//! implementation, and was then rewritten to use unsigned limbs instead
//! of signed limbs.
//!
//! This uses the formally-verified field arithmetic generated by the
//! [fiat-crypto project](https://github.com/mit-plv/fiat-crypto)
use core::fmt::Debug;
use core::ops::Neg;
use core::ops::{Add, AddAssign};
use core::ops::{Mul, MulAssign};
use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
use zeroize::Zeroize;
use fiat_crypto::curve25519_32::*;
/// A `FieldElement2625` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
///
/// In the 32-bit implementation, a `FieldElement` is represented in
/// radix \\(2\^{25.5}\\) as ten `u32`s. This means that a field
/// 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\\).
///
/// # Note
///
/// The `curve25519_dalek::field` module provides a type alias
/// `curve25519_dalek::field::FieldElement` to either `FieldElement51`
/// or `FieldElement2625`.
///
/// The backend-specific type `FieldElement2625` should not be used
/// outside of the `curve25519_dalek::field` module.
#[derive(Copy, Clone)]
pub struct FieldElement2625(pub(crate) [u32; 10]);
impl Debug for FieldElement2625 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "FieldElement2625({:?})", &self.0[..])
}
}
impl Zeroize for FieldElement2625 {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl<'b> AddAssign<&'b FieldElement2625> for FieldElement2625 {
fn add_assign(&mut self, _rhs: &'b FieldElement2625) {
let input = self.0;
fiat_25519_add(&mut self.0, &input, &_rhs.0);
let input = self.0;
fiat_25519_carry(&mut self.0, &input);
}
}
impl<'a, 'b> Add<&'b FieldElement2625> for &'a FieldElement2625 {
type Output = FieldElement2625;
fn add(self, _rhs: &'b FieldElement2625) -> FieldElement2625 {
let mut output = *self;
fiat_25519_add(&mut output.0, &self.0, &_rhs.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl<'b> SubAssign<&'b FieldElement2625> for FieldElement2625 {
fn sub_assign(&mut self, _rhs: &'b FieldElement2625) {
let input = self.0;
fiat_25519_sub(&mut self.0, &input, &_rhs.0);
let input = self.0;
fiat_25519_carry(&mut self.0, &input);
}
}
impl<'a, 'b> Sub<&'b FieldElement2625> for &'a FieldElement2625 {
type Output = FieldElement2625;
fn sub(self, _rhs: &'b FieldElement2625) -> FieldElement2625 {
let mut output = *self;
fiat_25519_sub(&mut output.0, &self.0, &_rhs.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl<'b> MulAssign<&'b FieldElement2625> for FieldElement2625 {
fn mul_assign(&mut self, _rhs: &'b FieldElement2625) {
let input = self.0;
fiat_25519_carry_mul(&mut self.0, &input, &_rhs.0);
}
}
impl<'a, 'b> Mul<&'b FieldElement2625> for &'a FieldElement2625 {
type Output = FieldElement2625;
fn mul(self, _rhs: &'b FieldElement2625) -> FieldElement2625 {
let mut output = *self;
fiat_25519_carry_mul(&mut output.0, &self.0, &_rhs.0);
output
}
}
impl<'a> Neg for &'a FieldElement2625 {
type Output = FieldElement2625;
fn neg(self) -> FieldElement2625 {
let mut output = *self;
fiat_25519_opp(&mut output.0, &self.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl ConditionallySelectable for FieldElement2625 {
fn conditional_select(
a: &FieldElement2625,
b: &FieldElement2625,
choice: Choice,
) -> FieldElement2625 {
let mut output = [0u32; 10];
fiat_25519_selectznz(&mut output, choice.unwrap_u8() as fiat_25519_u1, &a.0, &b.0);
FieldElement2625(output)
}
fn conditional_assign(&mut self, other: &FieldElement2625, choice: Choice) {
let mut output = [0u32; 10];
let choicebit = choice.unwrap_u8() as fiat_25519_u1;
fiat_25519_cmovznz_u32(&mut output[0], choicebit, self.0[0], other.0[0]);
fiat_25519_cmovznz_u32(&mut output[1], choicebit, self.0[1], other.0[1]);
fiat_25519_cmovznz_u32(&mut output[2], choicebit, self.0[2], other.0[2]);
fiat_25519_cmovznz_u32(&mut output[3], choicebit, self.0[3], other.0[3]);
fiat_25519_cmovznz_u32(&mut output[4], choicebit, self.0[4], other.0[4]);
fiat_25519_cmovznz_u32(&mut output[5], choicebit, self.0[5], other.0[5]);
fiat_25519_cmovznz_u32(&mut output[6], choicebit, self.0[6], other.0[6]);
fiat_25519_cmovznz_u32(&mut output[7], choicebit, self.0[7], other.0[7]);
fiat_25519_cmovznz_u32(&mut output[8], choicebit, self.0[8], other.0[8]);
fiat_25519_cmovznz_u32(&mut output[9], choicebit, self.0[9], other.0[9]);
*self = FieldElement2625(output);
}
fn conditional_swap(a: &mut FieldElement2625, b: &mut FieldElement2625, choice: Choice) {
u32::conditional_swap(&mut a.0[0], &mut b.0[0], choice);
u32::conditional_swap(&mut a.0[1], &mut b.0[1], choice);
u32::conditional_swap(&mut a.0[2], &mut b.0[2], choice);
u32::conditional_swap(&mut a.0[3], &mut b.0[3], choice);
u32::conditional_swap(&mut a.0[4], &mut b.0[4], choice);
u32::conditional_swap(&mut a.0[5], &mut b.0[5], choice);
u32::conditional_swap(&mut a.0[6], &mut b.0[6], choice);
u32::conditional_swap(&mut a.0[7], &mut b.0[7], choice);
u32::conditional_swap(&mut a.0[8], &mut b.0[8], choice);
u32::conditional_swap(&mut a.0[9], &mut b.0[9], choice);
}
}
impl FieldElement2625 {
/// Invert the sign of this field element
pub fn negate(&mut self) {
let neg = self.neg();
self.0 = neg.0;
}
/// Construct zero.
pub fn zero() -> FieldElement2625 {
FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement2625 {
FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement2625 {
FieldElement2625([
0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff,
0x3ffffff, 0x1ffffff,
])
}
/// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, k: u32) -> FieldElement2625 {
debug_assert!(k > 0);
let mut z = self.square();
for _ in 1..k {
z = z.square();
}
z
}
/// Load a `FieldElement2625` from the low 255 bits of a 256-bit
/// input.
///
/// # Warning
///
/// This function does not check that the input used the canonical
/// representative. It masks the high bit, but it will happily
/// decode 2^255 - 18 to 1. Applications that require a canonical
/// encoding of every field element should decode, re-encode to
/// the canonical encoding, and check that the input was
/// canonical.
pub fn from_bytes(data: &[u8; 32]) -> FieldElement2625 {
let mut temp = [0u8; 32];
temp.copy_from_slice(data);
temp[31] &= 127u8;
let mut output = [0u32; 10];
fiat_25519_from_bytes(&mut output, &temp);
FieldElement2625(output)
}
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
pub fn to_bytes(&self) -> [u8; 32] {
let mut bytes = [0u8; 32];
fiat_25519_to_bytes(&mut bytes, &self.0);
return bytes;
}
/// Compute `self^2`.
pub fn square(&self) -> FieldElement2625 {
let mut output = *self;
fiat_25519_carry_square(&mut output.0, &self.0);
output
}
/// Compute `2*self^2`.
pub fn square2(&self) -> FieldElement2625 {
let mut output = *self;
let mut temp = *self;
// Void vs return type, measure cost of copying self
fiat_25519_carry_square(&mut temp.0, &self.0);
fiat_25519_add(&mut output.0, &temp.0, &temp.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}

View file

@ -0,0 +1,26 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - 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.
//!
//! This uses the formally-verified field arithmetic generated by the
//! [fiat-crypto project](https://github.com/mit-plv/fiat-crypto)
#[path = "../u32/scalar.rs"]
pub mod scalar;
pub mod field;
#[path = "../u32/constants.rs"]
pub mod constants;

View file

@ -0,0 +1,249 @@
// -*- mode: rust; coding: utf-8; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
//! Field arithmetic modulo \\(p = 2\^{255} - 19\\), using \\(64\\)-bit
//! limbs with \\(128\\)-bit products.
//!
//! This uses the formally-verified field arithmetic generated by the
//! [fiat-crypto project](https://github.com/mit-plv/fiat-crypto)
use core::fmt::Debug;
use core::ops::Neg;
use core::ops::{Add, AddAssign};
use core::ops::{Mul, MulAssign};
use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
use zeroize::Zeroize;
use fiat_crypto::curve25519_64::*;
/// A `FieldElement51` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
///
/// In the 64-bit implementation, a `FieldElement` is represented in
/// radix \\(2\^{51}\\) as five `u64`s; the coefficients are allowed to
/// grow up to \\(2\^{54}\\) between reductions modulo \\(p\\).
///
/// # Note
///
/// The `curve25519_dalek::field` module provides a type alias
/// `curve25519_dalek::field::FieldElement` to either `FieldElement51`
/// or `FieldElement2625`.
///
/// The backend-specific type `FieldElement51` should not be used
/// outside of the `curve25519_dalek::field` module.
#[derive(Copy, Clone)]
pub struct FieldElement51(pub(crate) [u64; 5]);
impl Debug for FieldElement51 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "FieldElement51({:?})", &self.0[..])
}
}
impl Zeroize for FieldElement51 {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl<'b> AddAssign<&'b FieldElement51> for FieldElement51 {
fn add_assign(&mut self, _rhs: &'b FieldElement51) {
let input = self.0;
fiat_25519_add(&mut self.0, &input, &_rhs.0);
let input = self.0;
fiat_25519_carry(&mut self.0, &input);
}
}
impl<'a, 'b> Add<&'b FieldElement51> for &'a FieldElement51 {
type Output = FieldElement51;
fn add(self, _rhs: &'b FieldElement51) -> FieldElement51 {
let mut output = *self;
fiat_25519_add(&mut output.0, &self.0, &_rhs.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl<'b> SubAssign<&'b FieldElement51> for FieldElement51 {
fn sub_assign(&mut self, _rhs: &'b FieldElement51) {
let input = self.0;
fiat_25519_sub(&mut self.0, &input, &_rhs.0);
let input = self.0;
fiat_25519_carry(&mut self.0, &input);
}
}
impl<'a, 'b> Sub<&'b FieldElement51> for &'a FieldElement51 {
type Output = FieldElement51;
fn sub(self, _rhs: &'b FieldElement51) -> FieldElement51 {
let mut output = *self;
fiat_25519_sub(&mut output.0, &self.0, &_rhs.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl<'b> MulAssign<&'b FieldElement51> for FieldElement51 {
fn mul_assign(&mut self, _rhs: &'b FieldElement51) {
let input = self.0;
fiat_25519_carry_mul(&mut self.0, &input, &_rhs.0);
}
}
impl<'a, 'b> Mul<&'b FieldElement51> for &'a FieldElement51 {
type Output = FieldElement51;
fn mul(self, _rhs: &'b FieldElement51) -> FieldElement51 {
let mut output = *self;
fiat_25519_carry_mul(&mut output.0, &self.0, &_rhs.0);
output
}
}
impl<'a> Neg for &'a FieldElement51 {
type Output = FieldElement51;
fn neg(self) -> FieldElement51 {
let mut output = *self;
fiat_25519_opp(&mut output.0, &self.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}
impl ConditionallySelectable for FieldElement51 {
fn conditional_select(
a: &FieldElement51,
b: &FieldElement51,
choice: Choice,
) -> FieldElement51 {
let mut output = [0u64; 5];
fiat_25519_selectznz(&mut output, choice.unwrap_u8() as fiat_25519_u1, &a.0, &b.0);
FieldElement51(output)
}
fn conditional_swap(a: &mut FieldElement51, b: &mut FieldElement51, choice: Choice) {
u64::conditional_swap(&mut a.0[0], &mut b.0[0], choice);
u64::conditional_swap(&mut a.0[1], &mut b.0[1], choice);
u64::conditional_swap(&mut a.0[2], &mut b.0[2], choice);
u64::conditional_swap(&mut a.0[3], &mut b.0[3], choice);
u64::conditional_swap(&mut a.0[4], &mut b.0[4], choice);
}
fn conditional_assign(&mut self, _rhs: &FieldElement51, choice: Choice) {
let mut output = [0u64; 5];
let choicebit = choice.unwrap_u8() as fiat_25519_u1;
fiat_25519_cmovznz_u64(&mut output[0], choicebit, self.0[0], _rhs.0[0]);
fiat_25519_cmovznz_u64(&mut output[1], choicebit, self.0[1], _rhs.0[1]);
fiat_25519_cmovznz_u64(&mut output[2], choicebit, self.0[2], _rhs.0[2]);
fiat_25519_cmovznz_u64(&mut output[3], choicebit, self.0[3], _rhs.0[3]);
fiat_25519_cmovznz_u64(&mut output[4], choicebit, self.0[4], _rhs.0[4]);
*self = FieldElement51(output);
}
}
impl FieldElement51 {
/// Construct zero.
pub fn zero() -> FieldElement51 {
FieldElement51([0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement51 {
FieldElement51([1, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement51 {
FieldElement51([
2251799813685228,
2251799813685247,
2251799813685247,
2251799813685247,
2251799813685247,
])
}
/// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon).
#[inline(always)]
#[allow(dead_code)] // Need this to not complain about reduce not being used
fn reduce(mut limbs: [u64; 5]) -> FieldElement51 {
let input = limbs;
fiat_25519_carry(&mut limbs, &input);
FieldElement51(limbs)
}
/// Load a `FieldElement51` from the low 255 bits of a 256-bit
/// input.
///
/// # Warning
///
/// This function does not check that the input used the canonical
/// representative. It masks the high bit, but it will happily
/// decode 2^255 - 18 to 1. Applications that require a canonical
/// encoding of every field element should decode, re-encode to
/// the canonical encoding, and check that the input was
/// canonical.
///
pub fn from_bytes(bytes: &[u8; 32]) -> FieldElement51 {
let mut temp = [0u8; 32];
temp.copy_from_slice(bytes);
temp[31] &= 127u8;
let mut output = [0u64; 5];
fiat_25519_from_bytes(&mut output, &temp);
FieldElement51(output)
}
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
pub fn to_bytes(&self) -> [u8; 32] {
let mut bytes = [0u8; 32];
fiat_25519_to_bytes(&mut bytes, &self.0);
return bytes;
}
/// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, mut k: u32) -> FieldElement51 {
let mut output = *self;
loop {
let input = output.0;
fiat_25519_carry_square(&mut output.0, &input);
k -= 1;
if k == 0 {
return output;
}
}
}
/// Returns the square of this field element.
pub fn square(&self) -> FieldElement51 {
let mut output = *self;
fiat_25519_carry_square(&mut output.0, &self.0);
output
}
/// Returns 2 times the square of this field element.
pub fn square2(&self) -> FieldElement51 {
let mut output = *self;
let mut temp = *self;
// Void vs return type, measure cost of copying self
fiat_25519_carry_square(&mut temp.0, &self.0);
fiat_25519_add(&mut output.0, &temp.0, &temp.0);
let input = output.0;
fiat_25519_carry(&mut output.0, &input);
output
}
}

View file

@ -0,0 +1,28 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - 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.
#[path = "../u64/scalar.rs"]
pub mod scalar;
pub mod field;
#[path = "../u64/constants.rs"]
pub mod constants;

View file

@ -23,10 +23,15 @@
//! Note: at this time the `u32` and `u64` backends cannot be built
//! together.
#[cfg(not(any(feature = "u32_backend", feature = "u64_backend")))]
#[cfg(not(any(
feature = "u32_backend",
feature = "u64_backend",
feature = "fiat_u32_backend",
feature = "fiat_u64_backend"
)))]
compile_error!(
"no curve25519-dalek backend cargo feature enabled! \
please enable one of: u32_backend, u64_backend"
please enable one of: u32_backend, u64_backend, fiat_u32_backend, fiat_u64_backend"
);
#[cfg(feature = "u32_backend")]
@ -35,6 +40,12 @@ pub mod u32;
#[cfg(feature = "u64_backend")]
pub mod u64;
#[cfg(feature = "fiat_u32_backend")]
pub mod fiat_u32;
#[cfg(feature = "fiat_u64_backend")]
pub mod fiat_u64;
pub mod curve_models;
#[cfg(not(all(

View file

@ -14,8 +14,8 @@
//! lookup tables of pre-computed points.
use backend::serial::curve_models::AffineNielsPoint;
use backend::serial::u32::field::FieldElement2625;
use backend::serial::u32::scalar::Scalar29;
use super::field::FieldElement2625;
use super::scalar::Scalar29;
use edwards::{EdwardsBasepointTable, EdwardsPoint};
use window::{LookupTable, NafLookupTable8};

View file

@ -12,8 +12,8 @@
//! This module contains backend-specific constant values, such as the 64-bit limbs of curve constants.
use backend::serial::curve_models::AffineNielsPoint;
use backend::serial::u64::field::FieldElement51;
use backend::serial::u64::scalar::Scalar52;
use super::field::FieldElement51;
use super::scalar::Scalar52;
use edwards::{EdwardsBasepointTable, EdwardsPoint};
use window::{LookupTable, NafLookupTable8};

View file

@ -34,6 +34,10 @@ use ristretto::CompressedRistretto;
use montgomery::MontgomeryPoint;
use scalar::Scalar;
#[cfg(feature = "fiat_u32_backend")]
pub use backend::serial::fiat_u32::constants::*;
#[cfg(feature = "fiat_u64_backend")]
pub use backend::serial::fiat_u64::constants::*;
#[cfg(feature = "u64_backend")]
pub use backend::serial::u64::constants::*;
#[cfg(feature = "u32_backend")]

View file

@ -33,6 +33,21 @@ use subtle::ConstantTimeEq;
use constants;
use backend;
#[cfg(feature = "fiat_u32_backend")]
pub use backend::serial::fiat_u32::field::*;
#[cfg(feature = "fiat_u64_backend")]
pub use backend::serial::fiat_u64::field::*;
/// 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.
/// Using formally-verified field arithmetic from fiat-crypto
#[cfg(feature = "fiat_u32_backend")]
pub type FieldElement = backend::serial::fiat_u32::field::FieldElement2625;
#[cfg(feature = "fiat_u64_backend")]
pub type FieldElement = backend::serial::fiat_u64::field::FieldElement51;
#[cfg(feature = "u64_backend")]
pub use backend::serial::u64::field::*;
/// A `FieldElement` represents an element of the field

View file

@ -47,6 +47,9 @@ pub extern crate digest;
extern crate rand_core;
extern crate zeroize;
#[cfg(any(feature = "fiat_u64_backend", feature = "fiat_u32_backend"))]
extern crate fiat_crypto;
// Used for traits related to constant-time code.
extern crate subtle;

View file

@ -166,6 +166,15 @@ use zeroize::Zeroize;
use backend;
use constants;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
///
/// This is a type alias for one of the scalar types in the `backend`
/// module.
#[cfg(feature = "fiat_u32_backend")]
type UnpackedScalar = backend::serial::fiat_u32::scalar::Scalar29;
#[cfg(feature = "fiat_u64_backend")]
type UnpackedScalar = backend::serial::fiat_u64::scalar::Scalar52;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
///
/// This is a type alias for one of the scalar types in the `backend`