Merge branch 'main' into v4.1.1

This commit is contained in:
bunnie 2024-03-25 06:59:43 +08:00 committed by GitHub
commit b486cda2a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 156 additions and 136 deletions

View file

@ -5,6 +5,10 @@ major series.
## 4.x series
### 4.1.2
* Fix nightly SIMD build
### 4.1.1
* Mark `constants::BASEPOINT_ORDER` deprecated from pub API
@ -123,7 +127,7 @@ major series.
### 2.1.2
* Multiple documenation typo fixes.
* Multiple documentation typo fixes.
* Fix `alloc` feature working with stable rust.
### 2.1.1

View file

@ -4,7 +4,7 @@ name = "curve25519-dalek"
# - update CHANGELOG
# - update README if required by semver
# - if README was updated, also update module documentation in src/lib.rs
version = "4.1.1"
version = "4.1.2"
edition = "2021"
rust-version = "1.60.0"
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>",
@ -38,7 +38,6 @@ rand = "0.8"
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }
[build-dependencies]
platforms = "3.0.2"
rustc_version = "0.4.0"
[[bench]]

View file

@ -25,15 +25,12 @@ fn main() {
let curve25519_dalek_bits = match std::env::var("CARGO_CFG_CURVE25519_DALEK_BITS").as_deref() {
Ok("32") => DalekBits::Dalek32,
Ok("64") => DalekBits::Dalek64,
_ => deterministic::determine_curve25519_dalek_bits(),
_ => deterministic::determine_curve25519_dalek_bits(&target_arch),
};
build_debug!("CARGO_CFG_CURVE25519_DALEK_BITS: {:?}", std::env::var("CARGO_CFG_CURVE25519_DALEK_BITS").as_deref());
build_debug!("curve25519_dalek_bits {:?}", curve25519_dalek_bits);
match curve25519_dalek_bits {
DalekBits::Dalek64 => println!("cargo:rustc-cfg=curve25519_dalek_bits=\"64\""),
DalekBits::Dalek32 => println!("cargo:rustc-cfg=curve25519_dalek_bits=\"32\""),
}
println!("cargo:rustc-cfg=curve25519_dalek_bits=\"{curve25519_dalek_bits}\"");
if rustc_version::version_meta()
.expect("failed to detect rustc version")
@ -105,11 +102,12 @@ mod deterministic {
use super::*;
// Standard Cargo TARGET environment variable of triplet is required
static ERR_MSG_NO_TARGET: &str = "Standard Cargo TARGET environment variable is not set";
// Custom Rust non-cargo build tooling needs to set CARGO_CFG_TARGET_POINTER_WIDTH
static ERR_MSG_NO_POINTER_WIDTH: &str =
"Standard Cargo TARGET_POINTER_WIDTH environment variable is not set.";
// Custom Non-Rust standard target platforms require explicit settings.
static ERR_MSG_NO_PLATFORM: &str = "Unknown Rust target platform.";
// When either non-32 or 64 TARGET_POINTER_WIDTH detected
static ERR_MSG_UNKNOWN_POINTER_WIDTH: &str = "Unknown TARGET_POINTER_WIDTH detected.";
// Warning when the curve25519_dalek_bits cannot be determined
fn determine_curve25519_dalek_bits_warning(cause: &str) {
@ -117,41 +115,30 @@ mod deterministic {
}
// Determine the curve25519_dalek_bits based on Rust standard TARGET triplet
pub(super) fn determine_curve25519_dalek_bits() -> DalekBits {
use platforms::target::PointerWidth;
// TARGET environment is supplied by Cargo
// https://doc.rust-lang.org/cargo/reference/environment-variables.html
let target_triplet = match std::env::var("TARGET") {
Ok(t) => t,
pub(super) fn determine_curve25519_dalek_bits(target_arch: &String) -> DalekBits {
let target_pointer_width = match std::env::var("CARGO_CFG_TARGET_POINTER_WIDTH") {
Ok(pw) => pw,
Err(_) => {
determine_curve25519_dalek_bits_warning(ERR_MSG_NO_TARGET);
return DalekBits::Dalek32;
}
};
// platforms crate is the source of truth used to determine the platform
let platform = match platforms::Platform::find(&target_triplet) {
Some(p) => p,
None => {
determine_curve25519_dalek_bits_warning(ERR_MSG_NO_PLATFORM);
determine_curve25519_dalek_bits_warning(ERR_MSG_NO_POINTER_WIDTH);
return DalekBits::Dalek32;
}
};
#[allow(clippy::match_single_binding)]
match platform.target_arch {
match &target_arch {
//Issues: 449 and 456
//TODO: When adding arch defaults use proper types not String match
//TODO(Arm): Needs tests + benchmarks to back this up
//platforms::target::Arch::Arm => DalekBits::Dalek64,
//TODO(Wasm32): Needs tests + benchmarks to back this up
//platforms::target::Arch::Wasm32 => DalekBits::Dalek64,
_ => match platform.target_pointer_width {
PointerWidth::U64 => DalekBits::Dalek64,
PointerWidth::U32 => DalekBits::Dalek32,
_ => match target_pointer_width.as_ref() {
"64" => DalekBits::Dalek64,
"32" => DalekBits::Dalek32,
// Intended default solely for non-32/64 target pointer widths
// Otherwise known target platforms only.
_ => DalekBits::Dalek32,
_ => {
determine_curve25519_dalek_bits_warning(ERR_MSG_UNKNOWN_POINTER_WIDTH);
DalekBits::Dalek32
}
},
}
}

View file

@ -351,7 +351,7 @@ This computation requires 25 `vpmadd52luq` and 25 `vpmadd52huq`
operations. For 256-bit vectors, IFMA operations execute on an
i3-8121U with latency 4 cycles, throughput 0.5 cycles, so executing 50
instructions requires 25 cycles' worth of throughput. Accumulating
terms with coefficient \\(1\\) and \\(2\\) seperately means that the
terms with coefficient \\(1\\) and \\(2\\) separately means that the
longest dependency chain has length 5, so the critical path has length
20 cycles and the bottleneck is throughput.

View file

@ -87,24 +87,24 @@ where
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 =>
self::vector::scalar_mul::pippenger::spec_avx2::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
vector::scalar_mul::pippenger::spec_avx2::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 =>
self::vector::scalar_mul::pippenger::spec_avx512ifma_avx512vl::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
vector::scalar_mul::pippenger::spec_avx512ifma_avx512vl::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
BackendKind::Serial =>
self::serial::scalar_mul::pippenger::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
serial::scalar_mul::pippenger::Pippenger::optional_multiscalar_mul::<I, J>(scalars, points),
}
}
#[cfg(feature = "alloc")]
pub(crate) enum VartimePrecomputedStraus {
#[cfg(curve25519_dalek_backend = "simd")]
Avx2(self::vector::scalar_mul::precomputed_straus::spec_avx2::VartimePrecomputedStraus),
Avx2(vector::scalar_mul::precomputed_straus::spec_avx2::VartimePrecomputedStraus),
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
Avx512ifma(
self::vector::scalar_mul::precomputed_straus::spec_avx512ifma_avx512vl::VartimePrecomputedStraus,
vector::scalar_mul::precomputed_straus::spec_avx512ifma_avx512vl::VartimePrecomputedStraus,
),
Scalar(self::serial::scalar_mul::precomputed_straus::VartimePrecomputedStraus),
Scalar(serial::scalar_mul::precomputed_straus::VartimePrecomputedStraus),
}
#[cfg(feature = "alloc")]
@ -119,12 +119,12 @@ impl VartimePrecomputedStraus {
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 =>
VartimePrecomputedStraus::Avx2(self::vector::scalar_mul::precomputed_straus::spec_avx2::VartimePrecomputedStraus::new(static_points)),
VartimePrecomputedStraus::Avx2(vector::scalar_mul::precomputed_straus::spec_avx2::VartimePrecomputedStraus::new(static_points)),
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 =>
VartimePrecomputedStraus::Avx512ifma(self::vector::scalar_mul::precomputed_straus::spec_avx512ifma_avx512vl::VartimePrecomputedStraus::new(static_points)),
VartimePrecomputedStraus::Avx512ifma(vector::scalar_mul::precomputed_straus::spec_avx512ifma_avx512vl::VartimePrecomputedStraus::new(static_points)),
BackendKind::Serial =>
VartimePrecomputedStraus::Scalar(self::serial::scalar_mul::precomputed_straus::VartimePrecomputedStraus::new(static_points))
VartimePrecomputedStraus::Scalar(serial::scalar_mul::precomputed_straus::VartimePrecomputedStraus::new(static_points))
}
}
@ -179,19 +179,16 @@ where
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 => {
self::vector::scalar_mul::straus::spec_avx2::Straus::multiscalar_mul::<I, J>(
scalars, points,
)
vector::scalar_mul::straus::spec_avx2::Straus::multiscalar_mul::<I, J>(scalars, points)
}
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 => {
self::vector::scalar_mul::straus::spec_avx512ifma_avx512vl::Straus::multiscalar_mul::<
I,
J,
>(scalars, points)
vector::scalar_mul::straus::spec_avx512ifma_avx512vl::Straus::multiscalar_mul::<I, J>(
scalars, points,
)
}
BackendKind::Serial => {
self::serial::scalar_mul::straus::Straus::multiscalar_mul::<I, J>(scalars, points)
serial::scalar_mul::straus::Straus::multiscalar_mul::<I, J>(scalars, points)
}
}
}
@ -209,21 +206,19 @@ where
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 => {
self::vector::scalar_mul::straus::spec_avx2::Straus::optional_multiscalar_mul::<I, J>(
vector::scalar_mul::straus::spec_avx2::Straus::optional_multiscalar_mul::<I, J>(
scalars, points,
)
}
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 => {
self::vector::scalar_mul::straus::spec_avx512ifma_avx512vl::Straus::optional_multiscalar_mul::<
vector::scalar_mul::straus::spec_avx512ifma_avx512vl::Straus::optional_multiscalar_mul::<
I,
J,
>(scalars, points)
}
BackendKind::Serial => {
self::serial::scalar_mul::straus::Straus::optional_multiscalar_mul::<I, J>(
scalars, points,
)
serial::scalar_mul::straus::Straus::optional_multiscalar_mul::<I, J>(scalars, points)
}
}
}
@ -232,12 +227,12 @@ where
pub fn variable_base_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 => self::vector::scalar_mul::variable_base::spec_avx2::mul(point, scalar),
BackendKind::Avx2 => vector::scalar_mul::variable_base::spec_avx2::mul(point, scalar),
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 => {
self::vector::scalar_mul::variable_base::spec_avx512ifma_avx512vl::mul(point, scalar)
vector::scalar_mul::variable_base::spec_avx512ifma_avx512vl::mul(point, scalar)
}
BackendKind::Serial => self::serial::scalar_mul::variable_base::mul(point, scalar),
BackendKind::Serial => serial::scalar_mul::variable_base::mul(point, scalar),
}
}
@ -246,11 +241,11 @@ pub fn variable_base_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint
pub fn vartime_double_base_mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
match get_selected_backend() {
#[cfg(curve25519_dalek_backend = "simd")]
BackendKind::Avx2 => self::vector::scalar_mul::vartime_double_base::spec_avx2::mul(a, A, b),
BackendKind::Avx2 => vector::scalar_mul::vartime_double_base::spec_avx2::mul(a, A, b),
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
BackendKind::Avx512 => {
self::vector::scalar_mul::vartime_double_base::spec_avx512ifma_avx512vl::mul(a, A, b)
vector::scalar_mul::vartime_double_base::spec_avx512ifma_avx512vl::mul(a, A, b)
}
BackendKind::Serial => self::serial::scalar_mul::vartime_double_base::mul(a, A, b),
BackendKind::Serial => serial::scalar_mul::vartime_double_base::mul(a, A, b),
}
}

