Skip to content

Commit 5028239

Browse files
committed
Add NonIdentity::mul_by_generator() (RustCrypto#1833)
This PR adds `NonIdentity::mul_by_generator()`, which is similar to the `MulByGenerator` trait, but returns a `NonIdentity` instead of a `ProjectivePoint`. This is quite useful for getting the public key from a `NonZeroScalar` without having to go through the whole conversion dance.
1 parent e99fe58 commit 5028239

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

elliptic-curve/src/point/non_identity.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
33
use core::ops::{Deref, Mul};
44

5-
use group::{prime::PrimeCurveAffine, Curve, GroupEncoding};
5+
use group::{prime::PrimeCurveAffine, Curve, Group, GroupEncoding};
66
use rand_core::{CryptoRng, RngCore};
77
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
88

99
#[cfg(feature = "serde")]
1010
use serdect::serde::{de, ser, Deserialize, Serialize};
1111
use zeroize::Zeroize;
1212

13-
use crate::{CurveArithmetic, NonZeroScalar, Scalar};
13+
use crate::{ops::MulByGenerator, CurveArithmetic, NonZeroScalar, Scalar};
1414

1515
/// Non-identity point type.
1616
///
@@ -73,6 +73,16 @@ where
7373
point: self.point.to_affine(),
7474
}
7575
}
76+
77+
/// Multiply by the generator of the prime-order subgroup.
78+
pub fn mul_by_generator<C: CurveArithmetic>(scalar: &NonZeroScalar<C>) -> Self
79+
where
80+
P: Group<Scalar = C::Scalar> + MulByGenerator,
81+
{
82+
Self {
83+
point: P::mul_by_generator(scalar),
84+
}
85+
}
7686
}
7787

7888
impl<P> NonIdentity<P>
@@ -194,7 +204,7 @@ where
194204
}
195205
}
196206

197-
impl<P: group::Group> Zeroize for NonIdentity<P> {
207+
impl<P: Group> Zeroize for NonIdentity<P> {
198208
fn zeroize(&mut self) {
199209
self.point = P::generator();
200210
}
@@ -203,7 +213,7 @@ impl<P: group::Group> Zeroize for NonIdentity<P> {
203213
#[cfg(all(test, feature = "dev"))]
204214
mod tests {
205215
use super::NonIdentity;
206-
use crate::dev::{AffinePoint, ProjectivePoint};
216+
use crate::dev::{AffinePoint, NonZeroScalar, ProjectivePoint, SecretKey};
207217
use group::GroupEncoding;
208218
use hex_literal::hex;
209219
use zeroize::Zeroize;
@@ -254,4 +264,18 @@ mod tests {
254264

255265
assert_eq!(point.to_point(), ProjectivePoint::Generator);
256266
}
267+
268+
#[test]
269+
fn mul_by_generator() {
270+
let scalar = NonZeroScalar::from_repr(
271+
hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(),
272+
)
273+
.unwrap();
274+
let point = NonIdentity::<ProjectivePoint>::mul_by_generator(&scalar);
275+
276+
let sk = SecretKey::from(scalar);
277+
let pk = sk.public_key();
278+
279+
assert_eq!(point.to_point(), pk.to_projective());
280+
}
257281
}

0 commit comments

Comments
 (0)