Merge pull request #29 from Christewart/der_encoding_bug

Der encoding bug
This commit is contained in:
Thomas McCabe 2016-08-22 09:14:17 -05:00 committed by GitHub
commit 00acabba14
9 changed files with 82 additions and 47 deletions

View File

@ -13,6 +13,7 @@ trait DERSignatureUtil extends BitcoinSLogger {
/** /**
* Checks if this signature is encoded to DER correctly * Checks if this signature is encoded to DER correctly
* https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1 * https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1
* NOTE: This will fail if this signature contains the hash type appended to the end of it
* @return boolean representing if the signature is a valid * @return boolean representing if the signature is a valid
*/ */
def isDEREncoded(signature : ECDigitalSignature) : Boolean = isDEREncoded(signature.bytes) def isDEREncoded(signature : ECDigitalSignature) : Boolean = isDEREncoded(signature.bytes)
@ -20,22 +21,22 @@ trait DERSignatureUtil extends BitcoinSLogger {
/** /**
* Checks if the bytes are encoded to DER correctly * Checks if the bytes are encoded to DER correctly
* https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1 * https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1
* This will fail if this signature contains the hash type appended to the end of it
* @return boolean representing if the signature is a valid * @return boolean representing if the signature is a valid
*/ */
def isDEREncoded(bytes : Seq[Byte]) : Boolean = { def isDEREncoded(bytes : Seq[Byte]) : Boolean = {
//signature is trivially valid if the signature is empty //signature is trivially valid if the signature is empty
if (bytes.nonEmpty && bytes.size < 9) false
if (!bytes.isEmpty && bytes.size < 9) false else if (bytes.nonEmpty) {
else if (!bytes.isEmpty) {
//first byte must be 0x30 //first byte must be 0x30
val firstByteIs0x30 = bytes.head == 0x30 val firstByteIs0x30 = bytes.head == 0x30
logger.debug("firstByteIs0x30: " + firstByteIs0x30) logger.debug("firstByteIs0x30: " + firstByteIs0x30)
//second byte must indicate the length of the remaining byte array //second byte must indicate the length of the remaining byte array
val signatureSize = bytes(1).toLong val signatureSize = bytes(1).toLong
logger.debug("Encoded Sisgnature Size: " + signatureSize) logger.debug("Encoded Sisgnature Size: " + signatureSize)
logger.debug("Actual Signature Size: " + bytes.slice(3,bytes.size).size) logger.debug("Actual Signature Size: " + bytes.slice(2,bytes.size).size)
//checks to see if the signature length is the same as the signatureSize val //checks to see if the signature length is the same as the signatureSize val
val signatureLengthIsCorrect = signatureSize == bytes.slice(3,bytes.size).size val signatureLengthIsCorrect = signatureSize == bytes.slice(2,bytes.size).size
logger.debug("Signature length is correct: " + signatureLengthIsCorrect) logger.debug("Signature length is correct: " + signatureLengthIsCorrect)
//third byte must be 0x02 //third byte must be 0x02
val thirdByteIs0x02 = bytes(2) == 0x02 val thirdByteIs0x02 = bytes(2) == 0x02
@ -114,14 +115,15 @@ trait DERSignatureUtil extends BitcoinSLogger {
/** /**
* This functions implements the strict der encoding rules that were created in BIP66 * This functions implements the strict der encoding rules that were created in BIP66
* https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki * [[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki]]
* [[https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L98]]
* @param signature the signature to check if they are strictly der encoded * @param signature the signature to check if they are strictly der encoded
* @return boolean indicating whether the signature was der encoded or not * @return boolean indicating whether the signature was der encoded or not
*/ */
def isStrictDEREncoding(signature : ECDigitalSignature) : Boolean = { def isValidSignatureEncoding(signature : ECDigitalSignature) : Boolean = {
signature match { signature match {
case EmptyDigitalSignature => true case EmptyDigitalSignature => true
case signature : ECDigitalSignature => isStrictDEREncoding(signature.bytes) case signature : ECDigitalSignature => isValidSignatureEncoding(signature.bytes)
} }
} }
@ -129,10 +131,11 @@ trait DERSignatureUtil extends BitcoinSLogger {
/** /**
* This functions implements the strict der encoding rules that were created in BIP66 * This functions implements the strict der encoding rules that were created in BIP66
* https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki * https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
* [[https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L98]]
* @param bytes the bytes to check if they are strictly der encoded * @param bytes the bytes to check if they are strictly der encoded
* @return boolean indicating whether the bytes were der encoded or not * @return boolean indicating whether the bytes were der encoded or not
*/ */
def isStrictDEREncoding(bytes : Seq[Byte]) : Boolean = { def isValidSignatureEncoding(bytes : Seq[Byte]) : Boolean = {
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
// * total-length: 1-byte length descriptor of everything that follows, // * total-length: 1-byte length descriptor of everything that follows,
// excluding the sighash byte. // excluding the sighash byte.
@ -150,9 +153,9 @@ trait DERSignatureUtil extends BitcoinSLogger {
if (bytes.size == 0) return true if (bytes.size == 0) return true
//check if the bytes are ATLEAST der encoded //check if the bytes are ATLEAST der encoded
val isDerEncoded = isDEREncoded(bytes) /* val isDerEncoded = isDEREncoded(bytes)
if (!isDerEncoded) return false if (!isDerEncoded) return false
logger.debug("Signature is at minimum DER encoded") logger.debug("Signature is at minimum DER encoded")*/
if (bytes.size < 9) return false if (bytes.size < 9) return false
logger.debug("signature is the minimum size for strict der encoding") logger.debug("signature is the minimum size for strict der encoding")
@ -222,26 +225,34 @@ trait DERSignatureUtil extends BitcoinSLogger {
/** /**
* Requires the S value in signatures to be the low version of the S value * Requires the S value in signatures to be the low version of the S value
* https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures * https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures
*
* @param signature * @param signature
* @return if the S value is the low version * @return if the S value is the low version
*/ */
def isLowDerSignature(signature : ECDigitalSignature) : Boolean = isLowDerSignature(signature.bytes) def isLowS(signature : ECDigitalSignature) : Boolean = isLowS(signature.bytes)
/** /**
* Requires the S value in signatures to be the low version of the S value * Requires the S value in signatures to be the low version of the S value
* https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures * https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures
*
* @param signature * @param signature
* @return if the S value is the low version * @return if the S value is the low version
*/ */
def isLowDerSignature(signature : Seq[Byte]) : Boolean = { def isLowS(signature : Seq[Byte]) : Boolean = {
if (!isDEREncoded(signature)) false val result = Try {
else {
val (r,s) = decodeSignature(signature) val (r,s) = decodeSignature(signature)
val upperBound = BigInt("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0",16) s.bigInteger.compareTo(CryptoParams.halfCurveOrder) <= 0
s >= 0x1 && s <= upperBound
} }
result match {
case Success(bool) => bool
case Failure(_) => false
}
}
/** Checks if the given digital signature uses a low s value, if it does not it converts it to a low s value and returns it */
def lowS(signature: ECDigitalSignature): ECDigitalSignature = {
val sigLowS = if (isLowS(signature)) signature
else ECDigitalSignature(signature.r,CryptoParams.curve.getN().subtract(signature.s.bigInteger))
require(DERSignatureUtil.isLowS(sigLowS))
sigLowS
} }
} }

View File

@ -17,17 +17,21 @@ sealed trait ECDigitalSignature extends BitcoinSLogger {
/** /**
* Checks if this signature is encoded to DER correctly * Checks if this signature is encoded to DER correctly
* https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1 * https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1
* *
* @return boolean representing if the signature is a valid * @return boolean representing if the signature is a valid
*/ */
def isDEREncoded : Boolean = DERSignatureUtil.isDEREncoded(this) def isDEREncoded : Boolean = DERSignatureUtil.isDEREncoded(this)
/** Checks if the signature is strictly der encoded as per BIP66
* [[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki]]
* */
def isStrictEncoded: Boolean = DERSignatureUtil.isValidSignatureEncoding(this)
/** /**
* Decodes the digital signature into it's r and s points * Decodes the digital signature into it's r and s points
* throws an exception if the given sequence of bytes is not a DER encoded signature * throws an exception if the given sequence of bytes is not a DER encoded signature
* *
* @return the (r,s) values for the elliptic curve digital signature * @return the (r,s) values for the elliptic curve digital signature
*/ */
def decodeSignature : (BigInt,BigInt) = DERSignatureUtil.decodeSignature(this) def decodeSignature : (BigInt,BigInt) = DERSignatureUtil.decodeSignature(this)
@ -40,8 +44,8 @@ sealed trait ECDigitalSignature extends BitcoinSLogger {
/** /**
* Represents the s value found in a elliptic curve digital signature * Represents the s value found in a elliptic curve digital signature
* *
* @return * @return
*/ */
def s = decodeSignature._2 def s = decodeSignature._2
@ -61,7 +65,13 @@ object ECDigitalSignature extends Factory[ECDigitalSignature] {
//this represents the empty signature //this represents the empty signature
if (bytes.size == 1 && bytes.head == 0x0) EmptyDigitalSignature if (bytes.size == 1 && bytes.head == 0x0) EmptyDigitalSignature
else if (bytes.size == 0) EmptyDigitalSignature else if (bytes.size == 0) EmptyDigitalSignature
else ECDigitalSignatureImpl(bytes) else {
//make sure the signature follows BIP62's low-s value
//https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures
//bitcoinj implementation
//https://github.com/bitcoinj/bitcoinj/blob/1e66b9a8e38d9ad425507bf5f34d64c5d3d23bb8/core/src/main/java/org/bitcoinj/core/ECKey.java#L551
ECDigitalSignatureImpl(bytes)
}
} }
def apply(r : BigInt, s : BigInt) = fromRS(r,s) def apply(r : BigInt, s : BigInt) = fromRS(r,s)
@ -69,6 +79,7 @@ object ECDigitalSignature extends Factory[ECDigitalSignature] {
* Takes in the r and s component of a digital signature and gives back a ECDigitalSignature object * Takes in the r and s component of a digital signature and gives back a ECDigitalSignature object
* The ECDigitalSignature object complies with strict der encoding as per BIP62 * The ECDigitalSignature object complies with strict der encoding as per BIP62
* note: That the hash type for the signature CANNOT be added to the digital signature * note: That the hash type for the signature CANNOT be added to the digital signature
*
* @param r the r component of the digital signature * @param r the r component of the digital signature
* @param s the s component of the digital signature * @param s the s component of the digital signature
* @return * @return
@ -80,4 +91,12 @@ object ECDigitalSignature extends Factory[ECDigitalSignature] {
r.toByteArray.toSeq ++ Seq(0x2.toByte, s.toByteArray.size.toByte) ++ s.toByteArray.toSeq r.toByteArray.toSeq ++ Seq(0x2.toByte, s.toByteArray.size.toByte) ++ s.toByteArray.toSeq
fromBytes(bytes) fromBytes(bytes)
} }
/** Checks if the given digital signature uses a low s value,
* if it does not it converts it to a low s value and returns it */
private def lowS(signature: ECDigitalSignature): ECDigitalSignature = {
if (signature.s.bigInteger.compareTo(CryptoParams.halfCurveOrder) <= 0) signature
else ECDigitalSignature(signature.r,CryptoParams.curve.getN().subtract(signature.s.bigInteger))
}
} }

View File

@ -36,10 +36,10 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
pubKey: ECPublicKey, signature : ECDigitalSignature, flags : Seq[ScriptFlag]) : TransactionSignatureCheckerResult = { pubKey: ECPublicKey, signature : ECDigitalSignature, flags : Seq[ScriptFlag]) : TransactionSignatureCheckerResult = {
logger.info("Signature: " + signature) logger.info("Signature: " + signature)
val pubKeyEncodedCorrectly = BitcoinScriptUtil.checkPubKeyEncoding(pubKey,flags) val pubKeyEncodedCorrectly = BitcoinScriptUtil.checkPubKeyEncoding(pubKey,flags)
if (ScriptFlagUtil.requiresStrictDerEncoding(flags) && !DERSignatureUtil.isStrictDEREncoding(signature)) { if (ScriptFlagUtil.requiresStrictDerEncoding(flags) && !DERSignatureUtil.isValidSignatureEncoding(signature)) {
logger.error("Signature was not stricly encoded der: " + signature.hex) logger.error("Signature was not stricly encoded der: " + signature.hex)
SignatureValidationFailureNotStrictDerEncoding SignatureValidationFailureNotStrictDerEncoding
} else if (ScriptFlagUtil.requireLowSValue(flags) && !DERSignatureUtil.isLowDerSignature(signature)) { } else if (ScriptFlagUtil.requireLowSValue(flags) && !DERSignatureUtil.isLowS(signature)) {
logger.error("Signature did not have a low s value") logger.error("Signature did not have a low s value")
ScriptValidationFailureHighSValue ScriptValidationFailureHighSValue
} else if (ScriptFlagUtil.requireStrictEncoding(flags) && signature.bytes.nonEmpty && } else if (ScriptFlagUtil.requireStrictEncoding(flags) && signature.bytes.nonEmpty &&

View File

@ -9,7 +9,6 @@ trait TransactionSignatureCreator {
/** /**
* Creates a signature from a tx signature component * Creates a signature from a tx signature component
*
* @param txSignatureComponent contains the tx, inputIndex which specify which input we are creating a sig for * @param txSignatureComponent contains the tx, inputIndex which specify which input we are creating a sig for
* @param privateKey the private key which we are signing the hash with * @param privateKey the private key which we are signing the hash with
* @param hashType the procedure to use for hashing to transaction * @param hashType the procedure to use for hashing to transaction
@ -19,7 +18,9 @@ trait TransactionSignatureCreator {
val hash = TransactionSignatureSerializer.hashForSignature(txSignatureComponent, hashType) val hash = TransactionSignatureSerializer.hashForSignature(txSignatureComponent, hashType)
val signature = privateKey.sign(hash) val signature = privateKey.sign(hash)
//append 1 byte hash type onto the end //append 1 byte hash type onto the end
ECDigitalSignature(signature.bytes ++ Seq(hashType.byte)) val sig = ECDigitalSignature(signature.bytes ++ Seq(hashType.byte))
require(sig.isStrictEncoded, "We did not create a signature that is strictly encoded, got: " + sig)
sig
} }
} }

View File

@ -93,7 +93,7 @@ trait CryptoInterpreter extends ControlOperationsInterpreter with BitcoinSLogger
val signature = ECDigitalSignature(executionInProgressScriptProgram.stack.tail.head.bytes) val signature = ECDigitalSignature(executionInProgressScriptProgram.stack.tail.head.bytes)
if (ScriptFlagUtil.requiresStrictDerEncoding(executionInProgressScriptProgram.flags) && if (ScriptFlagUtil.requiresStrictDerEncoding(executionInProgressScriptProgram.flags) &&
!DERSignatureUtil.isStrictDEREncoding(signature)) { !DERSignatureUtil.isValidSignatureEncoding(signature)) {
//this means all of the signatures must encoded according to BIP66 strict dersig //this means all of the signatures must encoded according to BIP66 strict dersig
//https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki //https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
//script verification fails since the sig is not strictly der encoded //script verification fails since the sig is not strictly der encoded

View File

@ -1,12 +1,12 @@
package org.bitcoins.core.serializers package org.bitcoins.core.serializers
import org.bitcoins.core.util.BitcoinSUtil import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
/** /**
* Created by chris on 1/11/16. * Created by chris on 1/11/16.
* A common trait for reading/writing bitcoin objects to/from bytes/hex * A common trait for reading/writing bitcoin objects to/from bytes/hex
*/ */
trait RawBitcoinSerializer[T] extends RawBitcoinSerializerHelper { trait RawBitcoinSerializer[T] extends RawBitcoinSerializerHelper with BitcoinSLogger {
/** /**
* Reads a hexadecimal value and transforms it into the native * Reads a hexadecimal value and transforms it into the native

View File

@ -11,17 +11,20 @@ class DERSignatureUtilTest extends FlatSpec with MustMatchers {
val p2shSignature = ECDigitalSignature("304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001") val p2shSignature = ECDigitalSignature("304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001")
val p2pkhSignature = ECDigitalSignature("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01") val p2pkhSignature = ECDigitalSignature("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01")
val p2pkSignature = ECDigitalSignature("304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001") val p2pkSignature = ECDigitalSignature("304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001")
"DERSignatureUtil" must "say that a signature taken from a p2sh transaction is a valid DER encoded signature" in { "DERSignatureUtil" must "say that a signature taken from a p2sh transaction is a valid DER encoded signature" in {
DERSignatureUtil.isDEREncoded(p2shSignature) must be (true) DERSignatureUtil.isValidSignatureEncoding(p2shSignature) must be (true)
} }
it must "say that signature taken from a p2pkh transaction is a valid DER encoded signature" in { it must "say that signature taken from a p2pkh transaction is a valid DER encoded signature" in {
DERSignatureUtil.isDEREncoded(p2pkhSignature) must be (true) //need to remove the hash type byte to check for der encoding
val hashTypeByteRemoved = p2pkhSignature.bytes.slice(0,p2pkhSignature.bytes.size-1)
DERSignatureUtil.isDEREncoded(hashTypeByteRemoved) must be (true)
} }
it must "say that a signature taken from a p2pk transaction is a valid DER encoded signature" in { it must "say that a signature taken from a p2pk transaction is a valid DER encoded signature" in {
val hashTypeByteRemoved = p2pkSignature.bytes.slice(0,p2pkSignature.bytes.size-1)
DERSignatureUtil.isDEREncoded(p2pkSignature) must be (true) DERSignatureUtil.isDEREncoded(hashTypeByteRemoved) must be (true)
} }
it must "retrieve the (r,s) values for a p2sh signature in bitcoin" in { it must "retrieve the (r,s) values for a p2sh signature in bitcoin" in {
@ -43,32 +46,32 @@ class DERSignatureUtilTest extends FlatSpec with MustMatchers {
} }
it must "say that a signature taken from a p2sh transaction is a valid stirctly DER encoded signature" in { it must "say that a signature taken from a p2sh transaction is a valid stirctly DER encoded signature" in {
DERSignatureUtil.isStrictDEREncoding(p2shSignature) must be (true) DERSignatureUtil.isValidSignatureEncoding(p2shSignature) must be (true)
} }
it must "say that signature taken from a p2pkh transaction is a valid strictly DER encoded signature" in { it must "say that signature taken from a p2pkh transaction is a valid strictly DER encoded signature" in {
DERSignatureUtil.isStrictDEREncoding(p2pkhSignature) must be (true) DERSignatureUtil.isValidSignatureEncoding(p2pkhSignature) must be (true)
} }
it must "say that a signature taken from a p2pk transaction is a valid strictly DER encoded signature" in { it must "say that a signature taken from a p2pk transaction is a valid strictly DER encoded signature" in {
DERSignatureUtil.isStrictDEREncoding(p2pkSignature) must be (true) DERSignatureUtil.isValidSignatureEncoding(p2pkSignature) must be (true)
} }
it must "say that the empty signature is a valid strictly encoded DER signature" in { it must "say that the empty signature is a valid strictly encoded DER signature" in {
DERSignatureUtil.isStrictDEREncoding(ECDigitalSignature("")) must be (true) DERSignatureUtil.isValidSignatureEncoding(ECDigitalSignature("")) must be (true)
DERSignatureUtil.isStrictDEREncoding(EmptyDigitalSignature) must be (true) DERSignatureUtil.isValidSignatureEncoding(EmptyDigitalSignature) must be (true)
} }
it must "say that an overly long signature is NOT strict der encoded" in { it must "say that an overly long signature is NOT strict der encoded" in {
val sig = ECDigitalSignature("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") val sig = ECDigitalSignature("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
DERSignatureUtil.isStrictDEREncoding(sig) must be (false) DERSignatureUtil.isValidSignatureEncoding(sig) must be (false)
} }
it must "determine if a signature is encoded with a low s value" in { it must "determine if a signature is encoded with a low s value" in {
val highS = ECDigitalSignature("304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001".toLowerCase) val highS = ECDigitalSignature("304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001".toLowerCase)
DERSignatureUtil.isLowDerSignature(highS) must be (false) DERSignatureUtil.isLowS(highS) must be (false)
} }
} }

View File

@ -15,17 +15,17 @@ class ECDigitalSignatureTest extends FlatSpec with MustMatchers {
} }
it must "say that a signature taken from a p2sh transaction is a valid DER encoded signature" in { it must "say that a signature taken from a p2sh transaction is a valid DER encoded signature" in {
val signature = ECDigitalSignature("304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001") val signature = ECDigitalSignature("304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf80")
signature.isDEREncoded must be (true) signature.isDEREncoded must be (true)
} }
it must "say that signature taken from a p2pkh transaction is a valid DER encoded signature" in { it must "say that signature taken from a p2pkh transaction is a valid DER encoded signature" in {
val signature = ECDigitalSignature("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01") val signature = ECDigitalSignature("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac")
signature.isDEREncoded must be (true) signature.isDEREncoded must be (true)
} }
it must "say that a signature taken from a p2pk transaction is a valid DER encoded signature" in { it must "say that a signature taken from a p2pk transaction is a valid DER encoded signature" in {
val signature = ECDigitalSignature("304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001") val signature = ECDigitalSignature("304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b7420")
signature.isDEREncoded must be (true) signature.isDEREncoded must be (true)
} }

View File

@ -46,6 +46,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
txSignature.s must be (expectedSig.s) txSignature.s must be (expectedSig.s)
txSignature.hex must be (expectedSig.hex) txSignature.hex must be (expectedSig.hex)
} }
it must "create a p2pk scriptPubKey, create a crediting tx for scriptPubKey, " + it must "create a p2pk scriptPubKey, create a crediting tx for scriptPubKey, " +
"then create spending tx and make sure it evaluates to true in the interpreter" in { "then create spending tx and make sure it evaluates to true in the interpreter" in {
val privateKey = ECPrivateKey() val privateKey = ECPrivateKey()