Skip to content

Commit

Permalink
Merge pull request #2000 from zh-jq/ec_point_to_hex_str
Browse files Browse the repository at this point in the history
add EcPointRef::to_hex_str and EcPoint::from_hex_str
  • Loading branch information
sfackler authored Jul 23, 2023
2 parents 82f049d + ebf8027 commit 99bce5b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
14 changes: 14 additions & 0 deletions openssl-sys/src/handwritten/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,20 @@ extern "C" {
ctx: *mut BN_CTX,
) -> c_int;

pub fn EC_POINT_point2hex(
group: *const EC_GROUP,
p: *const EC_POINT,
form: point_conversion_form_t,
ctx: *mut BN_CTX,
) -> *mut c_char;

pub fn EC_POINT_hex2point(
group: *const EC_GROUP,
s: *const c_char,
p: *mut EC_POINT,
ctx: *mut BN_CTX,
) -> *mut EC_POINT;

pub fn EC_POINT_add(
group: *const EC_GROUP,
r: *mut EC_POINT,
Expand Down
63 changes: 63 additions & 0 deletions openssl/src/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! [`EcGroup`]: struct.EcGroup.html
//! [`Nid`]: ../nid/struct.Nid.html
//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::fmt;
Expand All @@ -28,6 +29,13 @@ use crate::util::ForeignTypeRefExt;
use crate::{cvt, cvt_n, cvt_p, init};
use openssl_macros::corresponds;

cfg_if! {
if #[cfg(not(boringssl))] {
use std::ffi::CString;
use crate::string::OpensslString;
}
}

/// Compressed or Uncompressed conversion
///
/// Conversion from the binary value of the point on the curve is performed in one of
Expand Down Expand Up @@ -463,6 +471,26 @@ impl EcPointRef {
}
}

/// Serializes the point to a hexadecimal string representation.
#[corresponds(EC_POINT_point2hex)]
#[cfg(not(boringssl))]
pub fn to_hex_str(
&self,
group: &EcGroupRef,
form: PointConversionForm,
ctx: &mut BigNumContextRef,
) -> Result<OpensslString, ErrorStack> {
unsafe {
let buf = cvt_p(ffi::EC_POINT_point2hex(
group.as_ptr(),
self.as_ptr(),
form.0,
ctx.as_ptr(),
))?;
Ok(OpensslString::from_ptr(buf))
}
}

/// Creates a new point on the specified curve with the same value.
#[corresponds(EC_POINT_dup)]
pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> {
Expand Down Expand Up @@ -631,6 +659,27 @@ impl EcPoint {
}
Ok(point)
}

/// Creates point from a hexadecimal string representation
#[corresponds(EC_POINT_hex2point)]
#[cfg(not(boringssl))]
pub fn from_hex_str(
group: &EcGroupRef,
s: &str,
ctx: &mut BigNumContextRef,
) -> Result<EcPoint, ErrorStack> {
let point = EcPoint::new(group)?;
unsafe {
let c_str = CString::new(s.as_bytes()).unwrap();
cvt_p(ffi::EC_POINT_hex2point(
group.as_ptr(),
c_str.as_ptr() as *const _,
point.as_ptr(),
ctx.as_ptr(),
))?;
}
Ok(point)
}
}

generic_foreign_type_and_impl_send_sync! {
Expand Down Expand Up @@ -1121,6 +1170,20 @@ mod test {
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}

#[test]
#[cfg(not(boringssl))]
fn point_hex_str() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let point = key.public_key();
let mut ctx = BigNumContext::new().unwrap();
let hex = point
.to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx)
.unwrap();
let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap();
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}

#[test]
fn point_owned() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
Expand Down

0 comments on commit 99bce5b

Please sign in to comment.