2024 11 09 schnorrsig hashtype (#5764)

* Add SchnorrDigitalSignature.hashTypeOpt, add DigitalSignature.{hashTypeOpt,appendHashType}

* Remove TaprootKeyPath.hashTypeOpt param
This commit is contained in:
Chris Stewart 2024-11-09 12:52:45 -06:00 committed by GitHub
parent 35fdb07e2d
commit 17f965fd45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 137 additions and 96 deletions

View File

@ -13,13 +13,15 @@ class OrderedSchnorrSignaturesTest extends BitcoinSUnitTest {
SchnorrNonce( SchnorrNonce(
"c4b89873c8753de3f0a9e94c4a6190badaa983513a6624a3469eb4577904bfea" "c4b89873c8753de3f0a9e94c4a6190badaa983513a6624a3469eb4577904bfea"
), ),
FieldElement.one FieldElement.one,
hashTypeOpt = None
), ),
SchnorrDigitalSignature( SchnorrDigitalSignature(
SchnorrNonce( SchnorrNonce(
"92efe81609c773d97da2b084eb691f48ef5e926acc6eecd629f80fb1184711bc" "92efe81609c773d97da2b084eb691f48ef5e926acc6eecd629f80fb1184711bc"
), ),
FieldElement.one FieldElement.one,
hashTypeOpt = None
) )
) )

View File

