Support secp256k1 RecoverableSignatures
[ldk-c-bindings] / lightning-c-bindings / src / c_types / mod.rs
index cd96dffe1969bbe6c845fcfa0ff2ec73e64dff4a..b28bc80fd264f8ea232723adabc07614a1525b6c 100644 (file)
@@ -9,6 +9,8 @@ use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
 use bitcoin::secp256k1::Signature as SecpSignature;
 use bitcoin::secp256k1::Error as SecpError;
+use bitcoin::secp256k1::recovery::RecoveryId;
+use bitcoin::secp256k1::recovery::RecoverableSignature as SecpRecoverableSignature;
 use bitcoin::bech32;
 
 use std::convert::TryInto; // Bindings need at least rustc 1.34
@@ -85,6 +87,32 @@ impl Signature {
        #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
 }
 
+#[repr(C)]
+#[derive(Clone)]
+/// Represents a secp256k1 signature serialized as two 32-byte numbers as well as a tag which
+/// allows recovering the exact public key which created the signature given the message.
+pub struct RecoverableSignature {
+       /// The bytes of the signature in "compact" form plus a "Recovery ID" which allows for
+       /// recovery.
+       pub serialized_form: [u8; 68],
+}
+impl RecoverableSignature {
+       pub(crate) fn from_rust(pk: &SecpRecoverableSignature) -> Self {
+               let (id, compact_form) = pk.serialize_compact();
+               let mut serialized_form = [0; 68];
+               serialized_form[0..64].copy_from_slice(&compact_form[..]);
+               serialized_form[64..].copy_from_slice(&id.to_i32().to_le_bytes());
+               Self { serialized_form }
+       }
+       pub(crate) fn into_rust(&self) -> SecpRecoverableSignature {
+               let mut id = [0; 4];
+               id.copy_from_slice(&self.serialized_form[64..]);
+               SecpRecoverableSignature::from_compact(&self.serialized_form[0..64],
+                               RecoveryId::from_i32(i32::from_le_bytes(id)).expect("Invalid Recovery ID"))
+                       .unwrap()
+       }
+}
+
 #[repr(C)]
 /// Represents an error returned from libsecp256k1 during validation of some secp256k1 data
 pub enum Secp256k1Error {