X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Fc_types%2Fmod.rs;h=6267b80bc2dd007ba9476f76d01127d2b9a74937;hp=cd96dffe1969bbe6c845fcfa0ff2ec73e64dff4a;hb=d3d51441b4cd98389308d4cfaba6548f25598c4c;hpb=5eebd45b471833805e81ad4c23ec93d7711e0a23 diff --git a/lightning-c-bindings/src/c_types/mod.rs b/lightning-c-bindings/src/c_types/mod.rs index cd96dff..6267b80 100644 --- a/lightning-c-bindings/src/c_types/mod.rs +++ b/lightning-c-bindings/src/c_types/mod.rs @@ -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 { @@ -354,11 +382,27 @@ impl Into for &'static str { Str { chars: self.as_ptr(), len: self.len(), chars_is_owned: false } } } -impl Into<&'static str> for Str { - fn into(self) -> &'static str { +impl Str { + pub(crate) fn into_str(&self) -> &'static str { if self.len == 0 { return ""; } std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap() } + pub(crate) fn into_string(mut self) -> String { + let bytes = if self.len == 0 { + Vec::new() + } else if self.chars_is_owned { + let ret = unsafe { + Box::from_raw(std::slice::from_raw_parts_mut(unsafe { self.chars as *mut u8 }, self.len)) + }.into(); + self.chars_is_owned = false; + ret + } else { + let mut ret = Vec::with_capacity(self.len); + ret.extend_from_slice(unsafe { std::slice::from_raw_parts(self.chars, self.len) }); + ret + }; + String::from_utf8(bytes).unwrap() + } } impl Into for String { fn into(self) -> Str {