diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index dbee44ec4..3068afaa0 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -2,7 +2,7 @@ use core::ops::{Deref, Mul}; -use group::{Curve, GroupEncoding, prime::PrimeCurveAffine}; +use group::{Curve, Group, GroupEncoding, prime::PrimeCurveAffine}; use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -73,6 +73,16 @@ where point: self.point.to_affine(), } } + + /// Multiply by the generator of the prime-order subgroup. + pub fn mul_by_generator(scalar: &NonZeroScalar) -> Self + where + P: Group, + { + Self { + point: P::mul_by_generator(scalar), + } + } } impl

NonIdentity

@@ -195,7 +205,7 @@ where } } -impl Zeroize for NonIdentity

{ +impl Zeroize for NonIdentity

{ fn zeroize(&mut self) { self.point = P::generator(); } @@ -204,7 +214,7 @@ impl Zeroize for NonIdentity

{ #[cfg(all(test, feature = "dev"))] mod tests { use super::NonIdentity; - use crate::dev::{AffinePoint, ProjectivePoint}; + use crate::dev::{AffinePoint, NonZeroScalar, ProjectivePoint, SecretKey}; use group::GroupEncoding; use hex_literal::hex; use zeroize::Zeroize; @@ -255,4 +265,18 @@ mod tests { assert_eq!(point.to_point(), ProjectivePoint::Generator); } + + #[test] + fn mul_by_generator() { + let scalar = NonZeroScalar::from_repr( + hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + let point = NonIdentity::::mul_by_generator(&scalar); + + let sk = SecretKey::from(scalar); + let pk = sk.public_key(); + + assert_eq!(point.to_point(), pk.to_projective()); + } }