Add negation support

This commit is contained in:
Kohei Taniguchi 2020-02-07 13:31:43 +09:00
parent a5147bbf01
commit d45f709cd4
2 changed files with 58 additions and 0 deletions

View File

@ -243,6 +243,14 @@ extern "C" {
//TODO secp256k1_ec_privkey_export //TODO secp256k1_ec_privkey_export
//TODO secp256k1_ec_privkey_import //TODO secp256k1_ec_privkey_import
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_1_1_ec_privkey_negate")]
pub fn secp256k1_ec_privkey_negate(cx: *const Context,
sk: *mut c_uchar) -> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_1_1_ec_pubkey_negate")]
pub fn secp256k1_ec_pubkey_negate(cx: *const Context,
pk: *mut PublicKey) -> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_1_1_ec_privkey_tweak_add")] #[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_1_1_ec_privkey_tweak_add")]
pub fn secp256k1_ec_privkey_tweak_add(cx: *const Context, pub fn secp256k1_ec_privkey_tweak_add(cx: *const Context,
sk: *mut c_uchar, sk: *mut c_uchar,

View File

@ -148,6 +148,19 @@ impl SecretKey {
} }
} }
#[inline]
/// Negates one secret key.
pub fn negate_assign(
&mut self
) {
unsafe {
ffi::secp256k1_ec_privkey_negate(
ffi::secp256k1_context_no_precomp,
self.as_mut_c_ptr()
);
}
}
#[inline] #[inline]
/// Adds one secret key to another, modulo the curve order. WIll /// Adds one secret key to another, modulo the curve order. WIll
/// return an error if the resulting key would be invalid or if /// return an error if the resulting key would be invalid or if
@ -291,6 +304,22 @@ impl PublicKey {
ret ret
} }
#[inline]
/// Negates the pk to the pk `self` in place
/// Will return an error if the pk would be invalid.
pub fn negate_assign<C: Verification>(
&mut self,
secp: &Secp256k1<C>
) -> Result<(), Error> {
unsafe {
if ffi::secp256k1_ec_pubkey_negate(secp.ctx, &mut self.0 as *mut _) == 1 {
Ok(())
} else {
Err(Error::InvalidPublicKey)
}
}
}
#[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
/// Will return an error if the resulting key would be invalid or /// Will return an error if the resulting key would be invalid or
@ -752,6 +781,27 @@ mod test {
assert_eq!(PublicKey::from_secret_key(&s, &sk2), pk2); assert_eq!(PublicKey::from_secret_key(&s, &sk2), pk2);
} }
#[test]
fn test_negation() {
let s = Secp256k1::new();
let (mut sk, mut pk) = s.generate_keypair(&mut thread_rng());
let original_sk = sk;
let original_pk = pk;
assert_eq!(PublicKey::from_secret_key(&s, &sk), pk);
sk.negate_assign();
assert!(pk.negate_assign(&s).is_ok());
assert_ne!(original_sk, sk);
assert_ne!(original_pk, pk);
sk.negate_assign();
assert!(pk.negate_assign(&s).is_ok());
assert_eq!(original_sk, sk);
assert_eq!(original_pk, pk);
assert_eq!(PublicKey::from_secret_key(&s, &sk), pk);
}
#[test] #[test]
fn pubkey_hash() { fn pubkey_hash() {
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;