From e67a8989d7a35d9bd9cd3ee7b258ff6e542f5fb7 Mon Sep 17 00:00:00 2001 From: Christopher Fong Date: Thu, 3 Jul 2025 19:14:20 -0400 Subject: [PATCH 1/2] refactor(utxo-core): changed toString for message to hex TICKET: BTC-2246 refactor(utxo-core): keep message as a buffer TICKET: BTC-2246 --- modules/utxo-core/src/paygo/psbt/payGoAddressProof.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/utxo-core/src/paygo/psbt/payGoAddressProof.ts b/modules/utxo-core/src/paygo/psbt/payGoAddressProof.ts index 277eed5eda..24dc10361c 100644 --- a/modules/utxo-core/src/paygo/psbt/payGoAddressProof.ts +++ b/modules/utxo-core/src/paygo/psbt/payGoAddressProof.ts @@ -19,6 +19,7 @@ import { * @param psbt - PSBT that we need to encode our paygo address into * @param outputIndex - the index of the address in our output * @param sig - the signature that we want to encode + * @param entropy - the arbitrary entropy bytes from our vasp proof */ export function addPayGoAddressProof( psbt: utxolib.bitgo.UtxoPsbt, @@ -40,7 +41,7 @@ export function addPayGoAddressProof( * * @param psbt - PSBT we want to verify that the paygo address is in * @param outputIndex - we have the output index that address is in - * @param uuid + * @param verificationPubkey - the pubkey signed by the HSM to verify our message * @returns */ export function verifyPayGoAddressProof( @@ -76,7 +77,8 @@ export function verifyPayGoAddressProof( // We construct our message
const message = createPayGoAttestationBuffer(addressFromOutput, entropy, psbt.network); - if (!verifyMessage(message.toString(), verificationPubkey, signature, utxolib.networks.bitcoin)) { + // bip32utils.verifyMessage now takes in message as a Buffer + if (!verifyMessage(message, verificationPubkey, signature, utxolib.networks.bitcoin)) { throw new ErrorPayGoAddressProofFailedVerification(); } } From c0cf207daef905479b3dd4cf65c6f2a340d945a5 Mon Sep 17 00:00:00 2001 From: Christopher Fong Date: Mon, 7 Jul 2025 00:33:15 -0400 Subject: [PATCH 2/2] refactor(utxo-core): updated proof generation funcions TICKET: BTC-2246 chore(utxo-core): fixed tests TICKET: BTC-2246 --- modules/utxo-core/src/paygo/parsePayGoAttestation.ts | 9 ++++----- .../testutil/generatePayGoAttestationProof.utils.ts | 11 +---------- .../utxo-core/test/paygo/psbt/payGoAddressProof.ts | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/modules/utxo-core/src/paygo/parsePayGoAttestation.ts b/modules/utxo-core/src/paygo/parsePayGoAttestation.ts index 461df4364f..aa8d28f543 100644 --- a/modules/utxo-core/src/paygo/parsePayGoAttestation.ts +++ b/modules/utxo-core/src/paygo/parsePayGoAttestation.ts @@ -3,9 +3,8 @@ import assert from 'assert'; import { bufferutils } from '@bitgo/utxo-lib'; // The signed address will always have the following structure: -// 0x18Bitcoin Signed Message:\n
+//
-const PrefixLength = Buffer.from([0x18]).length + Buffer.from('Bitcoin Signed Message:\n').length; // UUID has the structure 00000000-0000-0000-0000-000000000000, and after // we Buffer.from and get it's length its 36. const UuidBufferLength = 36; @@ -14,7 +13,7 @@ const EntropyLen = 64; /** * This function takes in the attestation proof of a PayGo address of the from - * 0x18Bitcoin Signed Message:\n
and returns + *
and returns * the address given its length. It is assumed that the ENTROPY is 64 bytes in the Buffer * so if not given an address proof length we can still extract the address from the proof. * @@ -26,13 +25,13 @@ export function parsePayGoAttestation(message: Buffer): { address: Buffer; uuid: Buffer; } { - if (message.length <= PrefixLength + EntropyLen + UuidBufferLength) { + if (message.length <= EntropyLen + UuidBufferLength) { throw new Error('PayGo attestation proof is too short to contain a valid address'); } // This generates the first part before the varint length so that we can // determine how many bytes this is and iterate through the Buffer. - let offset = PrefixLength; + let offset = 0; // we decode the varint of the message which is uint32 // https://en.bitcoin.it/wiki/Protocol_documentation diff --git a/modules/utxo-core/src/testutil/generatePayGoAttestationProof.utils.ts b/modules/utxo-core/src/testutil/generatePayGoAttestationProof.utils.ts index 22fd4ab73a..aef714dd89 100644 --- a/modules/utxo-core/src/testutil/generatePayGoAttestationProof.utils.ts +++ b/modules/utxo-core/src/testutil/generatePayGoAttestationProof.utils.ts @@ -12,11 +12,6 @@ import { bufferutils } from '@bitgo/utxo-lib'; * @returns */ export function generatePayGoAttestationProof(uuid: string, address: Buffer): Buffer { - // <0x18Bitcoin Signed Message:\n - const prefixByte = Buffer.from([0x18]); - const prefixMessage = Buffer.from('Bitcoin Signed Message:\n'); - const prefixBuffer = Buffer.concat([prefixByte, prefixMessage]); - // const entropyLength = 64; const entropy = crypto.randomBytes(entropyLength); @@ -33,11 +28,7 @@ export function generatePayGoAttestationProof(uuid: string, address: Buffer): Bu const msgLengthBuffer = bufferutils.varuint.encode(msgLength); // <0x18Bitcoin Signed Message:\n
- const proofMessage = Buffer.concat([prefixBuffer, msgLengthBuffer, entropy, address, uuidBuffer]); + const proofMessage = Buffer.concat([msgLengthBuffer, entropy, address, uuidBuffer]); - // we sign this with the priv key - // don't know what sign function to call. Since this is just a mirrored function don't know if we need - // to include this part. - // const signedMsg = sign(attestationPrvKey, proofMessage); return proofMessage; } diff --git a/modules/utxo-core/test/paygo/psbt/payGoAddressProof.ts b/modules/utxo-core/test/paygo/psbt/payGoAddressProof.ts index 2f95b32117..1bd8518f78 100644 --- a/modules/utxo-core/test/paygo/psbt/payGoAddressProof.ts +++ b/modules/utxo-core/test/paygo/psbt/payGoAddressProof.ts @@ -51,7 +51,7 @@ export const addressProofMsgBuffer = trimMessagePrefix(addressProofBuffer); export const addressProofEntropy = addressProofMsgBuffer.subarray(0, 65); // signature with the given msg addressProofBuffer -export const sig = signMessage(addressProofMsgBuffer.toString(), attestationPrvKey!, network); +export const sig = signMessage(addressProofMsgBuffer, attestationPrvKey!, network); function getTestPsbt() { return utxolib.testutil.constructPsbt(psbtInputs, psbtOutputs, network, rootWalletKeys, 'unsigned');