View file

@ -527,7 +527,7 @@ impl<'a> Neg for &'a AffineNielsPoint {
// ------------------------------------------------------------------------
impl Debug for ProjectivePoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"ProjectivePoint{{\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?}\n}}",
@ -537,7 +537,7 @@ impl Debug for ProjectivePoint {
}
impl Debug for CompletedPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"CompletedPoint{{\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?},\n\tT: {:?}\n}}",
@ -547,7 +547,7 @@ impl Debug for CompletedPoint {
}
impl Debug for AffineNielsPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"AffineNielsPoint{{\n\ty_plus_x: {:?},\n\ty_minus_x: {:?},\n\txy2d: {:?}\n}}",
@ -557,7 +557,7 @@ impl Debug for AffineNielsPoint {
}
impl Debug for ProjectiveNielsPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "ProjectiveNielsPoint{{\n\tY_plus_X: {:?},\n\tY_minus_X: {:?},\n\tZ: {:?},\n\tT2d: {:?}\n}}",
&self.Y_plus_X, &self.Y_minus_X, &self.Z, &self.T2d)
}

View file

@ -58,7 +58,7 @@ use fiat_crypto::curve25519_32::*;
pub struct FieldElement2625(pub(crate) fiat_25519_tight_field_element);
impl Debug for FieldElement2625 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "FieldElement2625({:?})", &(self.0).0[..])
}
}

