Remove error return from `PublicKey::from_secret_key()`

Make sure that you cannot create an invalid `SecretKey` in the first place.
Unbreaks the API.

[unbreaking-change]
This commit is contained in:
Andrew Poelstra 2014-08-28 11:11:25 -07:00
parent a67260eb3a
commit 15b8183ea8
2 changed files with 18 additions and 17 deletions

View File

@ -76,6 +76,12 @@ impl SecretKey {
/// Creates a new random secret key /// Creates a new random secret key
#[inline] #[inline]
pub fn new<R:Rng>(rng: &mut R) -> SecretKey { pub fn new<R:Rng>(rng: &mut R) -> SecretKey {
let mut data = random_32_bytes(rng);
unsafe {
while ffi::secp256k1_ecdsa_seckey_verify(data.as_ptr()) == 0 {
data = random_32_bytes(rng);
}
}
SecretKey(random_32_bytes(rng)) SecretKey(random_32_bytes(rng))
} }
@ -129,21 +135,21 @@ 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(sk: &SecretKey, compressed: bool) -> Result<PublicKey> { pub 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};
let mut len = 0; let mut len = 0;
init(); init();
unsafe { unsafe {
if ffi::secp256k1_ecdsa_pubkey_create( // We can assume the return value because it's not possible to construct
// an invalid `SecretKey` without transmute trickery or something
assert_eq!(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);
return Err(InvalidSecretKey);
}
} }
assert_eq!(len as uint, pk.len()); assert_eq!(len as uint, pk.len());
Ok(pk) pk
} }
/// Creates a public key directly from a slice /// Creates a public key directly from a slice
@ -363,15 +369,15 @@ mod test {
let (mut sk1, mut pk1) = s.generate_keypair(true).unwrap(); let (mut sk1, mut pk1) = s.generate_keypair(true).unwrap();
let (mut sk2, mut pk2) = s.generate_keypair(true).unwrap(); let (mut sk2, mut pk2) = s.generate_keypair(true).unwrap();
assert_eq!(PublicKey::from_secret_key(&sk1, true), Ok(pk1)); assert_eq!(PublicKey::from_secret_key(&sk1, true), pk1);
assert!(sk1.add_assign(&sk2).is_ok()); assert!(sk1.add_assign(&sk2).is_ok());
assert!(pk1.add_exp_assign(&sk2).is_ok()); assert!(pk1.add_exp_assign(&sk2).is_ok());
assert_eq!(PublicKey::from_secret_key(&sk1, true), Ok(pk1)); assert_eq!(PublicKey::from_secret_key(&sk1, true), pk1);
assert_eq!(PublicKey::from_secret_key(&sk2, true), Ok(pk2)); assert_eq!(PublicKey::from_secret_key(&sk2, true), pk2);
assert!(sk2.add_assign(&sk1).is_ok()); assert!(sk2.add_assign(&sk1).is_ok());
assert!(pk2.add_exp_assign(&sk1).is_ok()); assert!(pk2.add_exp_assign(&sk1).is_ok());
assert_eq!(PublicKey::from_secret_key(&sk2, true), Ok(pk2)); assert_eq!(PublicKey::from_secret_key(&sk2, true), pk2);
} }
} }

View File

@ -136,13 +136,8 @@ impl Secp256k1 {
-> Result<(key::SecretKey, key::PublicKey)> { -> Result<(key::SecretKey, key::PublicKey)> {
match self.rng { match self.rng {
Ok(ref mut rng) => { Ok(ref mut rng) => {
let mut sk = key::SecretKey::new(rng); let sk = key::SecretKey::new(rng);
let mut pk = key::PublicKey::from_secret_key(&sk, compressed); Ok((sk, key::PublicKey::from_secret_key(&sk, compressed)))
while pk.is_err() {
sk = key::SecretKey::new(rng);
pk = key::PublicKey::from_secret_key(&sk, compressed);
}
Ok((sk, pk.unwrap()))
} }
Err(ref e) => Err(RngError(e.clone())) Err(ref e) => Err(RngError(e.clone()))
} }