Commit 8f08d66d authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #674 from bradleybeddoes/add-ec-functions

Add elliptic curve functions
parents f34af836 c9665838
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1674,6 +1674,7 @@ extern "C" {
    pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int;
    pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int;
    pub fn EC_KEY_free(key: *mut EC_KEY);
    pub fn EC_KEY_set_public_key_affine_coordinates(key: *mut EC_KEY, x: *mut BIGNUM, y: *mut BIGNUM) -> c_int;

    #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
    pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
+1 −0
Original line number Diff line number Diff line
@@ -31,3 +31,4 @@ tempdir = "0.3"
winapi = "0.2"
ws2_32-sys = "0.2"
hex = "0.2"
data-encoding = "1.2"
+60 −1
Original line number Diff line number Diff line
@@ -459,12 +459,35 @@ impl EcKeyBuilderRef {
    pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
        unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) }
    }

    /// Sets the public key based on affine coordinates.
    pub fn set_public_key_affine_coordinates(&mut self,
                                             x: &BigNumRef,
                                             y: &BigNumRef)
                                             -> Result<&mut EcKeyBuilderRef, ErrorStack> {
        unsafe {
            cvt(ffi::EC_KEY_set_public_key_affine_coordinates(self.as_ptr(), 
	                                                      x.as_ptr(), 
							      y.as_ptr())
	    ).map(|_| self)
        }
    }

    /// Sets the private key.
    pub fn set_private_key(&mut self,
			   key: &BigNumRef)
			   -> Result<&mut EcKeyBuilderRef, ErrorStack> {
        unsafe {
            cvt(ffi::EC_KEY_set_private_key(self.as_ptr(), key.as_ptr())).map(|_| self)
        }
    }
}

#[cfg(test)]
mod test {
    use bn::BigNumContext;
    use bn::{BigNum, BigNumContext};
    use nid;
    use data_encoding;
    use super::*;

    #[test]
@@ -539,4 +562,40 @@ mod test {
        assert!(ec_key.public_key().is_some());
        assert!(ec_key.private_key().is_none());
    }

    #[test]
    fn key_from_affine_coordinates() {
        let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
        let x = data_encoding::base64url::decode_nopad("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes())
            .unwrap();
        let y = data_encoding::base64url::decode_nopad("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes())
            .unwrap();

        let xbn = BigNum::from_slice(&x).unwrap();
        let ybn = BigNum::from_slice(&y).unwrap();

        let mut builder = EcKeyBuilder::new().unwrap();
        builder.set_group(&group).unwrap();
        builder.set_public_key_affine_coordinates(&xbn, &ybn).unwrap();

        let ec_key = builder.build();
        assert!(ec_key.check_key().is_ok());
        assert!(ec_key.public_key().is_some());
    }

    #[test]
    fn set_private_key() {
        let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
        let d = data_encoding::base64url::decode_nopad("870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE".as_bytes())
            .unwrap();

        let dbn = BigNum::from_slice(&d).unwrap();

        let mut builder = EcKeyBuilder::new().unwrap();
        builder.set_group(&group).unwrap();
        builder.set_private_key(&dbn).unwrap();

        let ec_key = builder.build();
        assert!(ec_key.private_key().is_some());
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ extern crate openssl_sys as ffi;
extern crate hex;
#[cfg(test)]
extern crate tempdir;
#[cfg(test)]
extern crate data_encoding;

#[doc(inline)]
pub use ffi::init;