@ -71,7 +71,8 @@ sealed trait CompletedOracleEvent extends OracleEvent {
def signatures: OrderedSchnorrSignatures = { def signatures: OrderedSchnorrSignatures = {
val unsorted = nonces.toVector val unsorted = nonces.toVector
.zip(attestations) .zip(attestations)
.map(sigPieces => SchnorrDigitalSignature(sigPieces._1, sigPieces._2)) .map(sigPieces =>
SchnorrDigitalSignature(sigPieces._1, sigPieces._2, hashTypeOpt = None))
OrderedSchnorrSignatures.fromUnsorted(unsorted) OrderedSchnorrSignatures.fromUnsorted(unsorted)
} }
@ -84,7 +85,10 @@ sealed trait CompletedOracleEvent extends OracleEvent {
// announcementSignatures evaluate to true // announcementSignatures evaluate to true
val unsorted = ann.eventTLV.nonces val unsorted = ann.eventTLV.nonces
.zip(attestations) .zip(attestations)
.map(sigPieces => SchnorrDigitalSignature(sigPieces._1, sigPieces._2)) .map(sigPieces =>
SchnorrDigitalSignature(sigPieces._1,
sigPieces._2,
hashTypeOpt = None))
OracleAttestmentV0TLV(eventName, OracleAttestmentV0TLV(eventName,
pubkey, pubkey,
unsorted, unsorted,

View File

@ -37,7 +37,7 @@ case class EventDb(
eventDescriptorTLV: EventDescriptorTLV) { eventDescriptorTLV: EventDescriptorTLV) {
lazy val sigOpt: Option[SchnorrDigitalSignature] = lazy val sigOpt: Option[SchnorrDigitalSignature] =
attestationOpt.map(SchnorrDigitalSignature(nonce, _)) attestationOpt.map(SchnorrDigitalSignature(nonce, _, hashTypeOpt = None))
lazy val toOracleEvent: OracleEvent = OracleEvent.fromEventDbs(Vector(this)) lazy val toOracleEvent: OracleEvent = OracleEvent.fromEventDbs(Vector(this))
} }

View File

@ -74,13 +74,13 @@ trait TransactionSignatureChecker {
pubKey: SchnorrPublicKey, pubKey: SchnorrPublicKey,
witness: TaprootKeyPath, witness: TaprootKeyPath,
taprootOptions: TaprootSerializationOptions): ScriptResult = { 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 ScriptErrorSchnorrSigHashType
} else { } else {
checkSchnorrSignature(txSigComponent = txSigComponent, checkSchnorrSignature(txSigComponent = txSigComponent,
pubKey = pubKey, pubKey = pubKey,
schnorrSignature = witness.signature, schnorrSignature = witness.signature,
hashType = witness.hashType,
taprootOptions) taprootOptions)
} }
} }
@ -89,7 +89,6 @@ trait TransactionSignatureChecker {
txSigComponent: TxSigComponent, txSigComponent: TxSigComponent,
pubKey: SchnorrPublicKey, pubKey: SchnorrPublicKey,
schnorrSignature: SchnorrDigitalSignature, schnorrSignature: SchnorrDigitalSignature,
hashType: HashType,
taprootOptions: TaprootSerializationOptions): ScriptResult = { taprootOptions: TaprootSerializationOptions): ScriptResult = {
require( require(
txSigComponent.sigVersion == SigVersionTaprootKeySpend txSigComponent.sigVersion == SigVersionTaprootKeySpend
@ -97,6 +96,8 @@ trait TransactionSignatureChecker {
s"SigVerison must be Taproot or Tapscript, got=${txSigComponent.sigVersion}" 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 // bip341 restricts valid hash types: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
val validHashType = checkTaprootHashType(hashType) val validHashType = checkTaprootHashType(hashType)
if (!validHashType) { if (!validHashType) {

View File

@ -179,7 +179,8 @@ object DLCUtil {
val index = allAdaptorPoints.indexOf(adaptorPoint) val index = allAdaptorPoints.indexOf(adaptorPoint)
val outcome: OracleOutcome = contractInfo.allOutcomes(index) val outcome: OracleOutcome = contractInfo.allOutcomes(index)
(SchnorrDigitalSignature(outcome.aggregateNonce, s), outcome) (SchnorrDigitalSignature(outcome.aggregateNonce, s, hashTypeOpt = None),
outcome)
} }
} }

View File

@ -263,22 +263,18 @@ object TaprootWitness extends Factory[TaprootWitness] {
/** Spending a taproot output via the key path spend */ /** Spending a taproot output via the key path spend */
case class TaprootKeyPath( case class TaprootKeyPath(
signature: SchnorrDigitalSignature, signature: SchnorrDigitalSignature,
hashTypeOpt: Option[HashType],
annexOpt: Option[ByteVector]) annexOpt: Option[ByteVector])
extends TaprootWitness { extends TaprootWitness {
val hashType: HashType = hashTypeOpt.getOrElse(HashType.sigHashDefault) val hashType: HashType =
signature.hashTypeOpt.getOrElse(HashType.sigHashDefault)
override val stack: Vector[ByteVector] = { override val stack: Vector[ByteVector] = {
val sig = if (hashType == HashType.sigHashDefault) {
Vector(signature.bytes)
} else Vector(signature.bytes :+ hashType.byte)
annexOpt match { annexOpt match {
case Some(annex) => case Some(annex) =>
annex +: sig annex +: Vector(signature.bytes)
case None => 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 = { def apply(signature: SchnorrDigitalSignature): TaprootKeyPath = {
TaprootKeyPath(signature, None, None) TaprootKeyPath(signature, None)
} }
def fromStack(vec: Vector[ByteVector]): TaprootKeyPath = { 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 // means SIGHASH_DEFAULT is implicitly encoded
// see: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#Common_signature_message // see: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#Common_signature_message
val sig = SchnorrDigitalSignature.fromBytes(sigBytes) val sig = SchnorrDigitalSignature.fromBytes(sigBytes)
new TaprootKeyPath(sig, None, annexOpt) new TaprootKeyPath(sig, 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)
} else { } else {
sys.error( sys.error(
s"Unknown sig bytes length, should be 64 or 65, got=${sigBytes.length}") s"Unknown sig bytes length, should be 64 or 65, got=${sigBytes.length}")

View File

@ -650,10 +650,8 @@ case class InputPSBTMap(elements: Vector[InputPSBTRecord])
keySpendSignatureOpt match { keySpendSignatureOpt match {
case Some(keySpendSignature) => case Some(keySpendSignature) =>
val sig = keySpendSignature.signature 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))) Success(wipeAndAdd(EmptyScriptSignature, Some(witnessScript)))
case None => case None =>
// todo add script spend support // todo add script spend support

View File

@ -38,7 +38,10 @@ class MuSigTest extends BitcoinSCryptoTest {
val sig = signAgg(Vector(s), aggNonce) val sig = signAgg(Vector(s), aggNonce)
assert(sig == SchnorrDigitalSignature(aggNonce.schnorrNonce, s)) assert(
sig == SchnorrDigitalSignature(aggNonce.schnorrNonce,
s,
hashTypeOpt = None))
val aggPub = keySet.aggPubKey val aggPub = keySet.aggPubKey

View File

@ -186,9 +186,17 @@ trait LibSecp256k1CryptoRuntime extends CryptoRuntime {
data: ByteVector, data: ByteVector,
schnorrPubKey: SchnorrPublicKey, schnorrPubKey: SchnorrPublicKey,
signature: SchnorrDigitalSignature): Boolean = { signature: SchnorrDigitalSignature): Boolean = {
NativeSecp256k1.schnorrVerify(signature.bytes.toArray, if (signature.hashTypeOpt.isDefined) {
data.toArray, // drop hashType byte
schnorrPubKey.bytes.toArray) 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 // TODO: add a native implementation

View File

@ -339,7 +339,7 @@ trait CryptoRuntime {
val challenge = x.multiply(FieldElement(e)) val challenge = x.multiply(FieldElement(e))
val sig = k.add(challenge) val sig = k.add(challenge)
SchnorrDigitalSignature(rx, sig) SchnorrDigitalSignature(rx, sig, hashTypeOpt = None)
} }
def schnorrVerify( def schnorrVerify(

View File

@ -184,8 +184,9 @@ trait CryptoUtil extends CryptoRuntime {
override def schnorrVerify( override def schnorrVerify(
data: ByteVector, data: ByteVector,
schnorrPubKey: SchnorrPublicKey, schnorrPubKey: SchnorrPublicKey,
signature: SchnorrDigitalSignature): Boolean = signature: SchnorrDigitalSignature): Boolean = {
cryptoRuntime.schnorrVerify(data, schnorrPubKey, signature) cryptoRuntime.schnorrVerify(data, schnorrPubKey, signature)
}
override def schnorrComputeSigPoint( override def schnorrComputeSigPoint(
data: ByteVector, data: ByteVector,

View File

@ -1,3 +1,6 @@
package org.bitcoins.crypto package org.bitcoins.crypto
abstract class DigitalSignature extends NetworkElement abstract class DigitalSignature extends NetworkElement {
def hashTypeOpt: Option[HashType]
def appendHashType(hashType: HashType): DigitalSignature
}

View File

@ -1,10 +1,31 @@
package org.bitcoins.crypto package org.bitcoins.crypto
import org.bitcoins.crypto.HashType.byte
import scodec.bits.ByteVector import scodec.bits.ByteVector
case class SchnorrDigitalSignature(rx: SchnorrNonce, sig: FieldElement) case class SchnorrDigitalSignature(
rx: SchnorrNonce,
sig: FieldElement,
hashTypeOpt: Option[HashType])
extends DigitalSignature { 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] { 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 // If the sig is 65 bytes long, return sig[64] 0x00[20] and
// Verify(q, hashTapSighash(0x00 || SigMsg(sig[64], 0)), sig[0:64]). // Verify(q, hashTapSighash(0x00 || SigMsg(sig[64], 0)), sig[0:64]).
override def fromBytes(bytes: ByteVector): SchnorrDigitalSignature = { 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") s"SchnorrDigitalSignature must be exactly 64 bytes, got $bytes")
SchnorrDigitalSignature(SchnorrNonce(bytes.take(32)), val r = bytes.take(32)
FieldElement(bytes.drop(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 = lazy val dummy: SchnorrDigitalSignature =
SchnorrDigitalSignature(FieldElement.one.getPublicKey.schnorrNonce, SchnorrDigitalSignature(FieldElement.one.getPublicKey.schnorrNonce,
FieldElement.one) FieldElement.one,
hashTypeOpt = None)
} }

View File

@ -170,6 +170,6 @@ object MuSigUtil {
case None => sSum case None => sSum
} }
SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s) SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s, hashTypeOpt = None)
} }
} }

View File

@ -314,7 +314,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces.head, completedEvent.nonces.head,
completedEvent.attestation completedEvent.attestation,
hashTypeOpt = None
) == sig ) == sig
) )
assert( assert(
@ -368,7 +369,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces.head, completedEvent.nonces.head,
completedEvent.attestations.head completedEvent.attestations.head,
hashTypeOpt = None
) == signSig ) == signSig
) )
@ -382,7 +384,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(1), completedEvent.nonces(1),
completedEvent.attestations(1) completedEvent.attestations(1),
hashTypeOpt = None
) == sig100 ) == sig100
) )
@ -396,7 +399,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(2), completedEvent.nonces(2),
completedEvent.attestations(2) completedEvent.attestations(2),
hashTypeOpt = None
) == sig10 ) == sig10
) )
@ -410,7 +414,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(3), completedEvent.nonces(3),
completedEvent.attestations(3) completedEvent.attestations(3),
hashTypeOpt = None
) == sig1 ) == sig1
) )
case _: PendingOracleEvent | _: CompletedOracleEvent => case _: PendingOracleEvent | _: CompletedOracleEvent =>
@ -458,7 +463,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces.head, completedEvent.nonces.head,
completedEvent.attestations.head completedEvent.attestations.head,
hashTypeOpt = None
) == signSig ) == signSig
) )
@ -472,7 +478,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(1), completedEvent.nonces(1),
completedEvent.attestations(1) completedEvent.attestations(1),
hashTypeOpt = None
) == sig100 ) == sig100
) )
@ -486,7 +493,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(2), completedEvent.nonces(2),
completedEvent.attestations(2) completedEvent.attestations(2),
hashTypeOpt = None
) == sig10 ) == sig10
) )
@ -500,7 +508,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(3), completedEvent.nonces(3),
completedEvent.attestations(3) completedEvent.attestations(3),
hashTypeOpt = None
) == sig1 ) == sig1
) )
case _: PendingOracleEvent | _: CompletedOracleEvent => case _: PendingOracleEvent | _: CompletedOracleEvent =>
@ -550,7 +559,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces.head, completedEvent.nonces.head,
completedEvent.attestations.head completedEvent.attestations.head,
hashTypeOpt = None
) == sig100 ) == sig100
) )
@ -564,7 +574,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(1), completedEvent.nonces(1),
completedEvent.attestations(1) completedEvent.attestations(1),
hashTypeOpt = None
) == sig10 ) == sig10
) )
@ -578,7 +589,8 @@ class DLCOracleTest extends DLCOracleFixture {
assert( assert(
SchnorrDigitalSignature( SchnorrDigitalSignature(
completedEvent.nonces(2), completedEvent.nonces(2),
completedEvent.attestations(2) completedEvent.attestations(2),
hashTypeOpt = None
) == sig1 ) == sig1
) )
case _: PendingOracleEvent | _: CompletedOracleEvent => case _: PendingOracleEvent | _: CompletedOracleEvent =>
@ -725,7 +737,7 @@ class DLCOracleTest extends DLCOracleFixture {
futureTime, futureTime,
None, None,
None, None,
SchnorrDigitalSignature(nonce, FieldElement.one), SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None),
testDescriptor testDescriptor
) )

