15
15
//! [`EcGroup`]: struct.EcGroup.html
16
16
//! [`Nid`]: ../nid/struct.Nid.html
17
17
//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
18
+ use cfg_if:: cfg_if;
18
19
use foreign_types:: { ForeignType , ForeignTypeRef } ;
19
20
use libc:: c_int;
20
21
use std:: fmt;
@@ -28,6 +29,13 @@ use crate::util::ForeignTypeRefExt;
28
29
use crate :: { cvt, cvt_n, cvt_p, init} ;
29
30
use openssl_macros:: corresponds;
30
31
32
+ cfg_if ! {
33
+ if #[ cfg( not( boringssl) ) ] {
34
+ use std:: ffi:: CString ;
35
+ use crate :: string:: OpensslString ;
36
+ }
37
+ }
38
+
31
39
/// Compressed or Uncompressed conversion
32
40
///
33
41
/// Conversion from the binary value of the point on the curve is performed in one of
@@ -463,6 +471,26 @@ impl EcPointRef {
463
471
}
464
472
}
465
473
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
+
466
494
/// Creates a new point on the specified curve with the same value.
467
495
#[ corresponds( EC_POINT_dup ) ]
468
496
pub fn to_owned ( & self , group : & EcGroupRef ) -> Result < EcPoint , ErrorStack > {
@@ -631,6 +659,27 @@ impl EcPoint {
631
659
}
632
660
Ok ( point)
633
661
}
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
+ }
634
683
}
635
684
636
685
generic_foreign_type_and_impl_send_sync ! {
@@ -1121,6 +1170,20 @@ mod test {
1121
1170
assert ! ( point. eq( & group, & point2, & mut ctx) . unwrap( ) ) ;
1122
1171
}
1123
1172
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
+
1124
1187
#[ test]
1125
1188
fn point_owned ( ) {
1126
1189
let group = EcGroup :: from_curve_name ( Nid :: X9_62_PRIME256V1 ) . unwrap ( ) ;
0 commit comments