Skip to content

Commit

Permalink
Treat SIGHASH_ALL seperate from SIGHASH_DEFAULT
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewLM committed Oct 12, 2023
1 parent ca018b5 commit a3680c4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 14 deletions.
25 changes: 13 additions & 12 deletions coinlib/lib/src/tx/sighash/taproot_signature_hasher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,32 @@ final class TaprootSignatureHasher with Writable implements SignatureHasher {
final PrevOutSignatureHashes? prevOutHashes;
final int inputN;
final List<Output> prevOuts;
final SigHashType hashType;
final SigHashType? hashType;
final Uint8List? leafHash;
final int codeSeperatorPos;

/// Produces the hash for a Taproot input signature at [inputN].
/// Unless [SigHashType.anyonecanpay] is true, [prevOuts] must contain the
/// full list of previous outputs being spent.
/// The [hashType] controls what data is included. [SigHashType.all] shall be
/// encoded as SIGHASH_DEFAULT (0).
/// The [hashType] controls what data is included. If ommitted it will be
/// treated as SIGHASH_DEFAULT which includes the same data as SIGHASH_ALL but
/// produces distinct signatures.
/// If an input is being signed for a tapscript, the [leafHash] must be
/// provided. [codeSeperatorPos] must be provided with the position of the
/// last executed CODESEPARATOR unless none have been executed in the script
TaprootSignatureHasher({
required this.tx,
required this.inputN,
required this.prevOuts,
required this.hashType,
this.hashType,
this.leafHash,
this.codeSeperatorPos = 0xFFFFFFFF,
}) : txHashes = TransactionSignatureHashes(tx),
prevOutHashes = PrevOutSignatureHashes(prevOuts) {

SignatureHasher.checkInputN(tx, inputN);

if (hashType.single && inputN >= tx.outputs.length) {
if (hashType != null && hashType!.single && inputN >= tx.outputs.length) {
throw ArgumentError.value(
inputN, "inputN", "has no corresponing output for SIGHASH_SINGLE",
);
Expand All @@ -61,29 +62,29 @@ final class TaprootSignatureHasher with Writable implements SignatureHasher {
final extFlag = leafHash == null ? 0 : 1;

writer.writeUInt8(0); // "Epoch"
writer.writeUInt8(
(hashType.all && !hashType.anyOneCanPay) ? 0 : hashType.value,
);
writer.writeUInt8(hashType == null ? 0 : hashType!.value);

final actualHashType = hashType ?? SigHashType.all();

// Total transaction data
writer.writeUInt32(tx.version);
writer.writeUInt32(tx.locktime);

if (!hashType.anyOneCanPay) {
if (!actualHashType.anyOneCanPay) {
writer.writeSlice(txHashes.prevouts.singleHash);
writer.writeSlice(prevOutHashes!.amounts.singleHash);
writer.writeSlice(prevOutHashes!.scripts.singleHash);
writer.writeSlice(txHashes.sequences.singleHash);
}

if (hashType.all) {
if (actualHashType.all) {
writer.writeSlice(txHashes.outputs.singleHash);
}

// Data specific to spending input
writer.writeUInt8(extFlag << 1);

if (hashType.anyOneCanPay) {
if (actualHashType.anyOneCanPay) {
tx.inputs[inputN].prevOut.write(writer);
prevOuts[inputN].write(writer);
writer.writeUInt32(tx.inputs[inputN].sequence);
Expand All @@ -92,7 +93,7 @@ final class TaprootSignatureHasher with Writable implements SignatureHasher {
}

// Data specific to matched output
if (hashType.single) {
if (actualHashType.single) {
writer.writeSlice(
PrecomputeHasher.singleOutput(tx.outputs[inputN]).singleHash,
);
Expand Down
9 changes: 7 additions & 2 deletions coinlib/test/tx/sighash/taproot_signature_hasher_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final prevOuts = [

class TaprootSignatureVector {
final int inputN;
final SigHashType hashType;
final SigHashType? hashType;
final String? leafHashHex;
final String sigHashHex;
TaprootSignatureVector({
Expand All @@ -68,8 +68,13 @@ final taprootSigVectors = [
sigHashHex: "325a644af47e8a5a2591cda0ab0723978537318f10e6a63d4eed783b96a71a4d",
),
TaprootSignatureVector(
inputN: 4,
inputN: 3,
hashType: SigHashType.all(),
sigHashHex: "bf013ea93474aa67815b1b6cc441d23b64fa310911d991e713cd34c7f5d46669",
),
TaprootSignatureVector(
inputN: 4,
hashType: null,
sigHashHex: "4f900a0bae3f1446fd48490c2958b5a023228f01661cda3496a11da502a7f7ef",
),
TaprootSignatureVector(
Expand Down

0 comments on commit a3680c4

Please sign in to comment.