From 17f965fd45de4415a8f65ed9efe8a786f51fdd25 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Sat, 9 Nov 2024 12:52:45 -0600 Subject: [PATCH] 2024 11 09 schnorrsig hashtype (#5764) * Add SchnorrDigitalSignature.hashTypeOpt, add DigitalSignature.{hashTypeOpt,appendHashType} * Remove TaprootKeyPath.hashTypeOpt param --- .../util/OrderedSchnorrSignaturesTest.scala | 6 ++- .../core/api/dlcoracle/OracleEvent.scala | 8 ++- .../core/api/dlcoracle/db/EventDb.scala | 2 +- .../crypto/TransactionSignatureChecker.scala | 7 +-- .../core/protocol/dlc/compute/DLCUtil.scala | 3 +- .../core/protocol/script/ScriptWitness.scala | 50 +++---------------- .../org/bitcoins/core/psbt/PSBTMap.scala | 4 +- .../org/bitcoins/crypto/musig/MuSigTest.scala | 5 +- .../crypto/LibSecp256k1CryptoRuntime.scala | 14 ++++-- .../org/bitcoins/crypto/CryptoRuntime.scala | 2 +- .../org/bitcoins/crypto/CryptoUtil.scala | 3 +- .../bitcoins/crypto/DigitalSignature.scala | 5 +- .../crypto/SchnorrDigitalSignature.scala | 38 +++++++++++--- .../org/bitcoins/crypto/musig/MuSigUtil.scala | 2 +- .../bitcoins/dlc/oracle/DLCOracleTest.scala | 38 +++++++++----- .../dlc/oracle/storage/EventDAOTest.scala | 2 +- .../oracle/storage/EventOutcomeDAOTest.scala | 2 +- .../DLCMultiOracleEnumExecutionTest.scala | 2 +- ...MultiOracleExactNumericExecutionTest.scala | 2 +- .../DLCMultiOracleNumericExecutionTest.scala | 2 +- .../dlc/wallet/DLCNumericExecutionTest.scala | 2 +- .../org/bitcoins/dlc/wallet/DLCWallet.scala | 3 +- .../bitcoins/testkitcore/dlc/DLCTest.scala | 2 +- .../testkitcore/gen/CryptoGenerators.scala | 22 +++++++- .../org/bitcoins/testkitcore/gen/TLVGen.scala | 4 +- .../testkitcore/gen/WitnessGenerators.scala | 3 +- 26 files changed, 137 insertions(+), 96 deletions(-) diff --git a/core-test/src/test/scala/org/bitcoins/core/util/OrderedSchnorrSignaturesTest.scala b/core-test/src/test/scala/org/bitcoins/core/util/OrderedSchnorrSignaturesTest.scala index 2c18875ddf..9ebeaa6911 100644 --- a/core-test/src/test/scala/org/bitcoins/core/util/OrderedSchnorrSignaturesTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/util/OrderedSchnorrSignaturesTest.scala @@ -13,13 +13,15 @@ class OrderedSchnorrSignaturesTest extends BitcoinSUnitTest { SchnorrNonce( "c4b89873c8753de3f0a9e94c4a6190badaa983513a6624a3469eb4577904bfea" ), - FieldElement.one + FieldElement.one, + hashTypeOpt = None ), SchnorrDigitalSignature( SchnorrNonce( "92efe81609c773d97da2b084eb691f48ef5e926acc6eecd629f80fb1184711bc" ), - FieldElement.one + FieldElement.one, + hashTypeOpt = None ) ) diff --git a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala index 4236ea516f..5d16b16d51 100644 --- a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala +++ b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala @@ -71,7 +71,8 @@ sealed trait CompletedOracleEvent extends OracleEvent { def signatures: OrderedSchnorrSignatures = { val unsorted = nonces.toVector .zip(attestations) - .map(sigPieces => SchnorrDigitalSignature(sigPieces._1, sigPieces._2)) + .map(sigPieces => + SchnorrDigitalSignature(sigPieces._1, sigPieces._2, hashTypeOpt = None)) OrderedSchnorrSignatures.fromUnsorted(unsorted) } @@ -84,7 +85,10 @@ sealed trait CompletedOracleEvent extends OracleEvent { // announcementSignatures evaluate to true val unsorted = ann.eventTLV.nonces .zip(attestations) - .map(sigPieces => SchnorrDigitalSignature(sigPieces._1, sigPieces._2)) + .map(sigPieces => + SchnorrDigitalSignature(sigPieces._1, + sigPieces._2, + hashTypeOpt = None)) OracleAttestmentV0TLV(eventName, pubkey, unsorted, diff --git a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/db/EventDb.scala b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/db/EventDb.scala index 0b3840aea8..ffa76259a6 100644 --- a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/db/EventDb.scala +++ b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/db/EventDb.scala @@ -37,7 +37,7 @@ case class EventDb( eventDescriptorTLV: EventDescriptorTLV) { lazy val sigOpt: Option[SchnorrDigitalSignature] = - attestationOpt.map(SchnorrDigitalSignature(nonce, _)) + attestationOpt.map(SchnorrDigitalSignature(nonce, _, hashTypeOpt = None)) lazy val toOracleEvent: OracleEvent = OracleEvent.fromEventDbs(Vector(this)) } diff --git a/core/src/main/scala/org/bitcoins/core/crypto/TransactionSignatureChecker.scala b/core/src/main/scala/org/bitcoins/core/crypto/TransactionSignatureChecker.scala index e98f4e281b..8d63ffaceb 100644 --- a/core/src/main/scala/org/bitcoins/core/crypto/TransactionSignatureChecker.scala +++ b/core/src/main/scala/org/bitcoins/core/crypto/TransactionSignatureChecker.scala @@ -74,13 +74,13 @@ trait TransactionSignatureChecker { pubKey: SchnorrPublicKey, witness: TaprootKeyPath, taprootOptions: TaprootSerializationOptions): ScriptResult = { - if (witness.hashTypeOpt.contains(HashType.sigHashDefault)) { + if (witness.signature.hashTypeOpt.contains(HashType.sigHashDefault)) { + // cannot have DEFAULT hash type explicitly defined with BIP341 ScriptErrorSchnorrSigHashType } else { checkSchnorrSignature(txSigComponent = txSigComponent, pubKey = pubKey, schnorrSignature = witness.signature, - hashType = witness.hashType, taprootOptions) } } @@ -89,7 +89,6 @@ trait TransactionSignatureChecker { txSigComponent: TxSigComponent, pubKey: SchnorrPublicKey, schnorrSignature: SchnorrDigitalSignature, - hashType: HashType, taprootOptions: TaprootSerializationOptions): ScriptResult = { require( txSigComponent.sigVersion == SigVersionTaprootKeySpend @@ -97,6 +96,8 @@ trait TransactionSignatureChecker { s"SigVerison must be Taproot or Tapscript, got=${txSigComponent.sigVersion}" ) + val hashType = + schnorrSignature.hashTypeOpt.getOrElse(HashType.sigHashDefault) // bip341 restricts valid hash types: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message val validHashType = checkTaprootHashType(hashType) if (!validHashType) { diff --git a/core/src/main/scala/org/bitcoins/core/protocol/dlc/compute/DLCUtil.scala b/core/src/main/scala/org/bitcoins/core/protocol/dlc/compute/DLCUtil.scala index 92bcdf5ba5..8e60492d2d 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/dlc/compute/DLCUtil.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/dlc/compute/DLCUtil.scala @@ -179,7 +179,8 @@ object DLCUtil { val index = allAdaptorPoints.indexOf(adaptorPoint) val outcome: OracleOutcome = contractInfo.allOutcomes(index) - (SchnorrDigitalSignature(outcome.aggregateNonce, s), outcome) + (SchnorrDigitalSignature(outcome.aggregateNonce, s, hashTypeOpt = None), + outcome) } } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala index 0fc2c07636..7a47684335 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala @@ -263,22 +263,18 @@ object TaprootWitness extends Factory[TaprootWitness] { /** Spending a taproot output via the key path spend */ case class TaprootKeyPath( signature: SchnorrDigitalSignature, - hashTypeOpt: Option[HashType], annexOpt: Option[ByteVector]) extends TaprootWitness { - val hashType: HashType = hashTypeOpt.getOrElse(HashType.sigHashDefault) + val hashType: HashType = + signature.hashTypeOpt.getOrElse(HashType.sigHashDefault) override val stack: Vector[ByteVector] = { - val sig = if (hashType == HashType.sigHashDefault) { - Vector(signature.bytes) - } else Vector(signature.bytes :+ hashType.byte) - annexOpt match { case Some(annex) => - annex +: sig + annex +: Vector(signature.bytes) case None => - sig + Vector(signature.bytes) } } } @@ -294,36 +290,8 @@ object TaprootKeyPath extends Factory[TaprootKeyPath] { } } - def apply( - signature: SchnorrDigitalSignature, - hashType: HashType, - annexOpt: Option[ByteVector]): TaprootKeyPath = { - if (hashType == HashType.sigHashDefault) { - new TaprootKeyPath(signature, None, annexOpt) - } else { - new TaprootKeyPath(signature, Some(hashType), annexOpt) - } - } - - def apply( - signature: SchnorrDigitalSignature, - hashTypeOpt: Option[HashType], - annexOpt: Option[ByteVector]): TaprootKeyPath = { - if (hashTypeOpt.contains(HashType.sigHashDefault)) { - new TaprootKeyPath(signature, None, annexOpt) - } else { - new TaprootKeyPath(signature, hashTypeOpt, annexOpt) - } - } - - def apply( - signature: SchnorrDigitalSignature, - annexOpt: Option[ByteVector]): TaprootKeyPath = { - TaprootKeyPath(signature, None, annexOpt) - } - def apply(signature: SchnorrDigitalSignature): TaprootKeyPath = { - TaprootKeyPath(signature, None, None) + TaprootKeyPath(signature, None) } def fromStack(vec: Vector[ByteVector]): TaprootKeyPath = { @@ -347,15 +315,11 @@ object TaprootKeyPath extends Factory[TaprootKeyPath] { } } - val keyPath = if (sigBytes.length == 64) { + val keyPath = if (sigBytes.length == 64 || sigBytes.length == 65) { // means SIGHASH_DEFAULT is implicitly encoded // see: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#Common_signature_message val sig = SchnorrDigitalSignature.fromBytes(sigBytes) - new TaprootKeyPath(sig, None, annexOpt) - } else if (sigBytes.length == 65) { - val sig = SchnorrDigitalSignature.fromBytes(sigBytes.dropRight(1)) - val hashType = HashType.fromByte(sigBytes.last) - new TaprootKeyPath(sig, Some(hashType), annexOpt) + new TaprootKeyPath(sig, annexOpt) } else { sys.error( s"Unknown sig bytes length, should be 64 or 65, got=${sigBytes.length}") diff --git a/core/src/main/scala/org/bitcoins/core/psbt/PSBTMap.scala b/core/src/main/scala/org/bitcoins/core/psbt/PSBTMap.scala index ebe83c19d0..9c043874b5 100644 --- a/core/src/main/scala/org/bitcoins/core/psbt/PSBTMap.scala +++ b/core/src/main/scala/org/bitcoins/core/psbt/PSBTMap.scala @@ -650,10 +650,8 @@ case class InputPSBTMap(elements: Vector[InputPSBTRecord]) keySpendSignatureOpt match { case Some(keySpendSignature) => val sig = keySpendSignature.signature - val hashType = - sigHashTypeOpt.map(_.hashType).getOrElse(SIGHASH_DEFAULT) - val witnessScript = TaprootKeyPath(sig, hashType, None) + val witnessScript = TaprootKeyPath(sig, None) Success(wipeAndAdd(EmptyScriptSignature, Some(witnessScript))) case None => // todo add script spend support diff --git a/crypto-test/src/test/scala/org/bitcoins/crypto/musig/MuSigTest.scala b/crypto-test/src/test/scala/org/bitcoins/crypto/musig/MuSigTest.scala index b0d0dbd7ba..1a33b23a41 100644 --- a/crypto-test/src/test/scala/org/bitcoins/crypto/musig/MuSigTest.scala +++ b/crypto-test/src/test/scala/org/bitcoins/crypto/musig/MuSigTest.scala @@ -38,7 +38,10 @@ class MuSigTest extends BitcoinSCryptoTest { val sig = signAgg(Vector(s), aggNonce) - assert(sig == SchnorrDigitalSignature(aggNonce.schnorrNonce, s)) + assert( + sig == SchnorrDigitalSignature(aggNonce.schnorrNonce, + s, + hashTypeOpt = None)) val aggPub = keySet.aggPubKey diff --git a/crypto/.jvm/src/main/scala/org/bitcoins/crypto/LibSecp256k1CryptoRuntime.scala b/crypto/.jvm/src/main/scala/org/bitcoins/crypto/LibSecp256k1CryptoRuntime.scala index 2cd35b8cd3..2b8a6e99db 100644 --- a/crypto/.jvm/src/main/scala/org/bitcoins/crypto/LibSecp256k1CryptoRuntime.scala +++ b/crypto/.jvm/src/main/scala/org/bitcoins/crypto/LibSecp256k1CryptoRuntime.scala @@ -186,9 +186,17 @@ trait LibSecp256k1CryptoRuntime extends CryptoRuntime { data: ByteVector, schnorrPubKey: SchnorrPublicKey, signature: SchnorrDigitalSignature): Boolean = { - NativeSecp256k1.schnorrVerify(signature.bytes.toArray, - data.toArray, - schnorrPubKey.bytes.toArray) + if (signature.hashTypeOpt.isDefined) { + // drop hashType byte + NativeSecp256k1.schnorrVerify(signature.bytes.dropRight(1).toArray, + data.toArray, + schnorrPubKey.bytes.toArray) + } else { + NativeSecp256k1.schnorrVerify(signature.bytes.toArray, + data.toArray, + schnorrPubKey.bytes.toArray) + } + } // TODO: add a native implementation diff --git a/crypto/src/main/scala/org/bitcoins/crypto/CryptoRuntime.scala b/crypto/src/main/scala/org/bitcoins/crypto/CryptoRuntime.scala index db5762142a..79f68c7d2a 100644 --- a/crypto/src/main/scala/org/bitcoins/crypto/CryptoRuntime.scala +++ b/crypto/src/main/scala/org/bitcoins/crypto/CryptoRuntime.scala @@ -339,7 +339,7 @@ trait CryptoRuntime { val challenge = x.multiply(FieldElement(e)) val sig = k.add(challenge) - SchnorrDigitalSignature(rx, sig) + SchnorrDigitalSignature(rx, sig, hashTypeOpt = None) } def schnorrVerify( diff --git a/crypto/src/main/scala/org/bitcoins/crypto/CryptoUtil.scala b/crypto/src/main/scala/org/bitcoins/crypto/CryptoUtil.scala index 3369afb569..6e2d236000 100644 --- a/crypto/src/main/scala/org/bitcoins/crypto/CryptoUtil.scala +++ b/crypto/src/main/scala/org/bitcoins/crypto/CryptoUtil.scala @@ -184,8 +184,9 @@ trait CryptoUtil extends CryptoRuntime { override def schnorrVerify( data: ByteVector, schnorrPubKey: SchnorrPublicKey, - signature: SchnorrDigitalSignature): Boolean = + signature: SchnorrDigitalSignature): Boolean = { cryptoRuntime.schnorrVerify(data, schnorrPubKey, signature) + } override def schnorrComputeSigPoint( data: ByteVector, diff --git a/crypto/src/main/scala/org/bitcoins/crypto/DigitalSignature.scala b/crypto/src/main/scala/org/bitcoins/crypto/DigitalSignature.scala index f2ff48f8f9..60dc3b7d5f 100644 --- a/crypto/src/main/scala/org/bitcoins/crypto/DigitalSignature.scala +++ b/crypto/src/main/scala/org/bitcoins/crypto/DigitalSignature.scala @@ -1,3 +1,6 @@ package org.bitcoins.crypto -abstract class DigitalSignature extends NetworkElement +abstract class DigitalSignature extends NetworkElement { + def hashTypeOpt: Option[HashType] + def appendHashType(hashType: HashType): DigitalSignature +} diff --git a/crypto/src/main/scala/org/bitcoins/crypto/SchnorrDigitalSignature.scala b/crypto/src/main/scala/org/bitcoins/crypto/SchnorrDigitalSignature.scala index 21b4348695..5767517de9 100644 --- a/crypto/src/main/scala/org/bitcoins/crypto/SchnorrDigitalSignature.scala +++ b/crypto/src/main/scala/org/bitcoins/crypto/SchnorrDigitalSignature.scala @@ -1,10 +1,31 @@ package org.bitcoins.crypto +import org.bitcoins.crypto.HashType.byte import scodec.bits.ByteVector -case class SchnorrDigitalSignature(rx: SchnorrNonce, sig: FieldElement) +case class SchnorrDigitalSignature( + rx: SchnorrNonce, + sig: FieldElement, + hashTypeOpt: Option[HashType]) extends DigitalSignature { - override val bytes: ByteVector = rx.bytes ++ sig.bytes + override val bytes: ByteVector = { + rx.bytes ++ + sig.bytes ++ + hashTypeOpt + .map(h => ByteVector.fromByte(byte(h))) + .getOrElse(ByteVector.empty) + } + require( + bytes.length == 64 || bytes.length == 65, + s"SchnorrDigitalSignature must be 64/65 bytes in size, got=${bytes.length}") + + override def appendHashType(hashType: HashType): SchnorrDigitalSignature = { + require(this.hashTypeOpt.isEmpty, + "Cannot append HashType to signature which already has HashType") + + val bytesWithHashType = bytes.:+(hashType.byte) + SchnorrDigitalSignature.fromBytes(bytesWithHashType) + } } object SchnorrDigitalSignature extends Factory[SchnorrDigitalSignature] { @@ -12,13 +33,18 @@ object SchnorrDigitalSignature extends Factory[SchnorrDigitalSignature] { // If the sig is 65 bytes long, return sig[64] ≠ 0x00[20] and // Verify(q, hashTapSighash(0x00 || SigMsg(sig[64], 0)), sig[0:64]). override def fromBytes(bytes: ByteVector): SchnorrDigitalSignature = { - require(bytes.length == 64, + require(bytes.length == 64 || bytes.length == 65, s"SchnorrDigitalSignature must be exactly 64 bytes, got $bytes") - SchnorrDigitalSignature(SchnorrNonce(bytes.take(32)), - FieldElement(bytes.drop(32))) + val r = bytes.take(32) + val s = bytes.drop(32).take(32) + val hashTypeOpt = if (bytes.length == 65) Some(bytes(64)) else None + SchnorrDigitalSignature(SchnorrNonce(r), + FieldElement(s), + hashTypeOpt.map(HashType.fromByte)) } lazy val dummy: SchnorrDigitalSignature = SchnorrDigitalSignature(FieldElement.one.getPublicKey.schnorrNonce, - FieldElement.one) + FieldElement.one, + hashTypeOpt = None) } diff --git a/crypto/src/main/scala/org/bitcoins/crypto/musig/MuSigUtil.scala b/crypto/src/main/scala/org/bitcoins/crypto/musig/MuSigUtil.scala index b22b6b9d2d..00e5d281f0 100644 --- a/crypto/src/main/scala/org/bitcoins/crypto/musig/MuSigUtil.scala +++ b/crypto/src/main/scala/org/bitcoins/crypto/musig/MuSigUtil.scala @@ -170,6 +170,6 @@ object MuSigUtil { case None => sSum } - SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s) + SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s, hashTypeOpt = None) } } diff --git a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/DLCOracleTest.scala b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/DLCOracleTest.scala index 09d89851eb..1e5fb059b6 100644 --- a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/DLCOracleTest.scala +++ b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/DLCOracleTest.scala @@ -314,7 +314,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces.head, - completedEvent.attestation + completedEvent.attestation, + hashTypeOpt = None ) == sig ) assert( @@ -368,7 +369,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces.head, - completedEvent.attestations.head + completedEvent.attestations.head, + hashTypeOpt = None ) == signSig ) @@ -382,7 +384,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(1), - completedEvent.attestations(1) + completedEvent.attestations(1), + hashTypeOpt = None ) == sig100 ) @@ -396,7 +399,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(2), - completedEvent.attestations(2) + completedEvent.attestations(2), + hashTypeOpt = None ) == sig10 ) @@ -410,7 +414,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(3), - completedEvent.attestations(3) + completedEvent.attestations(3), + hashTypeOpt = None ) == sig1 ) case _: PendingOracleEvent | _: CompletedOracleEvent => @@ -458,7 +463,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces.head, - completedEvent.attestations.head + completedEvent.attestations.head, + hashTypeOpt = None ) == signSig ) @@ -472,7 +478,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(1), - completedEvent.attestations(1) + completedEvent.attestations(1), + hashTypeOpt = None ) == sig100 ) @@ -486,7 +493,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(2), - completedEvent.attestations(2) + completedEvent.attestations(2), + hashTypeOpt = None ) == sig10 ) @@ -500,7 +508,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(3), - completedEvent.attestations(3) + completedEvent.attestations(3), + hashTypeOpt = None ) == sig1 ) case _: PendingOracleEvent | _: CompletedOracleEvent => @@ -550,7 +559,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces.head, - completedEvent.attestations.head + completedEvent.attestations.head, + hashTypeOpt = None ) == sig100 ) @@ -564,7 +574,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(1), - completedEvent.attestations(1) + completedEvent.attestations(1), + hashTypeOpt = None ) == sig10 ) @@ -578,7 +589,8 @@ class DLCOracleTest extends DLCOracleFixture { assert( SchnorrDigitalSignature( completedEvent.nonces(2), - completedEvent.attestations(2) + completedEvent.attestations(2), + hashTypeOpt = None ) == sig1 ) case _: PendingOracleEvent | _: CompletedOracleEvent => @@ -725,7 +737,7 @@ class DLCOracleTest extends DLCOracleFixture { futureTime, None, None, - SchnorrDigitalSignature(nonce, FieldElement.one), + SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None), testDescriptor ) diff --git a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventDAOTest.scala b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventDAOTest.scala index 056d0b7374..b911dda822 100644 --- a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventDAOTest.scala +++ b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventDAOTest.scala @@ -34,7 +34,7 @@ class EventDAOTest extends DLCOracleDAOFixture { RValueDb(nonce, eventName, HDPurpose(0), HDCoinType.Bitcoin, 0, 0, 0) val dummySig: SchnorrDigitalSignature = - SchnorrDigitalSignature(nonce, FieldElement.one) + SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None) def descriptor: EventDescriptorTLV = TLVGen.eventDescriptorTLV.sampleSome diff --git a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventOutcomeDAOTest.scala b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventOutcomeDAOTest.scala index 6622a06228..86c83fbefa 100644 --- a/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventOutcomeDAOTest.scala +++ b/dlc-oracle-test/src/test/scala/org/bitcoins/dlc/oracle/storage/EventOutcomeDAOTest.scala @@ -49,7 +49,7 @@ class EventOutcomeDAOTest extends DLCOracleDAOFixture { time, None, None, - SchnorrDigitalSignature(nonce, FieldElement.one), + SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None), descriptor ) diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleEnumExecutionTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleEnumExecutionTest.scala index feb50b32bc..bbc79c909b 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleEnumExecutionTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleEnumExecutionTest.scala @@ -216,7 +216,7 @@ class DLCMultiOracleEnumExecutionTest extends BitcoinSDualWalletTest { .reduce(_.add(_)) val aggregateSignature = - SchnorrDigitalSignature(aggR, aggS) + SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None) aggregateSignature == statusB.oracleSig } } diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleExactNumericExecutionTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleExactNumericExecutionTest.scala index cac708dd06..8d188e3a73 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleExactNumericExecutionTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleExactNumericExecutionTest.scala @@ -225,7 +225,7 @@ class DLCMultiOracleExactNumericExecutionTest extends BitcoinSDualWalletTest { .reduce(_.add(_)) val aggregateSignature = - SchnorrDigitalSignature(aggR, aggS) + SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None) aggregateSignature == statusB.oracleSig } } diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleNumericExecutionTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleNumericExecutionTest.scala index ee0a530d57..b09289d8d4 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleNumericExecutionTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCMultiOracleNumericExecutionTest.scala @@ -238,7 +238,7 @@ class DLCMultiOracleNumericExecutionTest .reduce(_.add(_)) val aggregateSignature = - SchnorrDigitalSignature(aggR, aggS) + SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None) aggregateSignature == statusB.oracleSig } } diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCNumericExecutionTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCNumericExecutionTest.scala index 8a0cd88f79..1de378c3f1 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCNumericExecutionTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCNumericExecutionTest.scala @@ -236,7 +236,7 @@ class DLCNumericExecutionTest extends BitcoinSDualWalletTest { .reduce(_.add(_)) val aggregateSignature = - SchnorrDigitalSignature(aggR, aggS) + SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None) aggregateSignature == statusB.oracleSig } } diff --git a/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala b/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala index 6c0273531b..65585d3baa 100644 --- a/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala +++ b/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala @@ -1871,7 +1871,8 @@ case class DLCWallet(override val walletApi: Wallet)(implicit OracleSignatures.computeAggregateSignature(outcome, sigsUsed) aggSig = SchnorrDigitalSignature( outcome.aggregateNonce, - oracleSigSum.fieldElement + oracleSigSum.fieldElement, + hashTypeOpt = None ) _ <- updateAggregateSignature(contractId, aggSig) diff --git a/testkit-core/src/main/scala/org/bitcoins/testkitcore/dlc/DLCTest.scala b/testkit-core/src/main/scala/org/bitcoins/testkitcore/dlc/DLCTest.scala index 689fc378f9..8341c98517 100644 --- a/testkit-core/src/main/scala/org/bitcoins/testkitcore/dlc/DLCTest.scala +++ b/testkit-core/src/main/scala/org/bitcoins/testkitcore/dlc/DLCTest.scala @@ -1290,7 +1290,7 @@ trait DLCTest { sVals.reduce(_.add(_)) } - val aggSig = SchnorrDigitalSignature(aggR, aggS) + val aggSig = SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None) // Must use stored adaptor sigs because adaptor signing nonce is not deterministic (auxRand) val offerRefundSig = dlcOffer.dlcTxSigner.signRefundTx diff --git a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/CryptoGenerators.scala b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/CryptoGenerators.scala index ffd43505f3..aa7adac865 100644 --- a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/CryptoGenerators.scala +++ b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/CryptoGenerators.scala @@ -234,11 +234,29 @@ sealed abstract class CryptoGenerators { } } - def schnorrDigitalSignature: Gen[SchnorrDigitalSignature] = { + def schnorrDigitalSignatureNoHashType: Gen[SchnorrDigitalSignature] = { for { privKey <- privateKey hash <- CryptoGenerators.doubleSha256Digest - } yield privKey.schnorrSign(hash.bytes) + sigNoHashType = privKey.schnorrSign(hash.bytes) + } yield { + sigNoHashType + } + } + + def schnorrDigitalSignatureHashType: Gen[SchnorrDigitalSignature] = { + for { + privKey <- privateKey + hash <- CryptoGenerators.doubleSha256Digest + sigNoHashType = privKey.schnorrSign(hash.bytes) + hashType <- hashType + } yield { + sigNoHashType.appendHashType(hashType) + } + } + def schnorrDigitalSignature: Gen[SchnorrDigitalSignature] = { + Gen.oneOf(schnorrDigitalSignatureHashType, + schnorrDigitalSignatureNoHashType) } def adaptorSignature: Gen[ECAdaptorSignature] = { diff --git a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/TLVGen.scala b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/TLVGen.scala index 9ff1b27638..d4eaf5e879 100644 --- a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/TLVGen.scala +++ b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/TLVGen.scala @@ -146,7 +146,7 @@ trait TLVGen { def oracleAnnouncementV0TLV: Gen[OracleAnnouncementV0TLV] = { for { - sig <- CryptoGenerators.schnorrDigitalSignature + sig <- CryptoGenerators.schnorrDigitalSignatureNoHashType pubkey <- CryptoGenerators.schnorrPublicKey eventTLV <- oracleEventV0TLV } yield OracleAnnouncementV0TLV(sig, pubkey, eventTLV) @@ -159,7 +159,7 @@ trait TLVGen { numSigs <- Gen.choose(1, 10) unsorted <- Gen - .listOfN(numSigs, CryptoGenerators.schnorrDigitalSignature) + .listOfN(numSigs, CryptoGenerators.schnorrDigitalSignatureNoHashType) .map(_.toVector) sigs = OrderedSchnorrSignatures.fromUnsorted(unsorted) outcomes <- diff --git a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/WitnessGenerators.scala b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/WitnessGenerators.scala index 8bb548d9fa..f7dbfa9de7 100644 --- a/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/WitnessGenerators.scala +++ b/testkit-core/src/main/scala/org/bitcoins/testkitcore/gen/WitnessGenerators.scala @@ -45,9 +45,8 @@ sealed abstract class WitnessGenerators { def taprootKeyPath: Gen[TaprootKeyPath] = { for { signature <- CryptoGenerators.schnorrDigitalSignature - hashType <- CryptoGenerators.hashType annexOpt <- Gen.option(annex) - } yield TaprootKeyPath(signature, hashType, annexOpt) + } yield TaprootKeyPath(signature, annexOpt) } def taprootScriptPath: Gen[TaprootScriptPath] = {