Skip to content

Commit 117af52

Browse files
nymiusantonilol
andcommitted
feat(silentpayments): add receiving support
Co-authored-by: Antoni Spaanderman <[email protected]>
1 parent d0a51bb commit 117af52

File tree

3 files changed

+432
-1
lines changed

3 files changed

+432
-1
lines changed

secp256k1-sys/src/lib.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,101 @@ pub mod silentpayments {
962962
unlabeled_spend_pubkey: *const PublicKey,
963963
label: *const PublicKey,
964964
) -> c_int;
965+
966+
#[cfg_attr(
967+
not(rust_secp_no_symbol_renaming),
968+
link_name = "rustsecp256k1_v0_13_silentpayments_recipient_prevouts_summary_create"
969+
)]
970+
pub fn secp256k1_silentpayments_recipient_prevouts_summary_create(
971+
ctx: *const Context,
972+
prevouts_summary: *mut PrevoutsSummary,
973+
outpoint_smallest36: *const c_uchar,
974+
xonly_pubkeys: *const *const XOnlyPublicKey,
975+
n_xonly_pubkeys: size_t,
976+
plain_pubkeys: *const *const PublicKey,
977+
n_plain_pubkeys: size_t,
978+
) -> c_int;
979+
980+
#[cfg_attr(
981+
not(rust_secp_no_symbol_renaming),
982+
link_name = "rustsecp256k1_v0_13_silentpayments_recipient_scan_outputs"
983+
)]
984+
pub fn secp256k1_silentpayments_recipient_scan_outputs(
985+
ctx: *const Context,
986+
found_outputs: *mut *mut FoundOutput,
987+
n_found_outputs: *mut size_t,
988+
tx_outputs: *const *const XOnlyPublicKey,
989+
n_tx_outputs: size_t,
990+
scan_key32: *const c_uchar,
991+
prevouts_summary: *const PrevoutsSummary,
992+
unlabeled_spend_pubkey: *const PublicKey,
993+
label_lookup: LabelLookup,
994+
label_context: *const c_void,
995+
) -> c_int;
996+
997+
#[cfg_attr(
998+
not(rust_secp_no_symbol_renaming),
999+
link_name = "rustsecp256k1_v0_13_silentpayments_recipient_create_output_pubkeys"
1000+
)]
1001+
pub fn secp256k1_silentpayments_recipient_create_output_pubkeys(
1002+
ctx: *const Context,
1003+
outputs_xonly: *mut *mut XOnlyPublicKey,
1004+
scan_key32: *const c_uchar,
1005+
prevouts_summary: *const PrevoutsSummary,
1006+
spend_pubkeys: *const *mut PublicKey,
1007+
n_spend_pubkeys: size_t,
1008+
) -> c_int;
1009+
}
1010+
1011+
#[repr(C)]
1012+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1013+
pub struct FoundOutput {
1014+
pub output: XOnlyPublicKey,
1015+
pub tweak: [c_uchar; 32],
1016+
pub found_with_label: c_int,
1017+
pub label: PublicKey,
1018+
}
1019+
1020+
impl Default for FoundOutput {
1021+
fn default() -> Self {
1022+
Self {
1023+
output: unsafe { XOnlyPublicKey::new() },
1024+
tweak: [0u8; 32],
1025+
found_with_label: 0i32,
1026+
label: unsafe { PublicKey::new() },
1027+
}
1028+
}
1029+
}
1030+
1031+
#[repr(C)]
1032+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1033+
pub struct PrevoutsSummary {
1034+
data: [u8; 101],
1035+
}
1036+
1037+
impl PrevoutsSummary {
1038+
pub fn from_array(arr: [u8; 101]) -> Self { Self { data: arr } }
1039+
pub fn to_array(self) -> [u8; 101] { self.data }
1040+
}
1041+
1042+
impl core::fmt::Debug for PrevoutsSummary {
1043+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1044+
write!(f, "magic: {{")?;
1045+
for magic_byte in &self.data[..3] {
1046+
write!(f, "0x{magic_byte:02x}, ")?;
1047+
}
1048+
writeln!(f, "0x{:02x}}}", &self.data[3])?;
1049+
write!(f, "x: 0x")?;
1050+
for x_byte in &self.data[4..36] {
1051+
write!(f, "{x_byte:02x}")?;
1052+
}
1053+
writeln!(f)?;
1054+
write!(f, "y: 0x")?;
1055+
for y_byte in &self.data[36..68] {
1056+
write!(f, "{y_byte:02x}")?;
1057+
}
1058+
Ok(())
1059+
}
9651060
}
9661061

9671062
pub type LabelLookup =

src/silentpayments/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
1+
//! This module implements high-level Rust bindings for the libsecp256k1 implementation for Silent
2+
//! Payments, as specified in BIP352.
3+
//!
4+
//! This particularly involves the creation of input tweak data by summing up secret or public keys
5+
//! and the derivation of a shared secret using Elliptic Curve Diffie-Hellman. Combined are either:
6+
//!
7+
//! - spender's secret keys and recipient's public key (a * B, sender side)
8+
//! - spender's public keys and recipient's secret key (A * b, recipient side)
9+
//!
10+
//! With this result, the necessary key material for ultimately creating/scanning
11+
//! or spending Silent Payment outputs can be determined.
12+
//!
13+
//! Note that the underlying module this crate is binding is _not_ a full implementation of BIP352,
14+
//! as it inherently doesn't deal with higher-level concepts like addresses, output script types or
15+
//! transactions. The intent is to provide bindings to the libsecp256k1 module for abstracting away
16+
//! the elliptic-curve operations required for the protocol. For any wallet software already using
17+
//! this crate, this API should provide all the functions needed for a Silent Payments
18+
//! implementation without requiring any further elliptic-curve operations from the wallet.
119
pub mod recipient;
220
pub mod sender;

0 commit comments

Comments
 (0)