Skip to content

Commit 11f8656

Browse files
committed
psbt: add support for caching when generating signature hashes/signing
Having the cache as part of the PSBT is not ideal, but it allows us to support caching without having to modify a bunch of psbt calls in an incompatible fashion. Also includes a drive-by fix to add genesis_blockhash to the tests ctypes wrapper, as it was missed previously.
1 parent 07b766a commit 11f8656

File tree

9 files changed

+79
-2
lines changed

9 files changed

+79
-2
lines changed

include/wally.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,17 @@ inline int psbt_sign_input_bip32(const PSBT& psbt, size_t index, size_t subindex
16411641
return detail::check_ret(__FUNCTION__, ret);
16421642
}
16431643

1644+
inline int psbt_signing_cache_disable(struct wally_psbt* psbt) {
1645+
int ret = ::wally_psbt_signing_cache_disable(psbt);
1646+
return detail::check_ret(__FUNCTION__, ret);
1647+
}
1648+
1649+
template <class PSBT>
1650+
inline int psbt_signing_cache_enable(const PSBT& psbt, uint32_t flags) {
1651+
int ret = ::wally_psbt_signing_cache_enable(detail::get_p(psbt), flags);
1652+
return detail::check_ret(__FUNCTION__, ret);
1653+
}
1654+
16441655
template <class PSBT>
16451656
inline int psbt_to_base64(const PSBT& psbt, uint32_t flags, char** output) {
16461657
int ret = ::wally_psbt_to_base64(detail::get_p(psbt), flags, output);

include/wally_psbt.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ struct wally_psbt {
141141
uint32_t pset_modifiable_flags;
142142
unsigned char genesis_blockhash[SHA256_LEN]; /* All zeros if not present */
143143
#endif /* WALLY_ABI_NO_ELEMENTS */
144+
struct wally_map *signing_cache;
144145
};
145146
#endif /* SWIG */
146147

@@ -2592,6 +2593,36 @@ WALLY_CORE_API int wally_psbt_blind_alloc(
25922593
struct wally_map **output);
25932594
#endif /* WALLY_ABI_NO_ELEMENTS */
25942595

2596+
/**
2597+
* Enable caching of intermediate data when signing a PSBT.
2598+
*
2599+
* This function should be called just before signing a PSBT or the first
2600+
* input being signed, or before computing a signature hash for the PSBT.
2601+
* If the PSBT is modified in a way that would affect the signatures produced,
2602+
* this function should be called again to ensure that old cached data is
2603+
* purged before signing again.
2604+
*
2605+
* :param psbt: PSBT to enable the signing cache for. Directly modifies this PSBT.
2606+
* :param flags: Flags controlling the signing cache. Must be 0.
2607+
*
2608+
* .. note:: The signing cache is local to the given PSBT and is not
2609+
*| serialized with it.
2610+
*/
2611+
WALLY_CORE_API int wally_psbt_signing_cache_enable(
2612+
struct wally_psbt *psbt,
2613+
uint32_t flags);
2614+
2615+
/**
2616+
* Disable caching of intermediate data when signing a PSBT.
2617+
*
2618+
* This function can be called at any time to ensure that the PSBT signing
2619+
* cache data is not reused when signing again.
2620+
*
2621+
* :param psbt: PSBT to disable the signing cache for. Directly modifies this PSBT.
2622+
*/
2623+
WALLY_CORE_API int wally_psbt_signing_cache_disable(
2624+
struct wally_psbt *psbt);
2625+
25952626
/**
25962627
* Sign PSBT inputs corresponding to a given private key.
25972628
*

src/psbt.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "script_int.h"
1111
#include "script.h"
1212
#include "pullpush.h"
13+
#include "tx_io.h"
1314

1415
/* TODO:
1516
* - When setting utxo in an input via the psbt (in the SWIG
@@ -1308,6 +1309,7 @@ int wally_psbt_free(struct wally_psbt *psbt)
13081309
#ifdef BUILD_ELEMENTS
13091310
wally_map_clear(&psbt->global_scalars);
13101311
#endif /* BUILD_ELEMENTS */
1312+
wally_psbt_signing_cache_disable(psbt);
13111313
clear_and_free(psbt, sizeof(*psbt));
13121314
}
13131315
return WALLY_OK;
@@ -4528,7 +4530,7 @@ int wally_psbt_get_input_signature_hash(struct wally_psbt *psbt, size_t index,
45284530
NULL, 0,
45294531
psbt->genesis_blockhash, sizeof(psbt->genesis_blockhash),
45304532
sighash, WALLY_SIGTYPE_SW_V1,
4531-
NULL, bytes_out, len);
4533+
psbt->signing_cache, bytes_out, len);
45324534

45334535
wally_free(scripts.items); /* No need to clear the value pointers */
45344536
wally_free(values.items);
@@ -4720,6 +4722,24 @@ int wally_psbt_sign(struct wally_psbt *psbt,
47204722
return ret;
47214723
}
47224724

