Skip to content

Commit 91878f0

Browse files
committed
add EcPointRef::to_hex_str and EcPoint::from_hex_str
1 parent 50787ed commit 91878f0

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

openssl-sys/src/handwritten/ec.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,22 @@ extern "C" {
152152
ctx: *mut BN_CTX,
153153
) -> c_int;
154154

155+
#[cfg(not(boringssl))]
156+
pub fn EC_POINT_point2hex(
157+
group: *const EC_GROUP,
158+
p: *const EC_POINT,
159+
form: point_conversion_form_t,
160+
ctx: *mut BN_CTX,
161+
) -> *mut c_char;
162+
163+
#[cfg(not(boringssl))]
164+
pub fn EC_POINT_hex2point(
165+
group: *const EC_GROUP,
166+
s: *const c_char,
167+
p: *mut EC_POINT,
168+
ctx: *mut BN_CTX,
169+
) -> *mut EC_POINT;
170+
155171
pub fn EC_POINT_add(
156172
group: *const EC_GROUP,
157173
r: *mut EC_POINT,

openssl/src/ec.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
1818
use foreign_types::{ForeignType, ForeignTypeRef};
1919
use libc::c_int;
20+
use std::ffi::CString;
2021
use std::fmt;
2122
use std::ptr;
2223

2324
use crate::bn::{BigNum, BigNumContextRef, BigNumRef};
2425
use crate::error::ErrorStack;
2526
use crate::nid::Nid;
2627
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
28+
use crate::string::OpensslString;
2729
use crate::util::ForeignTypeRefExt;
2830
use crate::{cvt, cvt_n, cvt_p, init};
2931
use openssl_macros::corresponds;
@@ -463,6 +465,26 @@ impl EcPointRef {
463465
}
464466
}
465467

468+
/// Serializes the point to a hexadecimal string representation.
469+
#[corresponds(EC_POINT_point2hex)]
470+
#[cfg(not(boringssl))]
471+
pub fn to_hex_str(
472+
&self,
473+
group: &EcGroupRef,
474+
form: PointConversionForm,
475+
ctx: &mut BigNumContextRef,
476+
) -> Result<OpensslString, ErrorStack> {
477+
unsafe {
478+
let buf = cvt_p(ffi::EC_POINT_point2hex(
479+
group.as_ptr(),
480+
self.as_ptr(),
481+
form.0,
482+
ctx.as_ptr(),
483+
))?;
484+
Ok(OpensslString::from_ptr(buf))
485+
}
486+
}
487+
466488
/// Creates a new point on the specified curve with the same value.
467489
#[corresponds(EC_POINT_dup)]
468490
pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> {
@@ -631,6 +653,27 @@ impl EcPoint {
631653
}
632654
Ok(point)
633655
}
656+
657+
/// Creates point from a hexadecimal string representation
658+
#[corresponds(EC_POINT_hex2point)]
659+
#[cfg(not(boringssl))]
660+
pub fn from_hex_str(
661+
group: &EcGroupRef,
662+
s: &str,
663+
ctx: &mut BigNumContextRef,
664+
) -> Result<EcPoint, ErrorStack> {
665+
let point = EcPoint::new(group)?;
666+
unsafe {
667+
let c_str = CString::new(s.as_bytes()).unwrap();
668+
cvt_p(ffi::EC_POINT_hex2point(
669+
group.as_ptr(),
670+
c_str.as_ptr() as *const _,
671+
point.as_ptr(),
672+
ctx.as_ptr(),
673+
))?;
674+
}
675+
Ok(point)
676+
}
634677
}
635678

636679
generic_foreign_type_and_impl_send_sync! {
@@ -1121,6 +1164,20 @@ mod test {
11211164
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
11221165
}
11231166

1167+
#[test]
1168+
#[cfg(not(boringssl))]
1169+
fn point_hex_str() {
1170+
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
1171+
let key = EcKey::generate(&group).unwrap();
1172+
let point = key.public_key();
1173+
let mut ctx = BigNumContext::new().unwrap();
1174+
let hex = point
1175+
.to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx)
1176+
.unwrap();
1177+
let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap();
1178+
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
1179+
}
1180+
11241181
#[test]
11251182
fn point_owned() {
11261183
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();

0 commit comments

Comments
 (0)