Skip to content

Commit 65be261

Browse files
authored
primeorder: add scalar_mul_impls! macro (#1198)
Adds a macro which writes a series of `Mul` impls for `Scalar` types for both `AffinePoint` and `ProjectivePoint` as operands (and various combinations of references thereof). See also: RustCrypto/traits#1854
1 parent 692953f commit 65be261

File tree

15 files changed

+233
-14
lines changed

15 files changed

+233
-14
lines changed

bign256/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ primefield::fiat_field_arithmetic!(
8888
fiat_bign256_scalar_selectznz
8989
);
9090

91+
primeorder::scalar_mul_impls!(BignP256, Scalar);
92+
9193
impl Scalar {
9294
/// Returns the square root of self mod p, or `None` if no square root
9395
/// exists.

bp256/src/arithmetic/scalar.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
mod scalar_impl;
1616

1717
use self::scalar_impl::*;
18-
use crate::{FieldBytes, ORDER, ORDER_HEX, U256};
18+
use crate::{BrainpoolP256r1, BrainpoolP256t1, FieldBytes, ORDER, ORDER_HEX, U256};
1919
use elliptic_curve::{
2020
Error, Result,
2121
bigint::{ArrayEncoding, Limb},
@@ -60,6 +60,9 @@ primefield::fiat_field_arithmetic!(
6060
fiat_bp256_scalar_selectznz
6161
);
6262

63+
primeorder::scalar_mul_impls!(BrainpoolP256r1, Scalar);
64+
primeorder::scalar_mul_impls!(BrainpoolP256t1, Scalar);
65+
6366
impl Scalar {
6467
/// Returns the square root of self mod n, or `None` if no square root
6568
/// exists.

bp384/src/arithmetic/scalar.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
mod scalar_impl;
1616

1717
use self::scalar_impl::*;
18-
use crate::{FieldBytes, ORDER, ORDER_HEX, U384};
18+
use crate::{BrainpoolP384r1, BrainpoolP384t1, FieldBytes, ORDER, ORDER_HEX, U384};
1919
use elliptic_curve::{
2020
Error, Result,
2121
bigint::{ArrayEncoding, Limb},
@@ -60,6 +60,9 @@ primefield::fiat_field_arithmetic!(
6060
fiat_bp384_scalar_selectznz
6161
);
6262

63+
primeorder::scalar_mul_impls!(BrainpoolP384r1, Scalar);
64+
primeorder::scalar_mul_impls!(BrainpoolP384t1, Scalar);
65+
6366
impl Scalar {
6467
/// Atkin algorithm for q mod 8 = 5
6568
/// <https://eips.ethereum.org/assets/eip-3068/2012-685_Square_Root_Even_Ext.pdf>

k256/src/arithmetic/scalar.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ mod wide;
66

77
pub(crate) use self::wide::WideScalar;
88

9-
use crate::{FieldBytes, NonZeroScalar, ORDER, ORDER_HEX, Secp256k1, WideBytes};
9+
use crate::{
10+
FieldBytes, NonZeroScalar, ORDER, ORDER_HEX, Secp256k1, WideBytes,
11+
arithmetic::{AffinePoint, ProjectivePoint},
12+
};
1013
use core::{
1114
iter::{Product, Sum},
1215
ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign},
@@ -656,6 +659,78 @@ impl Mul<&Scalar> for Scalar {
656659
}
657660
}
658661

662+
impl Mul<AffinePoint> for Scalar {
663+
type Output = ProjectivePoint;
664+
665+
#[inline]
666+
fn mul(self, rhs: AffinePoint) -> ProjectivePoint {
667+
rhs * self
668+
}
669+
}
670+
671+
impl Mul<&AffinePoint> for Scalar {
672+
type Output = ProjectivePoint;
673+
674+
#[inline]
675+
fn mul(self, rhs: &AffinePoint) -> ProjectivePoint {
676+
*rhs * self
677+
}
678+
}
679+
680+
impl Mul<AffinePoint> for &Scalar {
681+
type Output = ProjectivePoint;
682+
683+
#[inline]
684+
fn mul(self, rhs: AffinePoint) -> ProjectivePoint {
685+
rhs * self
686+
}
687+
}
688+
689+
impl Mul<&AffinePoint> for &Scalar {
690+
type Output = ProjectivePoint;
691+
692+
#[inline]
693+
fn mul(self, rhs: &AffinePoint) -> ProjectivePoint {
694+
*rhs * self
695+
}
696+
}
697+
698+
impl Mul<ProjectivePoint> for Scalar {
699+
type Output = ProjectivePoint;
700+
701+
#[inline]
702+
fn mul(self, rhs: ProjectivePoint) -> ProjectivePoint {
703+
rhs * self
704+
}
705+
}
706+
707+
impl Mul<&ProjectivePoint> for Scalar {
708+
type Output = ProjectivePoint;
709+
710+
#[inline]
711+
fn mul(self, rhs: &ProjectivePoint) -> ProjectivePoint {
712+
rhs * &self
713+
}
714+
}
715+
716+
impl Mul<ProjectivePoint> for &Scalar {
717+
type Output = ProjectivePoint;
718+
719+
#[inline]
720+
fn mul(self, rhs: ProjectivePoint) -> ProjectivePoint {
721+
rhs * self
722+
}
723+
}
724+
725+
impl Mul<&ProjectivePoint> for &Scalar {
726+
type Output = ProjectivePoint;
727+
728+
#[inline]
729+
fn mul(self, rhs: &ProjectivePoint) -> ProjectivePoint {
730+
rhs * self
731+
}
732+
}
733+
659734
impl MulAssign<Scalar> for Scalar {
660735
fn mul_assign(&mut self, rhs: Scalar) {
661736
*self = Scalar::mul(self, &rhs);

p192/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ primefield::fiat_field_arithmetic!(
9898
fiat_p192_scalar_selectznz
9999
);
100100

101+
primeorder::scalar_mul_impls!(NistP192, Scalar);
102+
101103
impl Scalar {
102104
/// Tonelli-Shank's algorithm for q mod 16 = 1
103105
/// <https://eprint.iacr.org/2012/685.pdf> (page 12, algorithm 5)

p224/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ primefield::fiat_field_arithmetic!(
106106
fiat_p224_scalar_selectznz
107107
);
108108

109+
primeorder::scalar_mul_impls!(NistP224, Scalar);
110+
109111
impl Scalar {
110112
/// Atkin algorithm for q mod 8 = 5
111113
/// <https://eips.ethereum.org/assets/eip-3068/2012-685_Square_Root_Even_Ext.pdf>

p256/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,8 @@ impl SubAssign<&Scalar> for Scalar {
605605
}
606606
}
607607

608+
primeorder::scalar_mul_impls!(NistP256, Scalar);
609+
608610
impl Mul<Scalar> for Scalar {
609611
type Output = Scalar;
610612

p384/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ primefield::fiat_field_arithmetic!(
106106
fiat_p384_scalar_selectznz
107107
);
108108

109+
primeorder::scalar_mul_impls!(NistP384, Scalar);
110+
109111
impl Scalar {
110112
/// Compute modular square root.
111113
pub fn sqrt(&self) -> CtOption<Self> {

p521/src/arithmetic/scalar.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ impl Field for Scalar {
442442
primefield::field_op!(Scalar, Add, add, add);
443443
primefield::field_op!(Scalar, Sub, sub, sub);
444444
primefield::field_op!(Scalar, Mul, mul, multiply);
445+
primeorder::scalar_mul_impls!(NistP521, Scalar);
445446

446447
impl AddAssign<Scalar> for Scalar {
447448
#[inline]

primefield/src/lib.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,7 @@ macro_rules! field_element_type {
7474
$decode_uint:path,
7575
$encode_uint:path
7676
) => {
77-
primefield::field_element_type_core!(
78-
$fe,
79-
$bytes,
80-
$uint,
81-
$modulus,
82-
$decode_uint,
83-
$encode_uint
84-
);
77+
$crate::field_element_type_core!($fe, $bytes, $uint, $modulus, $decode_uint, $encode_uint);
8578

8679
$crate::field_op!($fe, Add, add, add);
8780
$crate::field_op!($fe, Sub, sub, sub);

primeorder/src/affine.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ where
429429
{
430430
type Output = ProjectivePoint<C>;
431431

432+
#[inline]
433+
fn mul(self, scalar: S) -> ProjectivePoint<C> {
434+
ProjectivePoint::<C>::from(self) * scalar
435+
}
436+
}
437+
438+
impl<C, S> Mul<S> for &AffinePoint<C>
439+
where
440+
C: PrimeCurveParams,
441+
S: Borrow<Scalar<C>>,
442+
ProjectivePoint<C>: Double,
443+
{
444+
type Output = ProjectivePoint<C>;
445+
446+
#[inline]
432447
fn mul(self, scalar: S) -> ProjectivePoint<C> {
433448
ProjectivePoint::<C>::from(self) * scalar
434449
}
@@ -440,6 +455,7 @@ where
440455
{
441456
type Output = Self;
442457

458+
#[inline]
443459
fn neg(self) -> Self {
444460
AffinePoint {
445461
x: self.x,
@@ -455,6 +471,7 @@ where
455471
{
456472
type Output = AffinePoint<C>;
457473

474+
#[inline]
458475
fn neg(self) -> AffinePoint<C> {
459476
-(*self)
460477
}

primeorder/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ pub mod point_arithmetic;
1717
mod affine;
1818
#[cfg(feature = "dev")]
1919
mod dev;
20+
mod macros;
2021
mod projective;
2122

2223
pub use crate::{affine::AffinePoint, projective::ProjectivePoint};
2324
pub use elliptic_curve::{self, Field, FieldBytes, PrimeCurve, PrimeField, array, point::Double};
2425

25-
use elliptic_curve::CurveArithmetic;
26-
use elliptic_curve::ops::Invert;
27-
use elliptic_curve::subtle::CtOption;
26+
use elliptic_curve::{CurveArithmetic, ops::Invert, subtle::CtOption};
2827

2928
/// Parameters for elliptic curves of prime order which can be described by the
3029
/// short Weierstrass equation.

primeorder/src/macros.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//! Macros for writing common patterns that interact with this crate.
2+
3+
/// Writes a series of `Mul` impls for an elliptic curve's scalar field
4+
#[macro_export]
5+
macro_rules! scalar_mul_impls {
6+
($curve:path, $scalar:ty) => {
7+
impl ::core::ops::Mul<$crate::elliptic_curve::AffinePoint<$curve>> for $scalar {
8+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
9+
10+
#[inline]
11+
fn mul(
12+
self,
13+
rhs: $crate::elliptic_curve::AffinePoint<$curve>,
14+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
15+
rhs * self
16+
}
17+
}
18+
19+
impl ::core::ops::Mul<&$crate::elliptic_curve::AffinePoint<$curve>> for $scalar {
20+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
21+
22+
#[inline]
23+
fn mul(
24+
self,
25+
rhs: &$crate::elliptic_curve::AffinePoint<$curve>,
26+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
27+
*rhs * self
28+
}
29+
}
30+
31+
impl ::core::ops::Mul<$crate::elliptic_curve::AffinePoint<$curve>> for &$scalar {
32+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
33+
34+
#[inline]
35+
fn mul(
36+
self,
37+
rhs: $crate::elliptic_curve::AffinePoint<$curve>,
38+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
39+
rhs * self
40+
}
41+
}
42+
43+
impl ::core::ops::Mul<&$crate::elliptic_curve::AffinePoint<$curve>> for &$scalar {
44+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
45+
46+
#[inline]
47+
fn mul(
48+
self,
49+
rhs: &$crate::elliptic_curve::AffinePoint<$curve>,
50+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
51+
*rhs * self
52+
}
53+
}
54+
55+
impl ::core::ops::Mul<$crate::elliptic_curve::ProjectivePoint<$curve>> for $scalar {
56+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
57+
58+
#[inline]
59+
fn mul(
60+
self,
61+
rhs: $crate::elliptic_curve::ProjectivePoint<$curve>,
62+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
63+
rhs * self
64+
}
65+
}
66+
67+
impl ::core::ops::Mul<&$crate::elliptic_curve::ProjectivePoint<$curve>> for $scalar {
68+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
69+
70+
#[inline]
71+
fn mul(
72+
self,
73+
rhs: &$crate::elliptic_curve::ProjectivePoint<$curve>,
74+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
75+
rhs * &self
76+
}
77+
}
78+
79+
impl ::core::ops::Mul<$crate::elliptic_curve::ProjectivePoint<$curve>> for &$scalar {
80+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
81+
82+
#[inline]
83+
fn mul(
84+
self,
85+
rhs: $crate::elliptic_curve::ProjectivePoint<$curve>,
86+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
87+
rhs * self
88+
}
89+
}
90+
91+
impl ::core::ops::Mul<&$crate::elliptic_curve::ProjectivePoint<$curve>> for &$scalar {
92+
type Output = $crate::elliptic_curve::ProjectivePoint<$curve>;
93+
94+
#[inline]
95+
fn mul(
96+
self,
97+
rhs: &$crate::elliptic_curve::ProjectivePoint<$curve>,
98+
) -> $crate::elliptic_curve::ProjectivePoint<$curve> {
99+
rhs * self
100+
}
101+
}
102+
};
103+
}

primeorder/src/projective.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,19 @@ where
738738
}
739739
}
740740

741+
impl<C, S> Mul<S> for &ProjectivePoint<C>
742+
where
743+
Self: Double,
744+
C: PrimeCurveParams,
745+
S: Borrow<Scalar<C>>,
746+
{
747+
type Output = ProjectivePoint<C>;
748+
749+
fn mul(self, scalar: S) -> ProjectivePoint<C> {
750+
ProjectivePoint::mul(self, scalar.borrow())
751+
}
752+
}
753+
741754
impl<C> Mul<&Scalar<C>> for &ProjectivePoint<C>
742755
where
743756
C: PrimeCurveParams,

sm2/src/arithmetic/scalar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ primefield::fiat_field_arithmetic!(
100100
fiat_sm2_scalar_selectznz
101101
);
102102

103+
primeorder::scalar_mul_impls!(Sm2, Scalar);
104+
103105
impl Scalar {
104106
/// Returns the square root of self mod n, or `None` if no square root
105107
/// exists.

0 commit comments

Comments
 (0)