From fe0f83531e35f76d3582813da4cbb518d9bb1d12 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Wed, 19 Jun 2024 23:56:42 +0200 Subject: BIP-352: generate `input_hash` after summing up keys (simplification) For both sender and receiver, generating the input hash is currently listed as the first step. This already involves summing up the public keys, even though summing up key material (private keys for sender, public keys of inputs for receiver) is then again listed explicitly in later steps. It seems to be more obvious and less redundant (and also hopefully less confusing for readers) to reorder the instructions to calculate the input_hash _after_ the key aggregation is done to reuse the result. In case of the sender, the private key sum has to be multiplicated with G in order to the get to the corresponding input pubkey sum. This also corresponds to the current BIP352 implementation in the secp256k1 library (https://github.com/bitcoin-core/secp256k1/pull/1519). The reference implementation in Python here is adapted for the sender side, the receiver side has already generated the input_hash after summing up the pubkeys. --- bip-0352/reference.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'bip-0352') diff --git a/bip-0352/reference.py b/bip-0352/reference.py index 9f43695..9b35d04 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -117,7 +117,7 @@ def decode_silent_payment_address(address: str, hrp: str = "tsp") -> Tuple[ECPub return B_scan, B_spend -def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], input_hash: bytes, recipients: List[str], hrp="tsp") -> List[str]: +def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], outpoints: List[COutPoint], recipients: List[str], hrp="tsp") -> List[str]: G = ECKey().set(1).get_pubkey() negated_keys = [] for key, is_xonly in input_priv_keys: @@ -127,6 +127,7 @@ def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], input_hash: bytes, negated_keys.append(k) a_sum = sum(negated_keys) + input_hash = get_input_hash(outpoints, a_sum * G) silent_payment_groups: Dict[ECPubKey, List[ECPubKey]] = {} for recipient in recipients: B_scan, B_m = decode_silent_payment_address(recipient, hrp=hrp) @@ -236,9 +237,8 @@ if __name__ == "__main__": sending_outputs = [] if (len(input_pub_keys) > 0): - A_sum = reduce(lambda x, y: x + y, input_pub_keys) - input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) - sending_outputs = create_outputs(input_priv_keys, input_hash, given["recipients"], hrp="sp") + outpoints = [vin.outpoint for vin in vins] + sending_outputs = create_outputs(input_priv_keys, outpoints, given["recipients"], hrp="sp") # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses # will produce different generated outputs if sending to multiple silent payment addresses belonging to the -- cgit v1.2.3