Skip to content

Commit 9f4929b

Browse files
chore(utxo-lib): modified verify function and tests
Issue: BTC-2047 TICKET: BTC-2047
1 parent 393b589 commit 9f4929b

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

modules/utxo-lib/src/bitgo/psbt/paygoAddressProof.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { crypto } from 'bitcoinjs-lib';
55
import { address } from '../..';
66
import { networks } from '../../networks';
77
import { toBase58Check } from '../../address';
8+
import { extractAddressBufferFromPayGoAttestationProof } from '../../bitgo/ExtractAddressPayGoAttestation';
89
import { getPsbtOutputProprietaryKeyVals, ProprietaryKeySubtype, PSBT_PROPRIETARY_IDENTIFIER } from '../PsbtUtil';
910
import { UtxoPsbt } from '../UtxoPsbt';
1011

@@ -33,15 +34,16 @@ export function addPaygoAddressProof(psbt: UtxoPsbt, outputIndex: number, sig: B
3334
* @param psbt - PSBT we want to verify that the paygo address is in
3435
* @param outputIndex - we have the output index that address is in
3536
* @param pub - The public key that we want to verify the proof with
37+
* @param message - The message we want to verify corresponding to sig
3638
* @returns
3739
*/
38-
export function verifyPaygoAddressProof(psbt: UtxoPsbt, outputIndex: number, pub: Buffer): void {
40+
export function verifyPaygoAddressProof(psbt: UtxoPsbt, outputIndex: number, message: Buffer): void {
3941
const stored = psbt.getOutputProprietaryKeyVals(outputIndex, {
4042
identifier: PSBT_PROPRIETARY_IDENTIFIER,
4143
subtype: ProprietaryKeySubtype.PAYGO_ADDRESS_ATTESTATION_PROOF,
4244
});
4345
if (!stored) {
44-
throw new Error('No address proof');
46+
throw new Error(`No address proof.`);
4547
}
4648

4749
// assert stored length is 0 or 1
@@ -52,20 +54,21 @@ export function verifyPaygoAddressProof(psbt: UtxoPsbt, outputIndex: number, pub
5254
}
5355

5456
const signature = stored[0].value;
57+
const pub = stored[0].key.keydata;
5558
// It doesn't matter that this is bitcoin or not, we just need to convert the public key buffer into an address format
5659
// for the verification
5760
const messageToVerify = toBase58Check(crypto.hash160(pub), networks.bitcoin.pubKeyHash, networks.bitcoin);
5861

5962
// TODO: need to figure out what the message is in this context
60-
// Answer: message is our <varint_length><Entropy><Address><UUID>
63+
// Answer: message is our 0x18Bitcoin Signed Message:\n<varint_length><Entropy><Address><UUID>
6164
if (!bitcoinMessage.verify(message, messageToVerify, signature)) {
6265
throw new Error('Cannot verify the paygo address signature with the provided pubkey.');
6366
}
6467

6568
const out = psbt.txOutputs[outputIndex];
6669
assert(out);
6770
const addressFromOutput = address.fromOutputScript(out.script, psbt.network);
68-
const addressFromProof = extractAddressFromPayGoAttestationProof(message, addressFromOutput.length);
71+
const addressFromProof = extractAddressBufferFromPayGoAttestationProof(message);
6972

7073
if (addressFromProof !== addressFromOutput) {
7174
throw new Error(

modules/utxo-lib/test/bitgo/psbt/paygoAddressProof.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as assert from 'assert';
2+
import * as bitcoinMessage from 'bitcoinjs-message';
23
import { decodeProprietaryKey } from 'bip174/src/lib/proprietaryKeyVal';
34
import { KeyValue } from 'bip174/src/lib/interfaces';
45
import { checkForOutput } from 'bip174/src/lib/utils';
@@ -14,29 +15,31 @@ import {
1415
psbtOutputIncludesPaygoAddressProof,
1516
} from '../../../src/bitgo/psbt/paygoAddressProof';
1617

18+
// To construct our PSBTs
1719
const network = networks.bitcoin;
1820
const keys = [1, 2, 3].map((v) => bip32.fromSeed(Buffer.alloc(16, `test/2/${v}`), network));
1921
const rootWalletKeys = new RootWalletKeys([keys[0], keys[1], keys[2]]);
20-
// const dummyKey1 = rootWalletKeys.deriveForChainAndIndex(50, 200);
21-
const dummyKey2 = rootWalletKeys.deriveForChainAndIndex(60, 201);
22-
2322
const psbtInputs = inputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(1000) }));
2423
const psbtOutputs = outputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(900) }));
25-
// const dummy1PubKey = dummyKey1.user.publicKey;
26-
// This generatePayGoAttestationProof function should be returning the bitcoin signed message
27-
const sig2 = dummyKey2.user.privateKey!;
2824

2925
// wallet pub and priv key for tbtc
3026
const attestationPubKey =
3127
'xpub661MyMwAqRbcFU2Qx7pvGmmiQpVj8NcR7dSVpgqNChMkQyobpVWWERcrTb47WicmXwkhAY2VrC3hb29s18FDQWJf5pLm3saN6uLXAXpw1GV';
32-
const attestationPrvKey = 'red';
28+
const attestationPrvKey = 'privkeyforpaygoattestationabdef12345';
29+
30+
// UUID structure
3331
const nilUUID = '00000000-0000-0000-0000-000000000000';
32+
33+
// our xpub converted to base58 address
3434
const address = toBase58Check(
3535
crypto.hash160(Buffer.from(attestationPubKey)),
3636
networks.bitcoin.pubKeyHash,
3737
networks.bitcoin
3838
);
39+
// this should be retuning a Buffer
3940
const addressProofBuffer = generatePayGoAttestationProof(Buffer.from(attestationPrvKey), nilUUID, address);
41+
// signature with the given msg addressProofBuffer
42+
const sig = bitcoinMessage.sign(addressProofBuffer, Buffer.from(attestationPrvKey));
4043