4725+
int wally_psbt_signing_cache_enable(struct wally_psbt *psbt, uint32_t flags)
4726+
{
4727+
if (!psbt || flags)
4728+
return WALLY_EINVAL;
4729+
wally_psbt_signing_cache_disable(psbt);
4730+
return wally_map_init_alloc(TXIO_CACHE_INITIAL_SIZE, NULL,
4731+
&psbt->signing_cache);
4732+
}
4733+
4734+
int wally_psbt_signing_cache_disable(struct wally_psbt *psbt)
4735+
{
4736+
if (!psbt)
4737+
return WALLY_EINVAL;
4738+
wally_map_free(psbt->signing_cache);
4739+
psbt->signing_cache = NULL;
4740+
return WALLY_OK;
4741+
}
4742+
47234743
static const struct wally_map_item *get_sig(const struct wally_psbt_input *input,
47244744
size_t i, size_t n)
47254745
{

src/swig_java/swig.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,8 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
955955
%returns_void__(wally_psbt_sign);
956956
%returns_void__(wally_psbt_sign_bip32);
957957
%returns_void__(wally_psbt_sign_input_bip32);
958+
%returns_void__(wally_psbt_signing_cache_enable);
959+
%returns_void__(wally_psbt_signing_cache_disable);
958960
%returns_string(wally_psbt_to_base64);
959961
%returns_size_t(wally_psbt_to_bytes);
960962
%returns_array_(wally_ripemd160, 3, 4, RIPEMD160_LEN);

src/test/util.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ class wally_psbt(Structure):
193193
('has_fallback_locktime', c_uint32),
194194
('tx_modifiable_flags', c_uint32),
195195
('global_scalars', wally_map),
196-
('pset_modifiable_flags', c_uint32)]
196+
('pset_modifiable_flags', c_uint32),
197+
('genesis_blockhash', c_ubyte * 32),
198+
('signing_cache', POINTER(wally_map))]
197199

198200
for f in (
199201
# Internal functions
@@ -629,6 +631,8 @@ class wally_psbt(Structure):
629631
('wally_psbt_sign', c_int, [POINTER(wally_psbt), c_void_p, c_size_t, c_uint32]),
630632
('wally_psbt_sign_bip32', c_int, [POINTER(wally_psbt), POINTER(ext_key), c_uint32]),
631633
('wally_psbt_sign_input_bip32', c_int, [POINTER(wally_psbt), c_size_t, c_size_t, c_void_p, c_size_t, POINTER(ext_key), c_uint32]),
634+
('wally_psbt_signing_cache_disable', c_int, [POINTER(wally_psbt)]),
635+
('wally_psbt_signing_cache_enable', c_int, [POINTER(wally_psbt), c_uint32]),
632636
('wally_psbt_to_base64', c_int, [POINTER(wally_psbt), c_uint32, c_char_p_p]),
633637
('wally_psbt_to_bytes', c_int, [POINTER(wally_psbt), c_uint32, c_void_p, c_size_t, c_size_t_p]),
634638
('wally_ripemd160', c_int, [c_void_p, c_size_t, c_void_p, c_size_t]),

src/tx_io.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <include/wally_map.h>
55
#include "ccan/ccan/crypto/sha256/sha256.h"
66

7+
/* Suggested initial size of a signing cache to avoid re-allocations */
8+
#define TXIO_CACHE_INITIAL_SIZE 16
9+
710
/* A cursor for pushing/pulling tx bytes for hashing */
811
typedef struct cursor_io
912
{

src/wasm_package/src/functions.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wasm_package/src/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ export function psbt_set_version(psbt: Ref_wally_psbt, flags: number, version: n
562562
export function psbt_sign(psbt: Ref_wally_psbt, key: Buffer|Uint8Array, flags: number): void;
563563
export function psbt_sign_bip32(psbt: Ref_wally_psbt, hdkey: Ref_ext_key, flags: number): void;
564564
export function psbt_sign_input_bip32(psbt: Ref_wally_psbt, index: number, subindex: number, txhash: Buffer|Uint8Array, hdkey: Ref_ext_key, flags: number): void;
565+
export function psbt_signing_cache_disable(psbt: Ref_wally_psbt): void;
566+
export function psbt_signing_cache_enable(psbt: Ref_wally_psbt, flags: number): void;
565567
export function psbt_to_base64(psbt: Ref_wally_psbt, flags: number): string;
566568
export function ripemd160(bytes: Buffer|Uint8Array): Buffer;
567569
export function s2c_commitment_verify(sig: Buffer|Uint8Array, s2c_data: Buffer|Uint8Array, s2c_opening: Buffer|Uint8Array, flags: number): void;

tools/wasm_exports.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ EXPORTED_FUNCTIONS="['_malloc','_free','_bip32_key_free' \
362362
,'_wally_psbt_sign' \
363363
,'_wally_psbt_sign_bip32' \
364364
,'_wally_psbt_sign_input_bip32' \
365+
,'_wally_psbt_signing_cache_disable' \
366+
,'_wally_psbt_signing_cache_enable' \
365367
,'_wally_psbt_to_base64' \
366368
,'_wally_psbt_to_bytes' \
367369
,'_wally_ripemd160' \

0 commit comments

Comments
 (0)