Skip to content

Commit 6ef8a3d

Browse files
Merge pull request #6413 from BitGo/BTC-2251.adding-prefix
refactor(utxo-core): Pay Go Functions prefix
2 parents e65d4eb + ccf4e84 commit 6ef8a3d

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

modules/utxo-core/src/paygo/parsePayGoAttestation.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import assert from 'assert';
33
import { bufferutils } from '@bitgo/utxo-lib';
44

55
// The signed address will always have the following structure:
6-
// <varint_length><ENTROPY><ADDRESS><UUID>
6+
// 0x18Bitcoin Signed Message:\n<varint_length><ENTROPY><ADDRESS><UUID>
7+
export const Prefix = Buffer.from('\u0018Bitcoin Signed Message:\n', 'utf-8');
78

89
// UUID has the structure 00000000-0000-0000-0000-000000000000, and after
910
// we Buffer.from and get it's length its 36.
@@ -32,6 +33,9 @@ export function parsePayGoAttestation(message: Buffer): {
3233
// This generates the first part before the varint length so that we can
3334
// determine how many bytes this is and iterate through the Buffer.
3435
let offset = 0;
36+
if (message.toString('hex').startsWith(Prefix.toString('hex'))) {
37+
offset = Prefix.length;
38+
}
3539

3640
// we decode the varint of the message which is uint32
3741
// https://en.bitcoin.it/wiki/Protocol_documentation

modules/utxo-core/src/testutil/generatePayGoAttestationProof.utils.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import crypto from 'crypto';
22

33
import { bufferutils } from '@bitgo/utxo-lib';
4+
5+
import { Prefix } from '../paygo';
6+
47
/** We have a mirrored function similar to our hsm that generates our Bitcoin signed
58
* message so that we can use for testing. This creates a random entropy as well using
69
* the nilUUID structure to construct our uuid buffer and given our address we can
@@ -11,7 +14,7 @@ import { bufferutils } from '@bitgo/utxo-lib';
1114
* @param address
1215
* @returns
1316
*/
14-
export function generatePayGoAttestationProof(uuid: string, address: Buffer): Buffer {
17+
export function generatePayGoAttestationProof(uuid: string, address: Buffer, hasPrefix = true): Buffer {
1518
// <ENTROPY>
1619
const entropyLength = 64;
1720
const entropy = crypto.randomBytes(entropyLength);
@@ -27,8 +30,10 @@ export function generatePayGoAttestationProof(uuid: string, address: Buffer): Bu
2730
const msgLength = entropyLength + addressBufferLength + uuidBufferLength;
2831
const msgLengthBuffer = bufferutils.varuint.encode(msgLength);
2932

30-
// <0x18Bitcoin Signed Message:\n<LENGTH><ENTROPY><ADDRESS><UUID>
33+
// <LENGTH><ENTROPY><ADDRESS><UUID>
3134
const proofMessage = Buffer.concat([msgLengthBuffer, entropy, address, uuidBuffer]);
3235

33-
return proofMessage;
36+
// If hasPrefix, we return 0x18Bitcoin Signed Message:\n<proof> otherwise its just <proof>
37+
// where <proof> = <VARINT_LEN><ENTROPY><ADDRESS><UUID>
38+
return hasPrefix ? Buffer.concat([Prefix, proofMessage]) : proofMessage;
3439
}

modules/utxo-core/test/paygo/parsePayGoAttestation.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,54 @@ import * as assert from 'assert';
22

33
import { parsePayGoAttestation } from '../../src/paygo';
44
import { generatePayGoAttestationProof } from '../../src/testutil';
5+
import { NIL_UUID } from '../../src/paygo/attestation';
56

67
const addressFromPubKeyBase58 = 'bitgoAddressToExtract';
78
const bufferAddressPubKeyB58 = Buffer.from(addressFromPubKeyBase58);
89

9-
describe('extractAddressBufferFromPayGoAttestationProof', () => {
10-
it('should extractAddressBufferFromPayGoAttestationProof properly', () => {
11-
const paygoAttestationProof = generatePayGoAttestationProof(
12-
'00000000-0000-0000-0000-000000000000',
13-
bufferAddressPubKeyB58
14-
);
10+
describe('parsePayGoAttestationProof with prefix', () => {
11+
it('should extractAddressBufferFromPayGoAttestationProof properly', function () {
12+
const paygoAttestationProof = generatePayGoAttestationProof(NIL_UUID, bufferAddressPubKeyB58);
1513
const { entropy, address, uuid } = parsePayGoAttestation(paygoAttestationProof);
16-
assert.deepStrictEqual(Buffer.compare(address, bufferAddressPubKeyB58), 0);
17-
assert.deepStrictEqual(uuid.toString(), '00000000-0000-0000-0000-000000000000');
14+
assert.ok(address.equals(bufferAddressPubKeyB58));
15+
assert.deepStrictEqual(uuid.toString(), NIL_UUID);
1816
assert.deepStrictEqual(entropy.length, 64);
1917
});
2018

21-
it('should extract the paygo address paygo attestation proof given a non nilUUID', () => {
19+
it('should extract the paygo address paygo attestation proof given a non nilUUID', function () {
2220
const paygoAttestationProof = generatePayGoAttestationProof(
2321
'12345678-1234-4567-6890-231928472123',
2422
bufferAddressPubKeyB58
2523
);
2624
const { entropy, address, uuid } = parsePayGoAttestation(paygoAttestationProof);
27-
assert.deepStrictEqual(Buffer.compare(address, bufferAddressPubKeyB58), 0);
28-
assert.deepStrictEqual(uuid.toString(), '12345678-1234-4567-6890-231928472123');
25+
assert.ok(address.equals(bufferAddressPubKeyB58));
26+
assert.deepStrictEqual(uuid.toString('utf-8'), '12345678-1234-4567-6890-231928472123');
2927
assert.deepStrictEqual(entropy.length, 64);
3028
});
3129

32-
it('should not extract the correct address given a uuid of wrong format', () => {
30+
it('should not extract the correct address given a uuid of wrong format', function () {
3331
const paygoAttestationProof = generatePayGoAttestationProof(
3432
'000000000000000-000000-0000000-000000-0000000000000000',
3533
bufferAddressPubKeyB58
3634
);
3735
const { address } = parsePayGoAttestation(paygoAttestationProof);
38-
assert.notDeepStrictEqual(Buffer.compare(address, bufferAddressPubKeyB58), 0);
36+
assert.ok(!address.equals(bufferAddressPubKeyB58));
3937
});
4038

41-
it('should throw an error if the paygo attestation proof is too short', () => {
39+
it('should throw an error if the paygo attestation proof is too short', function () {
4240
assert.throws(
43-
() => parsePayGoAttestation(Buffer.from('shortproof-shrug')),
41+
() => parsePayGoAttestation(Buffer.from('shortproof-shrug', 'utf-8')),
4442
'PayGo attestation proof is too short to contain a valid address.'
4543
);
4644
});
4745
});
46+
47+
describe('parsePayGoAttestation without prefix', function () {
48+
it('should extract the parts of the proof without the prefix automatically', function () {
49+
const payGoAttestationProof = generatePayGoAttestationProof(NIL_UUID, bufferAddressPubKeyB58, false);
50+
const { entropy, address, uuid } = parsePayGoAttestation(payGoAttestationProof);
51+
assert.ok(address.equals(bufferAddressPubKeyB58));
52+
assert.deepStrictEqual(uuid.toString(), NIL_UUID);
53+
assert.deepStrictEqual(entropy.length, 64);
54+
});
55+
});

0 commit comments

Comments
 (0)