Pull out initialization code so that `PublicKey::from_secret_key` can be used safely
This commit is contained in:
parent
522bafe433
commit
d6bf4039bd
25
src/key.rs
25
src/key.rs
|
@ -7,6 +7,7 @@ use constants;
|
||||||
use ffi;
|
use ffi;
|
||||||
|
|
||||||
use super::{Result, InvalidNonce, InvalidPublicKey, InvalidSecretKey};
|
use super::{Result, InvalidNonce, InvalidPublicKey, InvalidSecretKey};
|
||||||
|
use super::init;
|
||||||
|
|
||||||
/// Secret 256-bit nonce used as `k` in an ECDSA signature
|
/// Secret 256-bit nonce used as `k` in an ECDSA signature
|
||||||
pub struct Nonce([u8, ..constants::NONCE_SIZE]);
|
pub struct Nonce([u8, ..constants::NONCE_SIZE]);
|
||||||
|
@ -124,20 +125,22 @@ impl PublicKey {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new public key from a secret key
|
/// Creates a new public key from a secret key. Marked `unsafe` since you must
|
||||||
|
/// call `init()` (or construct a `Secp256k1`, which does this for you) before
|
||||||
|
/// using this function
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_secret_key(sk: &SecretKey, compressed: bool) -> PublicKey {
|
pub unsafe fn from_secret_key(sk: &SecretKey, compressed: bool) -> PublicKey {
|
||||||
let mut pk = PublicKey::new(compressed);
|
let mut pk = PublicKey::new(compressed);
|
||||||
let compressed = if compressed {1} else {0};
|
let compressed = if compressed {1} else {0};
|
||||||
unsafe {
|
let mut len = 0;
|
||||||
let mut len = 0;
|
|
||||||
while ffi::secp256k1_ecdsa_pubkey_create(
|
while ffi::secp256k1_ecdsa_pubkey_create(
|
||||||
pk.as_mut_ptr(), &mut len,
|
pk.as_mut_ptr(), &mut len,
|
||||||
sk.as_ptr(), compressed) != 1 {
|
sk.as_ptr(), compressed) != 1 {
|
||||||
// loop
|
// loop
|
||||||
}
|
}
|
||||||
assert_eq!(len as uint, pk.len());
|
assert_eq!(len as uint, pk.len());
|
||||||
};
|
|
||||||
pk
|
pk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
|
||||||
use std::io::IoError;
|
use std::io::{IoError, IoResult};
|
||||||
use std::rand::OsRng;
|
use std::rand::OsRng;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use sync::one::{Once, ONCE_INIT};
|
use sync::one::{Once, ONCE_INIT};
|
||||||
|
@ -84,28 +84,40 @@ pub struct Secp256k1 {
|
||||||
rng: OsRng
|
rng: OsRng
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Does one-time initialization of the secp256k1 engine. Can be called
|
||||||
|
/// multiple times, and is called by the `Secp256k1` constructor. This
|
||||||
|
/// only needs to be called directly if you are using the library without
|
||||||
|
/// a `Secp256k1` object, e.g. batch key generation through
|
||||||
|
/// `key::PublicKey::from_secret_key`.
|
||||||
|
pub fn init() {
|
||||||
|
unsafe {
|
||||||
|
Secp256k1_init.doit(|| {
|
||||||
|
ffi::secp256k1_start();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Secp256k1 {
|
impl Secp256k1 {
|
||||||
/// Constructs a new secp256k1 engine.
|
/// Constructs a new secp256k1 engine.
|
||||||
pub fn new() -> Result<Secp256k1> {
|
pub fn new() -> Result<Secp256k1> {
|
||||||
unsafe {
|
init();
|
||||||
Secp256k1_init.doit(|| {
|
|
||||||
ffi::secp256k1_start();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
match OsRng::new() {
|
match OsRng::new() {
|
||||||
Ok(rng) => Ok(Secp256k1 { rng: rng }),
|
Ok(rng) => Ok(Secp256k1 { rng: rng }),
|
||||||
Err(e) => Err(RngError(e))
|
Err(e) => Err(RngError(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a randam keypair
|
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
|
||||||
|
/// and `key::PublicKey::from_secret_key`; call those functions directly for
|
||||||
|
/// batch key generation.
|
||||||
pub fn generate_keypair(&mut self, compressed: bool)
|
pub fn generate_keypair(&mut self, compressed: bool)
|
||||||
-> (key::SecretKey, key::PublicKey) {
|
-> (key::SecretKey, key::PublicKey) {
|
||||||
let sk = key::SecretKey::new(&mut self.rng);
|
let sk = key::SecretKey::new(&mut self.rng);
|
||||||
(sk, key::PublicKey::from_secret_key(&sk, compressed))
|
unsafe { (sk, key::PublicKey::from_secret_key(&sk, compressed)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a random nonce
|
/// Generates a random nonce. Convenience function for `key::Nonce::new`; call
|
||||||
|
/// that function directly for batch nonce generation
|
||||||
pub fn generate_nonce(&mut self) -> key::Nonce {
|
pub fn generate_nonce(&mut self) -> key::Nonce {
|
||||||
key::Nonce::new(&mut self.rng)
|
key::Nonce::new(&mut self.rng)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue