Skip to content

Commit

Permalink
add tagged hashes
Browse files Browse the repository at this point in the history
BIP352 specifies tagged hashes for:

* the outpointHash (BIP0352/Inputs)
* the shared secret (BIP0352/SharedSecret)

This also involves updating the output hash function to now:

* Use the smallest outpoint (as opposed to all outpoints)
* Commit to the public key A (the sum of the eligible input pubkeys)
  • Loading branch information
josibake committed May 1, 2024
1 parent f776d1a commit 2457944
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ type SilentPaymentGroup = {
BmValues: Array<[Buffer, number | undefined]>;
};

function taggedHash(tag: string, data: Buffer): Buffer {
const hash = crypto.createHash('sha256');
const tagHash = hash.update(tag, 'utf-8').digest();
const ss = Buffer.concat([tagHash, tagHash, data]);
return crypto.createHash('sha256').update(ss).digest();
}

const G = Buffer.from("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "hex");

export class SilentPayment {
Expand Down Expand Up @@ -70,7 +77,8 @@ export class SilentPayment {
if (silentPaymentGroups.length === 0) return ret; // passthrough

const a = SilentPayment._sumPrivkeys(utxos);
const outpoint_hash = SilentPayment._outpointsHash(utxos);
const A = Buffer.from(ecc.pointFromScalar(a) as Uint8Array);
const outpoint_hash = SilentPayment._outpointsHash(utxos, A);

// Generating Pmn for each Bm in the group
for (const group of silentPaymentGroups) {
Expand All @@ -80,10 +88,10 @@ export class SilentPayment {

let n = 0;
for (const [Bm, amount] of group.BmValues) {
const tn = crypto
.createHash("sha256")
.update(Buffer.concat([ecdh_shared_secret!, SilentPayment._ser32(n)]))
.digest();
const tn = taggedHash(
"BIP0352/SharedSecret",
Buffer.concat([ecdh_shared_secret!, SilentPayment._ser32(n)])
);

// Let Pmn = tn·G + Bm
const Pmn = Buffer.from(ecc.pointAdd(ecc.pointMultiply(G, tn) as Uint8Array, Bm) as Uint8Array);
Expand All @@ -100,17 +108,15 @@ export class SilentPayment {
return ret;
}

static _outpointsHash(parameters: UTXO[]): Buffer {
static _outpointsHash(parameters: UTXO[], A: Buffer): Buffer {
let bufferConcat = Buffer.alloc(0);
const outpoints: Array<Buffer> = [];
for (const parameter of parameters) {
outpoints.push(Buffer.concat([Buffer.from(parameter.txid, "hex").reverse(), SilentPayment._ser32(parameter.vout).reverse()]));
}
outpoints.sort(Buffer.compare);
for (const outpoint of outpoints) {
bufferConcat = Buffer.concat([bufferConcat, outpoint]);
}
return crypto.createHash("sha256").update(bufferConcat).digest();
const smallest_outpoint = outpoints[0];
return taggedHash("BIP0352/Inputs", Buffer.concat([Buffer.from(smallest_outpoint), Buffer.from(A)]));
}

/**
Expand Down

0 comments on commit 2457944

Please sign in to comment.