Skip to content

Commit

Permalink
bitcoin: support sending to silent payment addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
benma committed Jun 9, 2024
1 parent 14cfe3f commit eaa0fba
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 50 deletions.
9 changes: 9 additions & 0 deletions messages/btc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ message BTCSignInitRequest {
SAT = 1;
}
FormatUnit format_unit = 8;
bool contains_silent_payment_outputs = 9;
}

message BTCSignNextResponse {
Expand All @@ -135,6 +136,7 @@ message BTCSignNextResponse {
// Previous tx's input/output index in case of PREV_INPUT or PREV_OUTPUT, for the input at `index`.
uint32 prev_index = 5;
AntiKleptoSignerCommitment anti_klepto_signer_commitment = 6;
bytes generated_output_pkscript = 7;
}

message BTCSignInputRequest {
Expand All @@ -158,6 +160,10 @@ enum BTCOutputType {
}

message BTCSignOutputRequest {
// https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki
message SilentPayment {
string address = 1;
}
bool ours = 1;
BTCOutputType type = 2; // if ours is false
// 20 bytes for p2pkh, p2sh, pw2wpkh. 32 bytes for p2wsh.
Expand All @@ -167,6 +173,9 @@ message BTCSignOutputRequest {
// If ours is true. References a script config from BTCSignInitRequest
uint32 script_config_index = 6;
optional uint32 payment_request_index = 7;
// If provided, `type` must be `P2TR` and the payload must be empty. The output's pkScript is
// returned BTCSignNextResponse.
SilentPayment silent_payment = 8;
}

message BTCScriptConfigRegistration {
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ add_custom_target(rust-bindgen
--allowlist-function keystore_lock
--allowlist-function keystore_create_and_store_seed
--allowlist-function keystore_copy_seed
--allowlist-function keystore_secp256k1_get_private_key
--allowlist-function keystore_get_bip39_mnemonic
--allowlist-function keystore_get_bip39_word
--allowlist-function keystore_get_ed25519_seed
Expand Down
23 changes: 23 additions & 0 deletions src/keystore.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,29 @@ bool keystore_secp256k1_schnorr_bip86_sign(
return secp256k1_schnorrsig_verify(ctx, sig64_out, msg32, 32, &pubkey) == 1;
}

bool keystore_secp256k1_get_private_key(
const uint32_t* keypath,
const size_t keypath_len,
bool tweak_bip86,
uint8_t* key_out)
{
if (tweak_bip86) {
secp256k1_keypair __attribute__((__cleanup__(_cleanup_keypair))) keypair = {0};
secp256k1_xonly_pubkey pubkey = {0};
if (!_schnorr_bip86_keypair(keypath, keypath_len, &keypair, &pubkey)) {
return false;
}
const secp256k1_context* ctx = wally_get_secp_context();
return secp256k1_keypair_sec(ctx, key_out, &keypair) == 1;
}
struct ext_key xprv __attribute__((__cleanup__(keystore_zero_xkey))) = {0};
if (!_get_xprv_twice(keypath, keypath_len, &xprv)) {
return false;
}
memcpy(key_out, xprv.priv_key + 1, 32);
return true;
}

#ifdef TESTING
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed)
{
Expand Down
6 changes: 6 additions & 0 deletions src/keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ USE_RESULT bool keystore_secp256k1_schnorr_bip86_sign(
const uint8_t* msg32,
uint8_t* sig64_out);

USE_RESULT bool keystore_secp256k1_get_private_key(
const uint32_t* keypath,
size_t keypath_len,
bool tweak_bip86,
uint8_t* key_out);

#ifdef TESTING
/**
* convenience to mock the keystore state (locked, seed) in tests.
Expand Down
4 changes: 3 additions & 1 deletion src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/bitbox02-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ util = { path = "../util" }
erc20_params = { path = "../erc20_params", optional = true }
binascii = { version = "0.1.4", default-features = false, features = ["encode"] }
bitbox02-noise = {path = "../bitbox02-noise"}
streaming-silent-payments = {path = "../streaming-silent-payments"}
hex = { workspace = true }
sha2 = { workspace = true }
sha3 = { workspace = true, optional = true }
Expand Down
Loading

0 comments on commit eaa0fba

Please sign in to comment.