diff --git a/openssl-sys/src/ec.rs b/openssl-sys/src/ec.rs index 5998e5bf..ffb1a16c 100644 --- a/openssl-sys/src/ec.rs +++ b/openssl-sys/src/ec.rs @@ -82,6 +82,11 @@ extern "C" { pub fn EC_POINT_free(point: *mut EC_POINT); + pub fn EC_POINT_dup( + p: *const EC_POINT, + group: *const EC_GROUP, + ) -> *mut EC_POINT; + pub fn EC_POINT_get_affine_coordinates_GFp( group: *const EC_GROUP, p: *const EC_POINT, diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs index 73aedc71..d6097bbc 100644 --- a/openssl/src/ec.rs +++ b/openssl/src/ec.rs @@ -446,6 +446,20 @@ impl EcPointRef { } } + /// Creates a new point on the specified curve with the same value. + /// + /// OpenSSL documentation at [`EC_POINT_dup`] + /// + /// [`EC_POINT_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_POINT_dup.html + pub fn to_owned( + &self, + group: &EcGroupRef, + ) -> Result { + unsafe { + cvt_p(ffi::EC_POINT_dup(self.as_ptr(), group.as_ptr())).map(EcPoint) + } + } + /// Determines if this point is equal to another. /// /// OpenSSL doucmentation at [`EC_POINT_cmp`] @@ -919,6 +933,16 @@ mod test { assert!(point.eq(&group, &point2, &mut ctx).unwrap()); } + #[test] + fn point_owned() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let point = key.public_key(); + let owned = point.to_owned(&group).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + assert!(owned.eq(&group, point, &mut ctx).unwrap()); + } + #[test] fn mul_generator() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();