Global secp256k1 context
This commit is contained in:
parent
6dca77434f
commit
1e8dd6321f
@ -8,6 +8,10 @@ pub type Secret = H256;
|
|||||||
pub type Public = H512;
|
pub type Public = H512;
|
||||||
pub type Signature = H520;
|
pub type Signature = H520;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref SECP256K1: Secp256k1 = Secp256k1::new();
|
||||||
|
}
|
||||||
|
|
||||||
impl Signature {
|
impl Signature {
|
||||||
/// Create a new signature from the R, S and V componenets.
|
/// Create a new signature from the R, S and V componenets.
|
||||||
pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Signature {
|
pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Signature {
|
||||||
@ -82,10 +86,10 @@ pub struct KeyPair {
|
|||||||
impl KeyPair {
|
impl KeyPair {
|
||||||
/// Create a pair from secret key
|
/// Create a pair from secret key
|
||||||
pub fn from_secret(secret: Secret) -> Result<KeyPair, CryptoError> {
|
pub fn from_secret(secret: Secret) -> Result<KeyPair, CryptoError> {
|
||||||
let context = Secp256k1::new();
|
let context = &SECP256K1;
|
||||||
let s: key::SecretKey = try!(key::SecretKey::from_slice(&context, &secret));
|
let s: key::SecretKey = try!(key::SecretKey::from_slice(context, &secret));
|
||||||
let pub_key = try!(key::PublicKey::from_secret_key(&context, &s));
|
let pub_key = try!(key::PublicKey::from_secret_key(context, &s));
|
||||||
let serialized = pub_key.serialize_vec(&context, false);
|
let serialized = pub_key.serialize_vec(context, false);
|
||||||
let p: Public = Public::from_slice(&serialized[1..65]);
|
let p: Public = Public::from_slice(&serialized[1..65]);
|
||||||
Ok(KeyPair {
|
Ok(KeyPair {
|
||||||
secret: secret,
|
secret: secret,
|
||||||
@ -94,10 +98,10 @@ impl KeyPair {
|
|||||||
}
|
}
|
||||||
/// Create a new random key pair
|
/// Create a new random key pair
|
||||||
pub fn create() -> Result<KeyPair, CryptoError> {
|
pub fn create() -> Result<KeyPair, CryptoError> {
|
||||||
let context = Secp256k1::new();
|
let context = &SECP256K1;
|
||||||
let mut rng = try!(OsRng::new());
|
let mut rng = try!(OsRng::new());
|
||||||
let (sec, publ) = try!(context.generate_keypair(&mut rng));
|
let (sec, publ) = try!(context.generate_keypair(&mut rng));
|
||||||
let serialized = publ.serialize_vec(&context, false);
|
let serialized = publ.serialize_vec(context, false);
|
||||||
let p: Public = Public::from_slice(&serialized[1..65]);
|
let p: Public = Public::from_slice(&serialized[1..65]);
|
||||||
let s: Secret = unsafe { ::std::mem::transmute(sec) };
|
let s: Secret = unsafe { ::std::mem::transmute(sec) };
|
||||||
Ok(KeyPair {
|
Ok(KeyPair {
|
||||||
@ -128,10 +132,10 @@ pub mod ec {
|
|||||||
/// Recovers Public key from signed message hash.
|
/// Recovers Public key from signed message hash.
|
||||||
pub fn recover(signature: &Signature, message: &H256) -> Result<Public, CryptoError> {
|
pub fn recover(signature: &Signature, message: &H256) -> Result<Public, CryptoError> {
|
||||||
use secp256k1::*;
|
use secp256k1::*;
|
||||||
let context = Secp256k1::new();
|
let context = &crypto::SECP256K1;
|
||||||
let rsig = try!(RecoverableSignature::from_compact(&context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
||||||
let publ = try!(context.recover(&try!(Message::from_slice(&message)), &rsig));
|
let publ = try!(context.recover(&try!(Message::from_slice(&message)), &rsig));
|
||||||
let serialized = publ.serialize_vec(&context, false);
|
let serialized = publ.serialize_vec(context, false);
|
||||||
let p: Public = Public::from_slice(&serialized[1..65]);
|
let p: Public = Public::from_slice(&serialized[1..65]);
|
||||||
//TODO: check if it's the zero key and fail if so.
|
//TODO: check if it's the zero key and fail if so.
|
||||||
Ok(p)
|
Ok(p)
|
||||||
@ -140,10 +144,10 @@ pub mod ec {
|
|||||||
pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> {
|
pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> {
|
||||||
// TODO: allow creation of only low-s signatures.
|
// TODO: allow creation of only low-s signatures.
|
||||||
use secp256k1::*;
|
use secp256k1::*;
|
||||||
let context = Secp256k1::new();
|
let context = &crypto::SECP256K1;
|
||||||
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
|
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
|
||||||
let s = try!(context.sign_recoverable(&try!(Message::from_slice(&message)), sec));
|
let s = try!(context.sign_recoverable(&try!(Message::from_slice(&message)), sec));
|
||||||
let (rec_id, data) = s.serialize_compact(&context);
|
let (rec_id, data) = s.serialize_compact(context);
|
||||||
let mut signature: crypto::Signature = unsafe { ::std::mem::uninitialized() };
|
let mut signature: crypto::Signature = unsafe { ::std::mem::uninitialized() };
|
||||||
signature.clone_from_slice(&data);
|
signature.clone_from_slice(&data);
|
||||||
signature[64] = rec_id.to_i32() as u8;
|
signature[64] = rec_id.to_i32() as u8;
|
||||||
@ -152,15 +156,15 @@ pub mod ec {
|
|||||||
/// Verify signature.
|
/// Verify signature.
|
||||||
pub fn verify(public: &Public, signature: &Signature, message: &H256) -> Result<bool, CryptoError> {
|
pub fn verify(public: &Public, signature: &Signature, message: &H256) -> Result<bool, CryptoError> {
|
||||||
use secp256k1::*;
|
use secp256k1::*;
|
||||||
let context = Secp256k1::new();
|
let context = &crypto::SECP256K1;
|
||||||
let rsig = try!(RecoverableSignature::from_compact(&context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
||||||
let sig = rsig.to_standard(&context);
|
let sig = rsig.to_standard(context);
|
||||||
|
|
||||||
let mut pdata: [u8; 65] = [4u8; 65];
|
let mut pdata: [u8; 65] = [4u8; 65];
|
||||||
let ptr = pdata[1..].as_mut_ptr();
|
let ptr = pdata[1..].as_mut_ptr();
|
||||||
let src = public.as_ptr();
|
let src = public.as_ptr();
|
||||||
unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) };
|
unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) };
|
||||||
let publ = try!(key::PublicKey::from_slice(&context, &pdata));
|
let publ = try!(key::PublicKey::from_slice(context, &pdata));
|
||||||
match context.verify(&try!(Message::from_slice(&message)), &sig, &publ) {
|
match context.verify(&try!(Message::from_slice(&message)), &sig, &publ) {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(Error::IncorrectSignature) => Ok(false),
|
Err(Error::IncorrectSignature) => Ok(false),
|
||||||
@ -190,17 +194,18 @@ pub mod ec {
|
|||||||
|
|
||||||
pub mod ecdh {
|
pub mod ecdh {
|
||||||
use crypto::*;
|
use crypto::*;
|
||||||
|
use crypto::{self};
|
||||||
|
|
||||||
pub fn agree(secret: &Secret, public: &Public, ) -> Result<Secret, CryptoError> {
|
pub fn agree(secret: &Secret, public: &Public, ) -> Result<Secret, CryptoError> {
|
||||||
use secp256k1::*;
|
use secp256k1::*;
|
||||||
let context = Secp256k1::new();
|
let context = &crypto::SECP256K1;
|
||||||
let mut pdata: [u8; 65] = [4u8; 65];
|
let mut pdata: [u8; 65] = [4u8; 65];
|
||||||
let ptr = pdata[1..].as_mut_ptr();
|
let ptr = pdata[1..].as_mut_ptr();
|
||||||
let src = public.as_ptr();
|
let src = public.as_ptr();
|
||||||
unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) };
|
unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) };
|
||||||
let publ = try!(key::PublicKey::from_slice(&context, &pdata));
|
let publ = try!(key::PublicKey::from_slice(context, &pdata));
|
||||||
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
|
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
|
||||||
let shared = ecdh::SharedSecret::new_raw(&context, &publ, &sec);
|
let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec);
|
||||||
let s: Secret = unsafe { ::std::mem::transmute(shared) };
|
let s: Secret = unsafe { ::std::mem::transmute(shared) };
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user