Add Sign.{schnorrSign(),schnorrSignWithNonce()} to Sign interface (#5754)

* Add Sign.{schnorrSign(),schnorrSignWithNonce} to Sign interface

* Add schnorrSignWithHashType()
This commit is contained in:
Chris Stewart 2024-11-13 10:42:45 -06:00 committed by GitHub
parent c5d57de618
commit cccaa582bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 87 additions and 21 deletions

View File

@ -37,6 +37,18 @@ case class ConstRandAdaptorSign(privKey: ECPrivateKey) extends AdaptorSign {
): ECAdaptorSignature = {
privKey.adaptorSign(adaptorPoint, msg, auxRand)
}
override def schnorrSign(
dataToSign: ByteVector,
auxRand: ByteVector): SchnorrDigitalSignature = {
privKey.schnorrSign(dataToSign, auxRand)
}
override def schnorrSignWithNonce(
dataToSign: ByteVector,
nonce: ECPrivateKey): SchnorrDigitalSignature = {
privKey.schnorrSignWithNonce(dataToSign, nonce)
}
}
object ConstRandAdaptorSign {

View File

@ -266,6 +266,18 @@ sealed abstract class ExtPrivateKey
def toHardened: ExtPrivateKeyHardened = {
ExtPrivateKeyHardened(version, depth, fingerprint, childNum, chainCode, key)
}
override def schnorrSign(
dataToSign: ByteVector,
auxRand: ByteVector): SchnorrDigitalSignature = {
key.schnorrSign(dataToSign, auxRand)
}
override def schnorrSignWithNonce(
dataToSign: ByteVector,
nonce: ECPrivateKey): SchnorrDigitalSignature = {
key.schnorrSignWithNonce(dataToSign, nonce)
}
}
object ExtPrivateKey

View File