View file

@ -47,7 +47,7 @@ use fiat_crypto::curve25519_64::*;
pub struct FieldElement51(pub(crate) fiat_25519_tight_field_element);
impl Debug for FieldElement51 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "FieldElement51({:?})", &(self.0).0[..])
}
}

View file

@ -164,7 +164,6 @@ impl VartimeMultiscalarMul for Pippenger {
mod test {
use super::*;
use crate::constants;
use crate::scalar::Scalar;
#[test]
fn test_vartime_pippenger() {

View file

@ -54,7 +54,7 @@ use zeroize::Zeroize;
pub struct FieldElement2625(pub(crate) [u32; 10]);
impl Debug for FieldElement2625 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "FieldElement2625({:?})", &self.0[..])
}
}

View file

@ -24,7 +24,7 @@ use crate::constants;
pub struct Scalar29(pub [u32; 9]);
impl Debug for Scalar29 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Scalar29: {:?}", &self.0[..])
}
}

View file

@ -43,7 +43,7 @@ use zeroize::Zeroize;
pub struct FieldElement51(pub(crate) [u64; 5]);
impl Debug for FieldElement51 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "FieldElement51({:?})", &self.0[..])
}
}

View file

@ -25,7 +25,7 @@ use crate::constants;
pub struct Scalar52(pub [u64; 5]);
impl Debug for Scalar52 {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Scalar52: {:?}", &self.0[..])
}
}