4144
function getTestPsbt() {
4245
return testutil.constructPsbt(psbtInputs, psbtOutputs, network, rootWalletKeys, 'unsigned');
@@ -59,36 +62,34 @@ describe('addPaygoAddressProof and verifyPaygoAddressProof', () => {
5962
it("should fail a proof verification if the proof isn't valid", () => {
6063
const outputIndex = 0;
6164
const psbt = getTestPsbt();
62-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(addressProofBuffer), Buffer.from(attestationPubKey));
65+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from(attestationPubKey));
6366
const output = checkForOutput(psbt.data.outputs, outputIndex);
6467
const proofInPsbt = getPaygoProprietaryKey(output.unknownKeyVals!);
6568
assert(proofInPsbt.length === 1);
6669
assert.throws(
67-
() => verifyPaygoAddressProof(psbt, 0, dummyKey2.user.publicKey),
70+
() => verifyPaygoAddressProof(psbt, 0, Buffer.from('Random Signed Message')),
6871
(e: any) => e.message === 'Cannot verify the paygo address signature with the provided pubkey.'
6972
);
7073
});
7174

7275
it('should add and verify a valid paygo address proof on the PSBT', () => {
7376
const outputIndex = 0;
7477
const psbt = getTestPsbt();
75-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(addressProofBuffer), Buffer.from(attestationPubKey));
76-
// should verify function return a boolean? that way we can assert
77-
// if this is verified, throws an error otherwise or false + error msg as an object
78-
verifyPaygoAddressProof(psbt, outputIndex, Buffer.from(attestationPubKey));
78+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from(attestationPubKey));
79+
verifyPaygoAddressProof(psbt, outputIndex, addressProofBuffer);
7980
});
8081

8182
it('should throw an error if there are multiple PayGo proprietary keys in the PSBT', () => {
8283
const outputIndex = 0;
8384
const psbt = getTestPsbt();
84-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(addressProofBuffer), Buffer.from(attestationPubKey));
85-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(sig2), Buffer.from(attestationPubKey));
85+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from(attestationPubKey));
86+
addPaygoAddressProof(psbt, outputIndex, Buffer.from('signature2'), Buffer.from(attestationPubKey));
8687
const output = checkForOutput(psbt.data.outputs, outputIndex);
8788
const proofInPsbt = getPaygoProprietaryKey(output.unknownKeyVals!);
8889
assert(proofInPsbt.length !== 0);
8990
assert(proofInPsbt.length <= 1);
9091
assert.throws(
91-
() => verifyPaygoAddressProof(psbt, outputIndex, Buffer.from(attestationPubKey)),
92+
() => verifyPaygoAddressProof(psbt, outputIndex, addressProofBuffer),
9293
(e: any) => e.message === 'There are multiple paygo address proofs encoded in the PSBT. Something went wrong.'
9394
);
9495
});
@@ -98,7 +99,7 @@ describe('verifyPaygoAddressProof', () => {
9899
it('should throw an error if there is no PayGo address in PSBT', () => {
99100
const psbt = getTestPsbt();
100101
assert.throws(
101-
() => verifyPaygoAddressProof(psbt, 0, Buffer.from(attestationPubKey)),
102+
() => verifyPaygoAddressProof(psbt, 0, addressProofBuffer),
102103
(e: any) => e.message === 'here is no paygo address proof encoded in the PSBT.'
103104
);
104105
});
@@ -108,7 +109,7 @@ describe('getPaygoAddressProofIndex', () => {
108109
it('should get PayGo address proof index from PSBT if there is one', () => {
109110
const psbt = getTestPsbt();
110111
const outputIndex = 0;
111-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(addressProofBuffer), Buffer.from(attestationPubKey));
112+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from(attestationPubKey));
112113
assert(psbtOutputIncludesPaygoAddressProof(psbt));
113114
assert(getPaygoAddressProofOutputIndex(psbt) === 0);
114115
});
@@ -122,13 +123,8 @@ describe('getPaygoAddressProofIndex', () => {
122123
it('should return an error and fail if we have multiple PayGo address in the PSBT in the same output index', () => {
123124
const psbt = getTestPsbt();
124125
const outputIndex = 0;
125-
addPaygoAddressProof(psbt, outputIndex, Buffer.from(addressProofBuffer), Buffer.from(attestationPubKey));
126-
addPaygoAddressProof(
127-
psbt,
128-
outputIndex,
129-
Buffer.from(addressProofBuffer),
130-
Buffer.from('xpub12345abcdef29a028510d3b2d4')
131-
);
126+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from(attestationPubKey));
127+
addPaygoAddressProof(psbt, outputIndex, sig, Buffer.from('xpub12345abcdef29a028510d3b2d4'));
132128
assert.throws(
133129
() => getPaygoAddressProofOutputIndex(psbt),
134130
(e: any) => e.message === 'There are multiple PayGo addresses in the PSBT output 0.'

0 commit comments

Comments
 (0)