View File

@ -34,7 +34,7 @@ class EventDAOTest extends DLCOracleDAOFixture {
RValueDb(nonce, eventName, HDPurpose(0), HDCoinType.Bitcoin, 0, 0, 0) RValueDb(nonce, eventName, HDPurpose(0), HDCoinType.Bitcoin, 0, 0, 0)
val dummySig: SchnorrDigitalSignature = val dummySig: SchnorrDigitalSignature =
SchnorrDigitalSignature(nonce, FieldElement.one) SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None)
def descriptor: EventDescriptorTLV = TLVGen.eventDescriptorTLV.sampleSome def descriptor: EventDescriptorTLV = TLVGen.eventDescriptorTLV.sampleSome

View File

@ -49,7 +49,7 @@ class EventOutcomeDAOTest extends DLCOracleDAOFixture {
time, time,
None, None,
None, None,
SchnorrDigitalSignature(nonce, FieldElement.one), SchnorrDigitalSignature(nonce, FieldElement.one, hashTypeOpt = None),
descriptor descriptor
) )

View File

@ -216,7 +216,7 @@ class DLCMultiOracleEnumExecutionTest extends BitcoinSDualWalletTest {
.reduce(_.add(_)) .reduce(_.add(_))
val aggregateSignature = val aggregateSignature =
SchnorrDigitalSignature(aggR, aggS) SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None)
aggregateSignature == statusB.oracleSig aggregateSignature == statusB.oracleSig
} }
} }

