Skip to content

Commit 99bce5b

Browse files
authored
Merge pull request #2000 from zh-jq/ec_point_to_hex_str
add EcPointRef::to_hex_str and EcPoint::from_hex_str
2 parents 82f049d + ebf8027 commit 99bce5b

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

openssl-sys/src/handwritten/ec.rs

+14
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,20 @@ extern "C" {
152152
ctx: *mut BN_CTX,
153153
) -> c_int;
154154

155+
pub fn EC_POINT_point2hex(
156+
group: *const EC_GROUP,
157+
p: *const EC_POINT,
158+
form: point_conversion_form_t,
159+
ctx: *mut BN_CTX,
160+
) -> *mut c_char;
161+
162+
pub fn EC_POINT_hex2point(
163+
group: *const EC_GROUP,
164+
s: *const c_char,
165+
p: *mut EC_POINT,
166+
ctx: *mut BN_CTX,
167+
) -> *mut EC_POINT;
168+
155169
pub fn EC_POINT_add(
156170
group: *const EC_GROUP,
157171
r: *mut EC_POINT,

openssl/src/ec.rs

+63
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//! [`EcGroup`]: struct.EcGroup.html
1616
//! [`Nid`]: ../nid/struct.Nid.html
1717
//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
18+
use cfg_if::cfg_if;
1819
use foreign_types::{ForeignType, ForeignTypeRef};
1920
use libc::c_int;
2021
use std::fmt;
@@ -28,6 +29,13 @@ use crate::util::ForeignTypeRefExt;
2829
use crate::{cvt, cvt_n, cvt_p, init};
2930
use openssl_macros::corresponds;
3031

32+
cfg_if! {
33+
if #[cfg(not(boringssl))] {
34+
use std::ffi::CString;
35+
use crate::string::OpensslString;
36+
}
37+
}
38+
3139
/// Compressed or Uncompressed conversion
3240
///
3341
/// Conversion from the binary value of the point on the curve is performed in one of
@@ -463,6 +471,26 @@ impl EcPointRef {
463471
}
464472
}
465473

474+
/// Serializes the point to a hexadecimal string representation.
475+
#[corresponds(EC_POINT_point2hex)]
476+
#[cfg(not(boringssl))]
477+
pub fn to_hex_str(
478+
&self,
479+
group: &EcGroupRef,
480+
form: PointConversionForm,
481+
ctx: &mut BigNumContextRef,
482+
) -> Result<OpensslString, ErrorStack> {
483+
unsafe {
484+
let buf = cvt_p(ffi::EC_POINT_point2hex(
485+
group.as_ptr(),
486+
self.as_ptr(),
487+
form.0,
488+
ctx.as_ptr(),
489+
))?;
490+
Ok(OpensslString::from_ptr(buf))
491+
}
492+
}
493+
466494
/// Creates a new point on the specified curve with the same value.
467495
#[corresponds(EC_POINT_dup)]
468496
pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> {
@@ -631,6 +659,27 @@ impl EcPoint {
631659
}
632660
Ok(point)
633661
}
662+
663+
/// Creates point from a hexadecimal string representation
664+
#[corresponds(EC_POINT_hex2point)]
665+
#[cfg(not(boringssl))]
666+
pub fn from_hex_str(
667+
group: &EcGroupRef,
668+
s: &str,
669+
ctx: &mut BigNumContextRef,
670+
) -> Result<EcPoint, ErrorStack> {
671+
let point = EcPoint::new(group)?;
672+
unsafe {
673+
let c_str = CString::new(s.as_bytes()).unwrap();
674+
cvt_p(ffi::EC_POINT_hex2point(
675+
group.as_ptr(),
676+
c_str.as_ptr() as *const _,
677+
point.as_ptr(),
678+
ctx.as_ptr(),
679+
))?;
680+
}
681+
Ok(point)
682+
}
634683
}
635684

636685
generic_foreign_type_and_impl_send_sync! {
@@ -1121,6 +1170,20 @@ mod test {
11211170
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
11221171
}
11231172

1173+
#[test]
1174+
#[cfg(not(boringssl))]
1175+
fn point_hex_str() {
1176+
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
1177+
let key = EcKey::generate(&group).unwrap();
1178+
let point = key.public_key();
1179+
let mut ctx = BigNumContext::new().unwrap();
1180+
let hex = point
1181+
.to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx)
1182+
.unwrap();
1183+
let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap();
1184+
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
1185+
}
1186+
11241187
#[test]
11251188
fn point_owned() {
11261189
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();

0 commit comments

Comments
 (0)