add EcKey creation from EcPoint, public_key

This commit is contained in:
Benjamin Fry 2016-12-31 10:40:56 -08:00
parent 283036c5ad
commit 444c00955a
1 changed files with 47 additions and 0 deletions

View File

@ -289,6 +289,38 @@ impl EcKey {
}
}
/// Constructs an `EcKey` from the specified group with the associated `EcPoint`, public_key.
///
/// This will only have the associated public_key.
///
/// # Example
///
/// ```
/// use openssl::bn::BigNumContext;
/// use openssl::ec::*;
/// use openssl::nid;
/// use openssl::pkey::PKey;
///
/// // get bytes from somewhere, i.e. this will not produce a valid key
/// let public_key: Vec<u8> = vec![];
///
/// // create a PKey from the binary form of a EcPoint
/// EcGroup::from_curve_name(nid::SECP256K1)
/// .and_then(|group| BigNumContext::new().map(|ctx| (group, ctx)))
/// .and_then(|(group, mut ctx)| EcPoint::from_bytes(&group, &public_key, &mut ctx)
/// .map(|point| (group, point) ))
/// .and_then(|(group, point)| EcKey::from_public_key(&group, &point))
/// .and_then(|ec_key| PKey::from_ec_key(ec_key));
/// ```
pub fn from_public_key(group: &EcGroupRef, public_key: &EcPointRef) -> Result<EcKey, ErrorStack> {
unsafe {
let key = EcKey(try!(cvt_p(ffi::EC_KEY_new())));
try!(cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())));
try!(cvt(ffi::EC_KEY_set_public_key(key.as_ptr(), public_key.as_ptr())));
Ok(key)
}
}
/// Generates a new public/private key pair on the specified curve.
pub fn generate(group: &EcGroupRef) -> Result<EcKey, ErrorStack> {
unsafe {
@ -353,4 +385,19 @@ mod test {
public_key.mul_generator(&group, key.private_key().unwrap(), &mut ctx).unwrap();
assert!(public_key.eq(&group, key.public_key().unwrap(), &mut ctx).unwrap());
}
#[test]
fn key_from_public_key() {
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let bytes = key.public_key().unwrap().to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx).unwrap();
drop(key);
let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
let ec_key = EcKey::from_public_key(&group, &public_key).unwrap();
assert!(ec_key.check_key().is_ok());
assert!(ec_key.public_key().is_some());
assert!(ec_key.private_key().is_none());
}
}