View File

@ -225,7 +225,7 @@ class DLCMultiOracleExactNumericExecutionTest extends BitcoinSDualWalletTest {
.reduce(_.add(_)) .reduce(_.add(_))
val aggregateSignature = val aggregateSignature =
SchnorrDigitalSignature(aggR, aggS) SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None)
aggregateSignature == statusB.oracleSig aggregateSignature == statusB.oracleSig
} }
} }

View File

@ -238,7 +238,7 @@ class DLCMultiOracleNumericExecutionTest
.reduce(_.add(_)) .reduce(_.add(_))
val aggregateSignature = val aggregateSignature =
SchnorrDigitalSignature(aggR, aggS) SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None)
aggregateSignature == statusB.oracleSig aggregateSignature == statusB.oracleSig
} }
} }

View File

@ -236,7 +236,7 @@ class DLCNumericExecutionTest extends BitcoinSDualWalletTest {
.reduce(_.add(_)) .reduce(_.add(_))
val aggregateSignature = val aggregateSignature =
SchnorrDigitalSignature(aggR, aggS) SchnorrDigitalSignature(aggR, aggS, hashTypeOpt = None)
aggregateSignature == statusB.oracleSig aggregateSignature == statusB.oracleSig
} }
} }

View File

@ -1871,7 +1871,8 @@ case class DLCWallet(override val walletApi: Wallet)(implicit
OracleSignatures.computeAggregateSignature(outcome, sigsUsed) OracleSignatures.computeAggregateSignature(outcome, sigsUsed)
aggSig = SchnorrDigitalSignature( aggSig = SchnorrDigitalSignature(
outcome.aggregateNonce, outcome.aggregateNonce,
oracleSigSum.fieldElement oracleSigSum.fieldElement,
hashTypeOpt = None
) )
_ <- updateAggregateSignature(contractId, aggSig) _ <- updateAggregateSignature(contractId, aggSig)

View File

@ -1290,7 +1290,7 @@ trait DLCTest {
sVals.reduce(_.add(_)) 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) // Must use stored adaptor sigs because adaptor signing nonce is not deterministic (auxRand)
val offerRefundSig = dlcOffer.dlcTxSigner.signRefundTx val offerRefundSig = dlcOffer.dlcTxSigner.signRefundTx

View File

@ -234,11 +234,29 @@ sealed abstract class CryptoGenerators {
} }
} }
def schnorrDigitalSignature: Gen[SchnorrDigitalSignature] = { def schnorrDigitalSignatureNoHashType: Gen[SchnorrDigitalSignature] = {
for { for {
privKey <- privateKey privKey <- privateKey
hash <- CryptoGenerators.doubleSha256Digest 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] = { def adaptorSignature: Gen[ECAdaptorSignature] = {

View File

@ -146,7 +146,7 @@ trait TLVGen {
def oracleAnnouncementV0TLV: Gen[OracleAnnouncementV0TLV] = { def oracleAnnouncementV0TLV: Gen[OracleAnnouncementV0TLV] = {
for { for {
sig <- CryptoGenerators.schnorrDigitalSignature sig <- CryptoGenerators.schnorrDigitalSignatureNoHashType
pubkey <- CryptoGenerators.schnorrPublicKey pubkey <- CryptoGenerators.schnorrPublicKey
eventTLV <- oracleEventV0TLV eventTLV <- oracleEventV0TLV
} yield OracleAnnouncementV0TLV(sig, pubkey, eventTLV) } yield OracleAnnouncementV0TLV(sig, pubkey, eventTLV)
@ -159,7 +159,7 @@ trait TLVGen {
numSigs <- Gen.choose(1, 10) numSigs <- Gen.choose(1, 10)
unsorted <- unsorted <-
Gen Gen
.listOfN(numSigs, CryptoGenerators.schnorrDigitalSignature) .listOfN(numSigs, CryptoGenerators.schnorrDigitalSignatureNoHashType)
.map(_.toVector) .map(_.toVector)
sigs = OrderedSchnorrSignatures.fromUnsorted(unsorted) sigs = OrderedSchnorrSignatures.fromUnsorted(unsorted)
outcomes <- outcomes <-

View File

@ -45,9 +45,8 @@ sealed abstract class WitnessGenerators {
def taprootKeyPath: Gen[TaprootKeyPath] = { def taprootKeyPath: Gen[TaprootKeyPath] = {
for { for {
signature <- CryptoGenerators.schnorrDigitalSignature signature <- CryptoGenerators.schnorrDigitalSignature
hashType <- CryptoGenerators.hashType
annexOpt <- Gen.option(annex) annexOpt <- Gen.option(annex)
} yield TaprootKeyPath(signature, hashType, annexOpt) } yield TaprootKeyPath(signature, annexOpt)
} }
def taprootScriptPath: Gen[TaprootScriptPath] = { def taprootScriptPath: Gen[TaprootScriptPath] = {