Skip to content

Commit e865426

Browse files
committed
Merge Scalar types
1 parent 7c6f898 commit e865426

File tree

22 files changed

+645
-1001
lines changed

22 files changed

+645
-1001
lines changed

ed448-goldilocks/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,27 @@ It is intended to be portable, fast, and safe.
1717
## Usage
1818

1919
```rust
20-
use ed448_goldilocks::{Ed448, EdwardsPoint, CompressedEdwardsY, EdwardsScalar, sha3::Shake256};
20+
use ed448_goldilocks::{Ed448, EdwardsPoint, CompressedEdwardsY, Scalar, sha3::Shake256};
2121
use elliptic_curve::consts::U84;
2222
use elliptic_curve::Field;
2323
use elliptic_curve::group::GroupEncoding;
2424
use hash2curve::{ExpandMsgXof, GroupDigest};
2525
use rand_core::OsRng;
2626

27-
let secret_key = EdwardsScalar::TWO;
27+
let secret_key = Scalar::TWO;
2828
let public_key = EdwardsPoint::GENERATOR * &secret_key;
2929

3030
assert_eq!(public_key, EdwardsPoint::GENERATOR + EdwardsPoint::GENERATOR);
3131

32-
let secret_key = EdwardsScalar::try_from_rng(&mut OsRng).unwrap();
32+
let secret_key = Scalar::try_from_rng(&mut OsRng).unwrap();
3333
let public_key = EdwardsPoint::GENERATOR * &secret_key;
3434
let compressed_public_key = public_key.to_bytes();
3535

3636
assert_eq!(compressed_public_key.len(), 57);
3737

3838
let hashed_scalar = hash2curve::hash_to_scalar::<Ed448, <Ed448 as GroupDigest>::ExpandMsg, U84>(&[b"test"], &[b"test DST"]).unwrap();
39-
let input = hex_literal::hex!("8108d09ce4ea5707d44a6e52d75f290d0a0801cd5e366b9a0e6f72c75246ea5042963192c01703749adb0f5a4b1ab0586ccc6cf58cfd6d0e00");
40-
let expected_scalar = EdwardsScalar::from_canonical_bytes(&input.into()).unwrap();
39+
let input = hex_literal::hex!("8108d09ce4ea5707d44a6e52d75f290d0a0801cd5e366b9a0e6f72c75246ea5042963192c01703749adb0f5a4b1ab0586ccc6cf58cfd6d0e");
40+
let expected_scalar = Scalar::from_canonical_bytes(&input.into()).unwrap();
4141
assert_eq!(hashed_scalar, expected_scalar);
4242

4343
let hashed_point = Ed448::hash_from_bytes(b"test", b"test DST").unwrap();

ed448-goldilocks/benches/bench.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
2-
use ed448_goldilocks::{
3-
Decaf448, DecafPoint, DecafScalar, Ed448, EdwardsPoint, EdwardsScalar, MontgomeryPoint,
4-
};
2+
use ed448_goldilocks::{Decaf448, DecafPoint, Ed448, EdwardsPoint, MontgomeryPoint, Scalar};
53
use elliptic_curve::group::GroupEncoding;
64
use elliptic_curve::{Field, Group};
75
use hash2curve::GroupDigest;
@@ -14,7 +12,7 @@ pub fn ed448(c: &mut Criterion) {
1412
b.iter_batched(
1513
|| {
1614
let point = EdwardsPoint::try_from_rng(&mut OsRng).unwrap();
17-
let scalar = EdwardsScalar::try_from_rng(&mut OsRng).unwrap();
15+
let scalar = Scalar::try_from_rng(&mut OsRng).unwrap();
1816
(point, scalar)
1917
},
2018
|(point, scalar)| point * scalar,
@@ -72,7 +70,7 @@ pub fn decaf448(c: &mut Criterion) {
7270
b.iter_batched(
7371
|| {
7472
let point = DecafPoint::try_from_rng(&mut OsRng).unwrap();
75-
let scalar = DecafScalar::try_from_rng(&mut OsRng).unwrap();
73+
let scalar = Scalar::try_from_rng(&mut OsRng).unwrap();
7674
(point, scalar)
7775
},
7876
|(point, scalar)| point * scalar,
@@ -131,7 +129,7 @@ pub fn x448(c: &mut Criterion) {
131129
|| {
132130
let mut point = MontgomeryPoint::default();
133131
OsRng.try_fill_bytes(&mut point.0).unwrap();
134-
let scalar = EdwardsScalar::try_from_rng(&mut OsRng).unwrap();
132+
let scalar = Scalar::try_from_rng(&mut OsRng).unwrap();
135133
(point, scalar)
136134
},
137135
|(point, scalar)| &point * &scalar,

ed448-goldilocks/src/curve/scalar_mul/variable_base.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#![allow(non_snake_case)]
22

33
use super::window::wnaf::LookupTable;
4-
use crate::EdwardsScalar;
4+
use crate::Scalar;
55
use crate::curve::twedwards::{extended::ExtendedPoint, extensible::ExtensiblePoint};
66
use subtle::{Choice, ConditionallyNegatable};
77

8-
pub fn variable_base(point: &ExtendedPoint, s: &EdwardsScalar) -> ExtensiblePoint {
8+
pub fn variable_base(point: &ExtendedPoint, s: &Scalar) -> ExtensiblePoint {
99
let mut result = ExtensiblePoint::IDENTITY;
1010

1111
// Recode Scalar
@@ -40,12 +40,13 @@ mod test {
4040
use crate::TWISTED_EDWARDS_BASE_POINT;
4141
use crate::curve::scalar_mul::double_and_add;
4242
use elliptic_curve::bigint::U448;
43+
use elliptic_curve::scalar::FromUintUnchecked;
4344

4445
#[test]
4546
fn test_scalar_mul() {
4647
// XXX: In the future use known multiples from Sage in bytes form?
4748
let twisted_point = TWISTED_EDWARDS_BASE_POINT;
48-
let scalar = EdwardsScalar::new(U448::from_be_hex(
49+
let scalar = Scalar::from_uint_unchecked(U448::from_be_hex(
4950
"05ca185aee2e1b73def437f63c003777083f83043fe5bf1aab454c66b64629d1de8026c1307f665ead0b70151533427ce128ae786ee372b7",
5051
));
5152

@@ -66,11 +67,11 @@ mod test {
6667
let x = TWISTED_EDWARDS_BASE_POINT;
6768

6869
// Test that 1 * P = P
69-
let exp = variable_base(&x, &EdwardsScalar::from(1u8));
70+
let exp = variable_base(&x, &Scalar::from(1u8));
7071
assert!(x == exp);
7172
// Test that 2 * (P + P) = 4 * P
7273
let expected_two_x = x.add_extended(&x).double();
73-
let got = variable_base(&x, &EdwardsScalar::from(4u8));
74+
let got = variable_base(&x, &Scalar::from(4u8));
7475
assert!(expected_two_x == got);
7576
}
7677
}

ed448-goldilocks/src/decaf.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
pub mod affine;
55
mod ops;
66
pub mod points;
7-
mod scalar;
87

98
pub use affine::AffinePoint;
109
pub use points::{CompressedDecaf, DecafPoint};
11-
pub use scalar::{DecafScalar, DecafScalarBytes, WideDecafScalarBytes};
1210

1311
// https://www.rfc-editor.org/rfc/rfc9496#name-group-elements-from-uniform-
1412
#[test]

ed448-goldilocks/src/decaf/affine.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::curve::twedwards::affine::AffinePoint as InnerAffinePoint;
22
use crate::field::FieldElement;
3-
use crate::{Decaf448FieldBytes, DecafPoint, DecafScalar, ORDER};
3+
use crate::{Decaf448FieldBytes, DecafPoint, ORDER, Scalar};
44
use core::ops::Mul;
5+
use elliptic_curve::scalar::FromUintUnchecked;
56
use elliptic_curve::{
67
Error,
78
point::{AffineCoordinates, NonIdentity},
@@ -47,7 +48,8 @@ impl AffineCoordinates for AffinePoint {
4748

4849
CtOption::new(
4950
point,
50-
point.0.is_on_curve() & (point * DecafScalar::new(*ORDER)).ct_eq(&DecafPoint::IDENTITY),
51+
point.0.is_on_curve()
52+
& (point * Scalar::from_uint_unchecked(*ORDER)).ct_eq(&DecafPoint::IDENTITY),
5153
)
5254
}
5355

@@ -105,13 +107,13 @@ impl From<NonIdentity<AffinePoint>> for AffinePoint {
105107
}
106108
}
107109

108-
impl Mul<&DecafScalar> for &AffinePoint {
110+
impl Mul<&Scalar> for &AffinePoint {
109111
type Output = DecafPoint;
110112

111113
#[inline]
112-
fn mul(self, scalar: &DecafScalar) -> DecafPoint {
114+
fn mul(self, scalar: &Scalar) -> DecafPoint {
113115
self.to_decaf() * scalar
114116
}
115117
}
116118

117-
define_mul_variants!(LHS = AffinePoint, RHS = DecafScalar, Output = DecafPoint);
119+
define_mul_variants!(LHS = AffinePoint, RHS = Scalar, Output = DecafPoint);

ed448-goldilocks/src/decaf/ops.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,34 @@
1-
use crate::{DecafAffinePoint, DecafScalar, curve::scalar_mul::double_and_add};
1+
use crate::{Decaf448, DecafAffinePoint, Scalar, curve::scalar_mul::double_and_add};
22
use core::{
33
borrow::Borrow,
44
iter::Sum,
55
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
66
};
7-
use elliptic_curve::CurveGroup;
7+
use elliptic_curve::{CurveGroup, scalar::FromUintUnchecked};
88

99
use super::DecafPoint;
1010

11+
elliptic_curve::scalar_impls!(Decaf448, Scalar);
12+
1113
/// Scalar Mul Operations
12-
impl Mul<&DecafScalar> for &DecafPoint {
14+
impl Mul<&Scalar> for &DecafPoint {
1315
type Output = DecafPoint;
1416

15-
fn mul(self, scalar: &DecafScalar) -> DecafPoint {
17+
fn mul(self, scalar: &Scalar) -> DecafPoint {
1618
// XXX: We can do better than double and add
1719
DecafPoint(double_and_add(&self.0, scalar.bits()).to_extended())
1820
}
1921
}
2022

21-
define_mul_variants!(LHS = DecafPoint, RHS = DecafScalar, Output = DecafPoint);
23+
define_mul_variants!(LHS = DecafPoint, RHS = Scalar, Output = DecafPoint);
2224

23-
impl<'s> MulAssign<&'s DecafScalar> for DecafPoint {
24-
fn mul_assign(&mut self, scalar: &'s DecafScalar) {
25+
impl<'s> MulAssign<&'s Scalar> for DecafPoint {
26+
fn mul_assign(&mut self, scalar: &'s Scalar) {
2527
*self = *self * scalar;
2628
}
2729
}
28-
impl MulAssign<DecafScalar> for DecafPoint {
29-
fn mul_assign(&mut self, scalar: DecafScalar) {
30+
impl MulAssign<Scalar> for DecafPoint {
31+
fn mul_assign(&mut self, scalar: Scalar) {
3032
*self = *self * scalar;
3133
}
3234
}

ed448-goldilocks/src/decaf/points.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl TryFrom<&DecafPointBytes> for DecafPoint {
167167
}
168168

169169
impl Group for DecafPoint {
170-
type Scalar = DecafScalar;
170+
type Scalar = Scalar;
171171

172172
fn try_from_rng<R>(rng: &mut R) -> Result<Self, R::Error>
173173
where
@@ -239,9 +239,9 @@ impl CofactorGroup for DecafPoint {
239239

240240
impl PrimeGroup for DecafPoint {}
241241

242-
impl<const N: usize> LinearCombination<[(DecafPoint, DecafScalar); N]> for DecafPoint {}
242+
impl<const N: usize> LinearCombination<[(DecafPoint, Scalar); N]> for DecafPoint {}
243243

244-
impl LinearCombination<[(DecafPoint, DecafScalar)]> for DecafPoint {}
244+
impl LinearCombination<[(DecafPoint, Scalar)]> for DecafPoint {}
245245

246246
impl CurveGroup for DecafPoint {
247247
type AffineRepr = DecafAffinePoint;
@@ -599,7 +599,10 @@ impl From<NonIdentity<DecafPoint>> for DecafPoint {
599599
mod test {
600600
use super::*;
601601
use crate::TWISTED_EDWARDS_BASE_POINT;
602+
use elliptic_curve::PrimeField;
603+
use elliptic_curve::consts::U64;
602604
use hash2curve::ExpandMsgXof;
605+
use hex_literal::hex;
603606
use sha3::Shake256;
604607

605608
#[test]
@@ -761,6 +764,72 @@ mod test {
761764
assert_ne!(point, DecafPoint::GENERATOR);
762765
}
763766

767+
#[test]
768+
fn scalar_hash() {
769+
let msg = b"hello world";
770+
let dst = b"decaf448_XOF:SHAKE256_D448MAP_RO_";
771+
let res =
772+
hash2curve::hash_to_scalar::<Decaf448, ExpandMsgXof<Shake256>, U64>(&[msg], &[dst])
773+
.unwrap();
774+
let expected: [u8; 56] = hex_literal::hex!(
775+
"55e7b59aa035db959409c6b69b817a18c8133d9ad06687665f5720672924da0a84eab7fee415ef13e7aaebdd227291ee8e156f32c507ad2e"
776+
);
777+
assert_eq!(res.to_repr(), Array::from(expected));
778+
}
779+
780+
/// Taken from <https://www.rfc-editor.org/rfc/rfc9497.html#name-decaf448-shake256>.
781+
#[test]
782+
fn hash_to_scalar_voprf() {
783+
struct TestVector {
784+
dst: &'static [u8],
785+
sk_sm: &'static [u8],
786+
}
787+
788+
const KEY_INFO: &[u8] = b"test key";
789+
const SEED: &[u8] =
790+
&hex!("a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3");
791+
792+
const TEST_VECTORS: &[TestVector] = &[
793+
TestVector {
794+
dst: b"DeriveKeyPairOPRFV1-\x00-decaf448-SHAKE256",
795+
sk_sm: &hex!(
796+
"e8b1375371fd11ebeb224f832dcc16d371b4188951c438f751425699ed29ecc80c6c13e558ccd67634fd82eac94aa8d1f0d7fee990695d1e"
797+
),
798+
},
799+
TestVector {
800+
dst: b"DeriveKeyPairOPRFV1-\x01-decaf448-SHAKE256",
801+
sk_sm: &hex!(
802+
"e3c01519a076a326a0eb566343e9b21c115fa18e6e85577ddbe890b33104fcc2835ddfb14a928dc3f5d79b936e17c76b99e0bf6a1680930e"
803+
),
804+
},
805+
TestVector {
806+
dst: b"DeriveKeyPairOPRFV1-\x02-decaf448-SHAKE256",
807+
sk_sm: &hex!(
808+
"792a10dcbd3ba4a52a054f6f39186623208695301e7adb9634b74709ab22de402990eb143fd7c67ac66be75e0609705ecea800992aac8e19"
809+
),
810+
},
811+
];
812+
813+
let key_info_len = u16::try_from(KEY_INFO.len()).unwrap().to_be_bytes();
814+
815+
'outer: for test_vector in TEST_VECTORS {
816+
for counter in 0_u8..=u8::MAX {
817+
let scalar = hash2curve::hash_to_scalar::<Decaf448, ExpandMsgXof<Shake256>, U64>(
818+
&[SEED, &key_info_len, KEY_INFO, &counter.to_be_bytes()],
819+
&[test_vector.dst],
820+
)
821+
.unwrap();
822+
823+
if !bool::from(scalar.is_zero()) {
824+
assert_eq!(scalar.to_bytes().as_slice(), test_vector.sk_sm);
825+
continue 'outer;
826+
}
827+
}
828+
829+
panic!("deriving key failed");
830+
}
831+
}
832+
764833
// TODO: uncomment once elliptic-curve-tools is updated to match elliptic-curve 0.14
765834
// #[test]
766835
// fn test_sum_of_products() { use elliptic_curve_tools::SumOfProducts; let values = [ (Scalar::from(8u8), DecafPoint::GENERATOR), (Scalar::from(9u8), DecafPoint::GENERATOR), (Scalar::from(10u8), DecafPoint::GENERATOR), (Scalar::from(11u8), DecafPoint::GENERATOR), (Scalar::from(12u8), DecafPoint::GENERATOR), ]; let expected = DecafPoint::GENERATOR * Scalar::from(50u8); let result = DecafPoint::sum_of_products(&values); assert_eq!(result, expected); }

0 commit comments

Comments
 (0)