mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-26 21:42:48 +01:00
Schnorr sig parsing checks (#4482)
This commit is contained in:
parent
ec599a5c3d
commit
3821060e68
1 changed files with 27 additions and 40 deletions
|
@ -20,6 +20,8 @@ import org.bitcoins.core.util.BitcoinScriptUtil
|
||||||
import org.bitcoins.crypto._
|
import org.bitcoins.crypto._
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
/** Created by chris on 1/6/16.
|
/** Created by chris on 1/6/16.
|
||||||
*/
|
*/
|
||||||
sealed abstract class CryptoInterpreter {
|
sealed abstract class CryptoInterpreter {
|
||||||
|
@ -154,33 +156,22 @@ sealed abstract class CryptoInterpreter {
|
||||||
* if the signature is the empty byte vector which trivially
|
* if the signature is the empty byte vector which trivially
|
||||||
* fails script interpreter validation
|
* fails script interpreter validation
|
||||||
*/
|
*/
|
||||||
private def getSignatureAndHashType(
|
private def getSignatureAndHashType(sigBytes: ByteVector): Either[
|
||||||
stack: List[ScriptToken],
|
ScriptError,
|
||||||
isCheckSigAdd: Boolean): Option[(SchnorrDigitalSignature, HashType)] = {
|
(SchnorrDigitalSignature, HashType)] = {
|
||||||
val sigBytes = {
|
val parseT = Try(if (sigBytes.length == 64) {
|
||||||
if (isCheckSigAdd) {
|
val sig = SchnorrDigitalSignature.fromBytes(sigBytes)
|
||||||
stack(2).bytes
|
Right((sig, HashType.sigHashDefault))
|
||||||
} else {
|
} else if (sigBytes.length == 65) {
|
||||||
stack.tail.head.bytes
|
val hashTypeByte = sigBytes.last
|
||||||
}
|
val hashType = HashType.fromByte(hashTypeByte)
|
||||||
}
|
val sig = SchnorrDigitalSignature.fromBytes(sigBytes.dropRight(1))
|
||||||
val sigHashTypeOpt: Option[(SchnorrDigitalSignature, HashType)] = {
|
Right((sig, hashType))
|
||||||
if (sigBytes.length == 64) {
|
} else {
|
||||||
val sig = SchnorrDigitalSignature.fromBytes(sigBytes)
|
Left(ScriptErrorSchnorrSigSize)
|
||||||
Some((sig, HashType.sigHashDefault))
|
})
|
||||||
} else if (sigBytes.length == 65) {
|
|
||||||
val hashTypeByte = sigBytes.last
|
parseT.getOrElse(Left(ScriptErrorSchnorrSig))
|
||||||
val hashType = HashType.fromByte(hashTypeByte)
|
|
||||||
val sig = SchnorrDigitalSignature.fromBytes(sigBytes.dropRight(1))
|
|
||||||
Some((sig, hashType))
|
|
||||||
} else if (sigBytes.isEmpty) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
sys.error(
|
|
||||||
s"Incorrect length for schnorr digital signature, got=${sigBytes.length}, expected 64 or 65 sigBytes=${sigBytes}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sigHashTypeOpt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def evalChecksigTapscript(
|
private def evalChecksigTapscript(
|
||||||
|
@ -226,19 +217,15 @@ sealed abstract class CryptoInterpreter {
|
||||||
sys.error(s"Invalid pubkey with 32 bytes in size, got=${xOnlyPubKeyT}")
|
sys.error(s"Invalid pubkey with 32 bytes in size, got=${xOnlyPubKeyT}")
|
||||||
} else {
|
} else {
|
||||||
val helperE: Either[ScriptError, TapscriptChecksigHelper] = {
|
val helperE: Either[ScriptError, TapscriptChecksigHelper] = {
|
||||||
val sigHashTypeOpt = getSignatureAndHashType(stack, isCheckSigAdd)
|
val sigHashTypeE = getSignatureAndHashType(sigBytes)
|
||||||
sigHashTypeOpt match {
|
sigHashTypeE.map { case (signature, hashType) =>
|
||||||
case Some((signature, hashType)) =>
|
val restOfStack =
|
||||||
val restOfStack =
|
program.stack.tail.tail //remove pubkey, signature
|
||||||
program.stack.tail.tail //remove pubkey, signature
|
val helper = TapscriptChecksigHelper(pubKey = xOnlyPubKeyT.get,
|
||||||
val helper = TapscriptChecksigHelper(pubKey = xOnlyPubKeyT.get,
|
signature = signature,
|
||||||
signature = signature,
|
hashType = hashType,
|
||||||
hashType = hashType,
|
restOfStack = restOfStack)
|
||||||
restOfStack = restOfStack)
|
helper
|
||||||
Right(helper)
|
|
||||||
case None =>
|
|
||||||
//this is because the signature was empty
|
|
||||||
Left(ScriptErrorEvalFalse)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
helperE match {
|
helperE match {
|
||||||
|
|
Loading…
Add table
Reference in a new issue