mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
2024 11 09 schnorrsig hashtype (#5764)
* Add SchnorrDigitalSignature.hashTypeOpt, add DigitalSignature.{hashTypeOpt,appendHashType} * Remove TaprootKeyPath.hashTypeOpt param
This commit is contained in:
parent
35fdb07e2d
commit
17f965fd45
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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}")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,6 @@ object MuSigUtil {
|
|||||||
case None => sSum
|
case None => sSum
|
||||||
}
|
}
|
||||||
|
|
||||||
SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s)
|
SchnorrDigitalSignature(aggPubNonce.schnorrNonce, s, hashTypeOpt = None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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] = {
|
||||||
|
@ -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 <-
|
||||||
|
@ -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] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user