View file

@ -35,7 +35,6 @@
#![allow(non_snake_case)]
use core::convert::From;
use core::ops::{Add, Neg, Sub};
use subtle::Choice;

View file

@ -96,7 +96,6 @@
use core::array::TryFromSliceError;
use core::borrow::Borrow;
use core::fmt::Debug;
use core::iter::Iterator;
use core::iter::Sum;
use core::ops::{Add, Neg, Sub};
use core::ops::{AddAssign, SubAssign};
@ -110,10 +109,12 @@ use digest::{generic_array::typenum::U64, Digest};
#[cfg(feature = "group")]
use {
group::{cofactor::CofactorGroup, prime::PrimeGroup, GroupEncoding},
rand_core::RngCore,
subtle::CtOption,
};
#[cfg(feature = "group")]
use rand_core::RngCore;
use subtle::Choice;
use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
@ -170,7 +171,7 @@ impl ConstantTimeEq for CompressedEdwardsY {
}
impl Debug for CompressedEdwardsY {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "CompressedEdwardsY: {:?}", self.as_bytes())
}
}
@ -258,7 +259,7 @@ impl TryFrom<&[u8]> for CompressedEdwardsY {
#[cfg(feature = "serde")]
use serde::de::Visitor;
#[cfg(feature = "serde")]
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
impl Serialize for EdwardsPoint {
@ -301,7 +302,7 @@ impl<'de> Deserialize<'de> for EdwardsPoint {
impl<'de> Visitor<'de> for EdwardsPointVisitor {
type Value = EdwardsPoint;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("a valid point in Edwards y + sign format")
}
@ -337,7 +338,7 @@ impl<'de> Deserialize<'de> for CompressedEdwardsY {
impl<'de> Visitor<'de> for CompressedEdwardsYVisitor {
type Value = CompressedEdwardsY;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("32 bytes of data")
}
@ -1052,7 +1053,7 @@ macro_rules! impl_basepoint_table {
}
impl Debug for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}([\n", stringify!($name))?;
for i in 0..32 {
write!(f, "\t{:?},\n", &self.0[i])?;
@ -1263,7 +1264,7 @@ impl EdwardsPoint {
// ------------------------------------------------------------------------
impl Debug for EdwardsPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"EdwardsPoint{{\n\tX: {:?},\n\tY: {:?},\n\tZ: {:?},\n\tT: {:?}\n}}",
@ -1591,8 +1592,10 @@ impl CofactorGroup for EdwardsPoint {
#[cfg(test)]
mod test {
use super::*;
use crate::{field::FieldElement, scalar::Scalar};
use subtle::ConditionallySelectable;
// If `group` is set, then this is already imported in super
#[cfg(not(feature = "group"))]
use rand_core::RngCore;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
@ -1600,8 +1603,6 @@ mod test {
#[cfg(feature = "precomputed-tables")]
use crate::constants::ED25519_BASEPOINT_TABLE;
use rand_core::RngCore;
/// X coordinate of the basepoint.
/// = 15112221349535400772501151409588531511454012693041857206046113283949847762202
static BASE_X_COORD_BYTES: [u8; 32] = [

View file

@ -25,8 +25,6 @@
#[allow(unused_qualifications)]
use core::cmp::{Eq, PartialEq};
use cfg_if::cfg_if;
use subtle::Choice;
@ -322,7 +320,6 @@ extern crate rand;
#[cfg(test)]
mod test {
use crate::field::*;
use subtle::ConditionallyNegatable;
/// Random element a of GF(2^255-19), from Sage
/// a = 1070314506888354081329385823235218444233221\

View file

@ -10,7 +10,14 @@
// - Henry de Valence <hdevalence@hdevalence.ca>
#![no_std]
#![cfg_attr(all(curve25519_dalek_backend = "simd", nightly), feature(stdsimd))]
#![cfg_attr(
all(
curve25519_dalek_backend = "simd",
nightly,
any(target_arch = "x86", target_arch = "x86_64")
),
feature(stdarch_x86_avx512)
)]
#![cfg_attr(
all(curve25519_dalek_backend = "simd", nightly),
feature(avx512_target_feature)

View file

@ -364,7 +364,7 @@ impl TryFrom<&[u8]> for CompressedRistretto {
#[cfg(feature = "serde")]
use serde::de::Visitor;
#[cfg(feature = "serde")]
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
impl Serialize for RistrettoPoint {
@ -407,7 +407,7 @@ impl<'de> Deserialize<'de> for RistrettoPoint {
impl<'de> Visitor<'de> for RistrettoPointVisitor {
type Value = RistrettoPoint;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("a valid point in Ristretto format")
}
@ -443,7 +443,7 @@ impl<'de> Deserialize<'de> for CompressedRistretto {
impl<'de> Visitor<'de> for CompressedRistrettoVisitor {
type Value = CompressedRistretto;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("32 bytes of data")
}
@ -1155,13 +1155,13 @@ impl ConditionallySelectable for RistrettoPoint {
// ------------------------------------------------------------------------
impl Debug for CompressedRistretto {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "CompressedRistretto: {:?}", self.as_bytes())
}
}
impl Debug for RistrettoPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let coset = self.coset4();
write!(
f,
@ -1277,8 +1277,6 @@ impl Zeroize for RistrettoPoint {
mod test {
use super::*;
use crate::edwards::CompressedEdwardsY;
use crate::scalar::Scalar;
use crate::traits::Identity;
use rand_core::OsRng;

View file

@ -112,8 +112,6 @@
//! has been enabled.
use core::borrow::Borrow;
use core::cmp::{Eq, PartialEq};
use core::convert::TryInto;
use core::fmt::Debug;
use core::iter::{Product, Sum};
use core::ops::Index;
@ -124,13 +122,13 @@ use core::ops::{Sub, SubAssign};
use cfg_if::cfg_if;
#[cfg(feature = "group")]
use group::ff::{Field, FromUniformBytes, PrimeField};
#[cfg(feature = "group-bits")]
use group::ff::{FieldBits, PrimeFieldBits};
#[cfg(feature = "group")]
use {
group::ff::{Field, FromUniformBytes, PrimeField},
rand_core::RngCore,
};
#[cfg(any(test, feature = "group"))]
use rand_core::RngCore;
#[cfg(any(test, feature = "rand_core"))]
use rand_core::CryptoRngCore;
@ -294,7 +292,7 @@ impl Scalar {
}
impl Debug for Scalar {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Scalar{{\n\tbytes: {:?},\n}}", &self.bytes)
}
}
@ -409,7 +407,7 @@ impl ConditionallySelectable for Scalar {
#[cfg(feature = "serde")]
use serde::de::Visitor;
#[cfg(feature = "serde")]
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
@ -439,7 +437,7 @@ impl<'de> Deserialize<'de> for Scalar {
impl<'de> Visitor<'de> for ScalarVisitor {
type Value = Scalar;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str(
"a sequence of 32 bytes whose little-endian interpretation is less than the \
basepoint order ",
@ -840,7 +838,7 @@ impl Scalar {
}
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut scratch);
Zeroize::zeroize(&mut scratch);
ret
}
@ -1401,13 +1399,10 @@ pub const fn clamp_integer(mut bytes: [u8; 32]) -> [u8; 32] {
#[cfg(test)]
pub(crate) mod test {
use super::*;
use crate::constants;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use rand::RngCore;
/// x = 2238329342913194256032495932344128051776374960164957527413114840482143558222
pub static X: Scalar = Scalar {
bytes: [

View file

@ -15,9 +15,8 @@
use core::borrow::Borrow;
use subtle;
use crate::scalar::{clamp_integer, Scalar};
use subtle::ConstantTimeEq;
// ------------------------------------------------------------------------
// Public Traits
@ -41,7 +40,7 @@ pub trait IsIdentity {
/// constructor.
impl<T> IsIdentity for T
where
T: subtle::ConstantTimeEq + Identity,
T: ConstantTimeEq + Identity,
{
fn is_identity(&self) -> bool {
self.ct_eq(&T::identity()).into()
@ -409,6 +408,7 @@ pub trait VartimePrecomputedMultiscalarMul: Sized {
/// This trait is only for debugging/testing, since it should be
/// impossible for a `curve25519-dalek` user to construct an invalid
/// point.
#[allow(dead_code)]
pub(crate) trait ValidityCheck {
/// Checks whether the point is on the curve. Not CT.
fn is_valid(&self) -> bool;

View file

@ -83,7 +83,7 @@ macro_rules! impl_lookup_table {
}
impl<T: Debug> Debug for $name<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}(", stringify!($name))?;
for x in self.0.iter() {
@ -193,7 +193,7 @@ impl<T: Copy> NafLookupTable5<T> {
}
impl<T: Debug> Debug for NafLookupTable5<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "NafLookupTable5({:?})", self.0)
}
}
@ -240,7 +240,7 @@ impl<T: Copy> NafLookupTable8<T> {
#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
impl<T: Debug> Debug for NafLookupTable8<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "NafLookupTable8([")?;
for i in 0..64 {
writeln!(f, "\t{:?},", &self.0[i])?;

View file

@ -10,6 +10,10 @@ Entries are listed in reverse chronological order per undeprecated major series.
# 2.x series
## 2.1.1
* Fix nightly SIMD build
## 2.1.0
* Add `SigningKey::to_scalar_bytes` for getting the unclamped scalar from a signing key

View file

@ -1,6 +1,6 @@
[package]
name = "ed25519-dalek"
version = "2.1.0"
version = "2.1.1"
edition = "2021"
authors = [
"isis lovecruft <isis@patternsinthevoid.net>",

View file

@ -31,7 +31,7 @@ This crate is `#[no_std]` compatible with `default-features = false`.
# Major Changes
See [CHANGELOG.md](CHANGELOG.md) for a list of changes made in past version of this crate.
See [CHANGELOG.md](CHANGELOG.md) for a list of changes made in past versions of this crate.
## Breaking Changes in 2.0.0
@ -63,7 +63,7 @@ SemVer exemptions are outlined below for MSRV and public API.
| 2.x | 1.60 |
| 1.x | 1.41 |
From 2.x and on, MSRV changes will be accompanied by a minor version bump.
From 2.x onwards, MSRV changes will be accompanied by a minor version bump.
## Public API SemVer Exemptions
@ -130,7 +130,7 @@ Backend selection details and instructions can be found in the [curve25519-dalek
# Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md)
See [CONTRIBUTING.md](../CONTRIBUTING.md)
# Batch Signature Verification

View file

@ -11,7 +11,6 @@
use alloc::vec::Vec;
use core::convert::TryFrom;
use core::iter::once;
use curve25519_dalek::constants;

View file

@ -21,6 +21,7 @@
#![cfg_attr(feature = "rand_core", doc = "```")]
#![cfg_attr(not(feature = "rand_core"), doc = "```ignore")]
//! # fn main() {
//! // $ cargo add ed25519_dalek --features rand_core
//! use rand::rngs::OsRng;
//! use ed25519_dalek::SigningKey;
//! use ed25519_dalek::Signature;

View file

@ -9,7 +9,6 @@
//! An ed25519 signature.
use core::convert::TryFrom;
use core::fmt::Debug;
use curve25519_dalek::edwards::CompressedEdwardsY;
@ -58,7 +57,7 @@ impl Clone for InternalSignature {
}
impl Debug for InternalSignature {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Signature( R: {:?}, s: {:?} )", &self.R, &self.s)
}
}

View file

@ -543,7 +543,7 @@ impl AsRef<VerifyingKey> for SigningKey {
}
impl Debug for SigningKey {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SigningKey")
.field("verifying_key", &self.verifying_key)
.finish_non_exhaustive() // avoids printing `secret_key`
@ -742,7 +742,7 @@ impl<'d> Deserialize<'d> for SigningKey {
impl<'de> serde::de::Visitor<'de> for SigningKeyVisitor {
type Value = SigningKey;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(formatter, concat!("An ed25519 signing (private) key"))
}

View file

@ -9,7 +9,6 @@
//! ed25519 public keys.
use core::convert::TryFrom;
use core::fmt::Debug;
use core::hash::{Hash, Hasher};
@ -505,6 +504,11 @@ impl VerifyingKey {
pub fn to_montgomery(&self) -> MontgomeryPoint {
self.point.to_montgomery()
}
/// Return this verifying key in Edwards form.
pub fn to_edwards(&self) -> EdwardsPoint {
self.point
}
}
impl Verifier<ed25519::Signature> for VerifyingKey {
@ -563,6 +567,12 @@ impl TryFrom<&[u8]> for VerifyingKey {
}
}
impl From<VerifyingKey> for EdwardsPoint {
fn from(vk: VerifyingKey) -> EdwardsPoint {
vk.point
}
}
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
impl pkcs8::EncodePublicKey for VerifyingKey {
fn to_public_key_der(&self) -> pkcs8::spki::Result<pkcs8::Document> {
@ -632,7 +642,7 @@ impl<'d> Deserialize<'d> for VerifyingKey {
impl<'de> serde::de::Visitor<'de> for VerifyingKeyVisitor {
type Value = VerifyingKey;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(formatter, concat!("An ed25519 verifying (public) key"))
}

View file

@ -27,10 +27,11 @@ mod vectors {
scalar::Scalar,
traits::IsIdentity,
};
#[cfg(not(feature = "digest"))]
use sha2::{digest::Digest, Sha512};
use std::{
convert::TryFrom,
fs::File,
io::{BufRead, BufReader},
ops::Neg,
@ -288,8 +289,6 @@ mod vectors {
mod integrations {
use super::*;
use rand::rngs::OsRng;
#[cfg(feature = "digest")]
use sha2::Sha512;
use std::collections::HashMap;
#[test]
@ -459,6 +458,29 @@ mod integrations {
assert_eq!(v, "Second public key");
assert_eq!(m.len(), 2usize);
}
#[test]
fn montgomery_and_edwards_conversion() {
let mut rng = rand::rngs::OsRng;
let signing_key = SigningKey::generate(&mut rng);
let verifying_key = signing_key.verifying_key();
let ed = verifying_key.to_edwards();
// Check that to_edwards and From return same result:
assert_eq!(ed, curve25519_dalek::EdwardsPoint::from(verifying_key));
// The verifying key serialization is simply the compressed Edwards point
assert_eq!(verifying_key.to_bytes(), ed.compress().0);
// Check that modulo sign, to_montgomery().to_edwards() returns the original point
let monty = verifying_key.to_montgomery();
let via_monty0 = monty.to_edwards(0).unwrap();
let via_monty1 = monty.to_edwards(1).unwrap();
assert!(via_monty0 != via_monty1);
assert!(ed == via_monty0 || ed == via_monty1);
}
}
#[cfg(all(test, feature = "serde"))]

View file

@ -22,7 +22,7 @@ const VERIFY_ALLOWED_EDGECASES: &[Flag] = &[
const VERIFY_STRICT_ALLOWED_EDGECASES: &[Flag] =
&[Flag::LowOrderComponentA, Flag::LowOrderComponentR];
/// Each variant describes a specfiic edge case that can occur in an Ed25519 signature. Refer to
/// Each variant describes a specific edge case that can occur in an Ed25519 signature. Refer to
/// the test vector [README][] for more info.
///
/// [README]: https://github.com/C2SP/CCTV/blob/5ea85644bd035c555900a2f707f7e4c31ea65ced/ed25519vectors/README.md

View file

@ -6,6 +6,10 @@ Entries are listed in reverse chronological order.
* Note: All `x255919-dalek` 2.x releases are in sync with the underlying `curve25519-dalek` 4.x releases.
## 2.0.1
* Fix nightly SIMD build
## 2.0.0-rc.3
* `StaticSecret` serialization and `to_bytes()` no longer returns clamped integers. Clamping is still always done during scalar-point multiplication.

View file

@ -6,7 +6,7 @@ edition = "2021"
# - update html_root_url
# - update CHANGELOG
# - if any changes were made to README.md, mirror them in src/lib.rs docs
version = "2.0.0"
version = "2.0.1"
authors = [
"Isis Lovecruft <isis@patternsinthevoid.net>",
"DebugSteven <debugsteven@gmail.com>",