@ -14,7 +14,7 @@ import org.bitcoins.core.wallet.builder.{
import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.core.wallet.signer.BitcoinSigner
import org.bitcoins.core.wallet.utxo.*
import org.bitcoins.crypto.{ECDigitalSignature, HashType, Sign}
import org.bitcoins.crypto.{HashType, Sign}
import scala.annotation.tailrec
import scala.util.{Failure, Success, Try}
@ -173,9 +173,7 @@ object TxUtil {
case (inputInfo, index) =>
val mockSigners =
inputInfo.pubKeys.take(inputInfo.requiredSigs).map { pubKey =>
Sign(_ => ECDigitalSignature.dummy,
(_, _) => ECDigitalSignature.dummy,
pubKey)
Sign.dummySign(pubKey)
}
val mockSpendingInfo =

View File

@ -176,18 +176,13 @@ case class ECPrivateKey(bytes: ByteVector)
CryptoUtil.signWithEntropy(this, bytes, entropy)
}
def schnorrSign(dataToSign: ByteVector): SchnorrDigitalSignature = {
val auxRand = ECPrivateKey.freshPrivateKey.bytes
schnorrSign(dataToSign, auxRand)
}
def schnorrSign(
override def schnorrSign(
dataToSign: ByteVector,
auxRand: ByteVector): SchnorrDigitalSignature = {
CryptoUtil.schnorrSign(dataToSign, this, auxRand)
}
def schnorrSignWithNonce(
override def schnorrSignWithNonce(
dataToSign: ByteVector,
nonce: ECPrivateKey): SchnorrDigitalSignature = {
CryptoUtil.schnorrSignWithNonce(dataToSign, this, nonce)
@ -245,10 +240,6 @@ case class ECPrivateKey(bytes: ByteVector)
override def publicKey: ECPublicKey =
CryptoUtil.publicKey(toPrivateKeyBytes())
def schnorrPublicKey: SchnorrPublicKey = {
SchnorrPublicKey(publicKey.bytes)
}
def toXOnly: XOnlyPubKey = schnorrPublicKey.toXOnly
def schnorrNonce: SchnorrNonce = {

View File

@ -29,7 +29,6 @@ case class SchnorrDigitalSignature(
}
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 = {
@ -43,7 +42,7 @@ object SchnorrDigitalSignature extends Factory[SchnorrDigitalSignature] {
hashTypeOpt.map(HashType.fromByte))
}
lazy val dummy: SchnorrDigitalSignature =
val dummy: SchnorrDigitalSignature =
SchnorrDigitalSignature(FieldElement.one.getPublicKey.schnorrNonce,
FieldElement.one,
hashTypeOpt = None)

View File

@ -62,6 +62,8 @@ trait AsyncSign {
}
def publicKey: ECPublicKey
final def schnorrPublicKey: SchnorrPublicKey = publicKey.schnorrPublicKey
}
object AsyncSign {
@ -196,6 +198,25 @@ trait Sign extends AsyncSign {
ec: ExecutionContext): Future[ECDigitalSignature] = {
Future.successful(signLowR(bytes))
}
final def schnorrSign(dataToSign: ByteVector): SchnorrDigitalSignature = {
val auxRand = ECPrivateKey.freshPrivateKey.bytes
schnorrSign(dataToSign, auxRand)
}
def schnorrSign(
dataToSign: ByteVector,
auxRand: ByteVector): SchnorrDigitalSignature
def schnorrSignWithNonce(
dataToSign: ByteVector,
nonce: ECPrivateKey): SchnorrDigitalSignature
final def schnorrSignWithHashType(
dataToSign: ByteVector,
hashType: HashType): SchnorrDigitalSignature = {
schnorrSign(dataToSign).appendHashType(hashType)
}
}
object Sign {
@ -203,6 +224,10 @@ object Sign {
private case class SignImpl(
signFunction: ByteVector => ECDigitalSignature,
signWithEntropyFunction: (ByteVector, ByteVector) => ECDigitalSignature,
schnorrSignFunction: (ByteVector, ByteVector) => SchnorrDigitalSignature,
schnorrSingWithNonceFunction: (
ByteVector,
ECPrivateKey) => SchnorrDigitalSignature,
override val publicKey: ECPublicKey)
extends Sign {
@ -215,21 +240,50 @@ object Sign {
entropy: ByteVector): ECDigitalSignature = {
signWithEntropyFunction(bytes, entropy)
}
override def schnorrSign(
dataToSign: ByteVector,
auxRand: ByteVector): SchnorrDigitalSignature = {
schnorrSignFunction(dataToSign, auxRand)
}
override def schnorrSignWithNonce(
dataToSign: ByteVector,
nonce: ECPrivateKey): SchnorrDigitalSignature = {
schnorrSingWithNonceFunction(dataToSign, nonce)
}
}
def apply(
sign: ByteVector => ECDigitalSignature,
signWithEntropy: (ByteVector, ByteVector) => ECDigitalSignature,
schnorrSignFunction: (ByteVector, ByteVector) => SchnorrDigitalSignature,
schnorrSingWithNonceFunction: (
ByteVector,
ECPrivateKey) => SchnorrDigitalSignature,
pubKey: ECPublicKey): Sign = {
SignImpl(sign, signWithEntropy, pubKey)
SignImpl(sign,
signWithEntropy,
schnorrSignFunction,
schnorrSingWithNonceFunction,
pubKey)
}
def constant(sig: ECDigitalSignature, pubKey: ECPublicKey): Sign = {
SignImpl(_ => sig, (_, _) => sig, pubKey)
def constant(
sig: ECDigitalSignature,
pubKey: ECPublicKey,
schnorrDigitalSignature: SchnorrDigitalSignature): Sign = {
SignImpl(
signFunction = (_ => sig),
signWithEntropyFunction = ((_, _) => sig),
schnorrSignFunction = (_, _) => schnorrDigitalSignature,
schnorrSingWithNonceFunction = (_, _) => schnorrDigitalSignature,
publicKey = pubKey
)
}
def dummySign(publicKey: ECPublicKey): Sign = {
constant(ECDigitalSignature.empty, publicKey)
constant(ECDigitalSignature.empty, publicKey, SchnorrDigitalSignature.dummy)
}
}