Add `Secp256k1::with_rng`, parameterize `Secp256k1` over its RNG.
Now that you can't create secret keys by directly passing a Rng to `SecretKey::new`, we need a way to allow user-chosed randomness. We add it to the `Secp256k1`.
This commit is contained in:
parent
e52faee98f
commit
9e717d4219
23
src/key.rs
23
src/key.rs
|
@ -55,7 +55,7 @@ fn random_32_bytes<R:Rng>(rng: &mut R) -> [u8; 32] {
|
||||||
impl SecretKey {
|
impl SecretKey {
|
||||||
/// Creates a new random secret key
|
/// Creates a new random secret key
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(secp: &mut Secp256k1) -> SecretKey {
|
pub fn new<R: Rng>(secp: &mut Secp256k1<R>) -> SecretKey {
|
||||||
let mut data = random_32_bytes(&mut secp.rng);
|
let mut data = random_32_bytes(&mut secp.rng);
|
||||||
unsafe {
|
unsafe {
|
||||||
while ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 {
|
while ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 {
|
||||||
|
@ -67,7 +67,8 @@ impl SecretKey {
|
||||||
|
|
||||||
/// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key
|
/// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(secp: &Secp256k1, data: &[u8]) -> Result<SecretKey, Error> {
|
pub fn from_slice<R: Rng>(secp: &Secp256k1<R>, data: &[u8])
|
||||||
|
-> Result<SecretKey, Error> {
|
||||||
match data.len() {
|
match data.len() {
|
||||||
constants::SECRET_KEY_SIZE => {
|
constants::SECRET_KEY_SIZE => {
|
||||||
let mut ret = [0; constants::SECRET_KEY_SIZE];
|
let mut ret = [0; constants::SECRET_KEY_SIZE];
|
||||||
|
@ -87,7 +88,10 @@ impl SecretKey {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Adds one secret key to another, modulo the curve order
|
/// Adds one secret key to another, modulo the curve order
|
||||||
pub fn add_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> {
|
pub fn add_assign<R: Rng>(&mut self,
|
||||||
|
secp: &Secp256k1<R>,
|
||||||
|
other: &SecretKey)
|
||||||
|
-> Result<(), Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if ffi::secp256k1_ec_privkey_tweak_add(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 {
|
if ffi::secp256k1_ec_privkey_tweak_add(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 {
|
||||||
Err(Unknown)
|
Err(Unknown)
|
||||||
|
@ -113,7 +117,10 @@ impl PublicKey {
|
||||||
|
|
||||||
/// Creates a new public key from a secret key.
|
/// Creates a new public key from a secret key.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_secret_key(secp: &Secp256k1, sk: &SecretKey, compressed: bool) -> PublicKey {
|
pub fn from_secret_key<R: Rng>(secp: &Secp256k1<R>,
|
||||||
|
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};
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
|
@ -132,7 +139,8 @@ impl PublicKey {
|
||||||
|
|
||||||
/// Creates a public key directly from a slice
|
/// Creates a public key directly from a slice
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(secp: &Secp256k1, data: &[u8]) -> Result<PublicKey, Error> {
|
pub fn from_slice<R: Rng>(secp: &Secp256k1<R>, data: &[u8])
|
||||||
|
-> Result<PublicKey, Error> {
|
||||||
match data.len() {
|
match data.len() {
|
||||||
constants::COMPRESSED_PUBLIC_KEY_SIZE => {
|
constants::COMPRESSED_PUBLIC_KEY_SIZE => {
|
||||||
let mut ret = [0; constants::COMPRESSED_PUBLIC_KEY_SIZE];
|
let mut ret = [0; constants::COMPRESSED_PUBLIC_KEY_SIZE];
|
||||||
|
@ -204,7 +212,10 @@ impl PublicKey {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Adds the pk corresponding to `other` to the pk `self` in place
|
/// Adds the pk corresponding to `other` to the pk `self` in place
|
||||||
pub fn add_exp_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> {
|
pub fn add_exp_assign<R: Rng>(&mut self,
|
||||||
|
secp: &Secp256k1<R>,
|
||||||
|
other: &SecretKey)
|
||||||
|
-> Result<(), Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, self.as_mut_ptr(),
|
if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, self.as_mut_ptr(),
|
||||||
self.len() as ::libc::c_int,
|
self.len() as ::libc::c_int,
|
||||||
|
|
29
src/lib.rs
29
src/lib.rs
|
@ -212,28 +212,37 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The secp256k1 engine, used to execute all signature operations
|
/// The secp256k1 engine, used to execute all signature operations
|
||||||
pub struct Secp256k1 {
|
pub struct Secp256k1<R: Rng = Fortuna> {
|
||||||
ctx: ffi::Context,
|
ctx: ffi::Context,
|
||||||
rng: Fortuna
|
rng: R
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Secp256k1 {
|
impl<R: Rng> Drop for Secp256k1<R> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { ffi::secp256k1_context_destroy(self.ctx); }
|
unsafe { ffi::secp256k1_context_destroy(self.ctx); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Secp256k1 {
|
impl Secp256k1<Fortuna> {
|
||||||
/// Constructs a new secp256k1 engine.
|
/// Constructs a new secp256k1 engine with the default key-generation Rng
|
||||||
pub fn new() -> io::Result<Secp256k1> {
|
/// (a Fortuna seeded with randomness from the OS during `new`)
|
||||||
|
pub fn new() -> io::Result<Secp256k1<Fortuna>> {
|
||||||
|
let mut osrng = try!(OsRng::new());
|
||||||
|
let mut seed = [0; 2048];
|
||||||
|
osrng.fill_bytes(&mut seed);
|
||||||
|
let rng: Fortuna = SeedableRng::from_seed(&seed[..]);
|
||||||
|
Secp256k1::with_rng(rng)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Rng> Secp256k1<R> {
|
||||||
|
/// Constructs a new secp256k1 engine with its key-generation RNG specified
|
||||||
|
pub fn with_rng(rng: R) -> io::Result<Secp256k1<R>> {
|
||||||
let ctx = unsafe {
|
let ctx = unsafe {
|
||||||
ffi::secp256k1_context_create(ffi::SECP256K1_START_VERIFY |
|
ffi::secp256k1_context_create(ffi::SECP256K1_START_VERIFY |
|
||||||
ffi::SECP256K1_START_SIGN)
|
ffi::SECP256K1_START_SIGN)
|
||||||
};
|
};
|
||||||
let mut osrng = try!(OsRng::new());
|
Ok(Secp256k1 { ctx: ctx, rng: rng })
|
||||||
let mut seed = [0; 2048];
|
|
||||||
osrng.fill_bytes(&mut seed);
|
|
||||||
Ok(Secp256k1 { ctx: ctx, rng: SeedableRng::from_seed(&seed[..]) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
|
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
|
||||||
|
|
Loading…
Reference in New Issue