Skip to content

Commit

Permalink
Merge #15826: Pure python EC
Browse files Browse the repository at this point in the history
b679785 Add comments to Python ECDSA implementation (John Newbery)
8c7b932 Pure python EC (Pieter Wuille)

Pull request description:

  This removes the dependency on OpenSSL for the interaction tests, by providing a pure-Python
  toy implementation of secp256k1.

ACKs for commit b67978:
  jnewbery:
    utACK b679785

Tree-SHA512: 181445eb08b316c46937b80dc10aa50d103ab1fdddaf834896c0ea22204889f7b13fd33cbcbd00ddba15f7e4686fe0d9f8e8bb4c0ad0e9587490c90be83966dc
  • Loading branch information
MarcoFalke committed Apr 22, 2019
2 parents 56376f3 + b679785 commit 08bd21a
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 230 deletions.
8 changes: 4 additions & 4 deletions test/functional/feature_assumevalid.py
Expand Up @@ -32,7 +32,7 @@
import time

from test_framework.blocktools import (create_block, create_coinbase)
from test_framework.key import CECKey
from test_framework.key import ECKey
from test_framework.messages import (
CBlockHeader,
COutPoint,
Expand Down Expand Up @@ -104,9 +104,9 @@ def run_test(self):
self.blocks = []

# Get a pubkey for the coinbase TXO
coinbase_key = CECKey()
coinbase_key.set_secretbytes(b"horsebattery")
coinbase_pubkey = coinbase_key.get_pubkey()
coinbase_key = ECKey()
coinbase_key.generate()
coinbase_pubkey = coinbase_key.get_pubkey().get_bytes()

# Create the first block with a coinbase output to our key
height = 1
Expand Down
12 changes: 6 additions & 6 deletions test/functional/feature_block.py
Expand Up @@ -14,7 +14,7 @@
get_legacy_sigopcount_block,
MAX_BLOCK_SIGOPS,
)
from test_framework.key import CECKey
from test_framework.key import ECKey
from test_framework.messages import (
CBlock,
COIN,
Expand Down Expand Up @@ -86,9 +86,9 @@ def run_test(self):
self.bootstrap_p2p() # Add one p2p connection to the node

self.block_heights = {}
self.coinbase_key = CECKey()
self.coinbase_key.set_secretbytes(b"horsebattery")
self.coinbase_pubkey = self.coinbase_key.get_pubkey()
self.coinbase_key = ECKey()
self.coinbase_key.generate()
self.coinbase_pubkey = self.coinbase_key.get_pubkey().get_bytes()
self.tip = None
self.blocks = {}
self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16)
Expand Down Expand Up @@ -528,7 +528,7 @@ def run_test(self):
tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b''))
# Note: must pass the redeem_script (not p2sh_script) to the signature hash function
(sighash, err) = SignatureHash(redeem_script, tx, 1, SIGHASH_ALL)
sig = self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))
sig = self.coinbase_key.sign_ecdsa(sighash) + bytes(bytearray([SIGHASH_ALL]))
scriptSig = CScript([sig, redeem_script])

tx.vin[1].scriptSig = scriptSig
Expand Down Expand Up @@ -1284,7 +1284,7 @@ def sign_tx(self, tx, spend_tx):
tx.vin[0].scriptSig = CScript()
return
(sighash, err) = SignatureHash(spend_tx.vout[0].scriptPubKey, tx, 0, SIGHASH_ALL)
tx.vin[0].scriptSig = CScript([self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))])
tx.vin[0].scriptSig = CScript([self.coinbase_key.sign_ecdsa(sighash) + bytes(bytearray([SIGHASH_ALL]))])

def create_and_sign_transaction(self, spend_tx, value, script=CScript([OP_TRUE])):
tx = self.create_tx(spend_tx, 0, value, script)
Expand Down
23 changes: 11 additions & 12 deletions test/functional/p2p_segwit.py
Expand Up @@ -9,7 +9,7 @@
import time

from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment, get_witness_script, WITNESS_COMMITMENT_HEADER
from test_framework.key import CECKey, CPubKey
from test_framework.key import ECKey
from test_framework.messages import (
BIP125_SEQUENCE_NUMBER,
CBlock,
Expand Down Expand Up @@ -100,7 +100,7 @@ def get_p2pkh_script(pubkeyhash):
def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key):
"""Add signature for a P2PK witness program."""
tx_hash = SegwitVersion1SignatureHash(script, tx_to, in_idx, hashtype, value)
signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1')
signature = key.sign_ecdsa(tx_hash) + chr(hashtype).encode('latin-1')
tx_to.wit.vtxinwit[in_idx].scriptWitness.stack = [signature, script]
tx_to.rehash()

Expand Down Expand Up @@ -1479,10 +1479,9 @@ def test_uncompressed_pubkey(self):

# Segwit transactions using uncompressed pubkeys are not accepted
# under default policy, but should still pass consensus.
key = CECKey()
key.set_secretbytes(b"9")
key.set_compressed(False)
pubkey = CPubKey(key.get_pubkey())
key = ECKey()
key.generate(False)
pubkey = key.get_pubkey().get_bytes()
assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey

utxo = self.utxo.pop(0)
Expand Down Expand Up @@ -1512,7 +1511,7 @@ def test_uncompressed_pubkey(self):
tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh))
script = get_p2pkh_script(pubkeyhash)
sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [signature, pubkey]
tx2.rehash()
Expand Down Expand Up @@ -1566,7 +1565,7 @@ def test_uncompressed_pubkey(self):
tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b""))
tx5.vout.append(CTxOut(tx4.vout[0].nValue - 1000, CScript([OP_TRUE])))
(sig_hash, err) = SignatureHash(script_pubkey, tx5, 0, SIGHASH_ALL)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx5.vin[0].scriptSig = CScript([signature, pubkey])
tx5.rehash()
# Should pass policy and consensus.
Expand All @@ -1579,9 +1578,9 @@ def test_uncompressed_pubkey(self):
@subtest
def test_signature_version_1(self):

key = CECKey()
key.set_secretbytes(b"9")
pubkey = CPubKey(key.get_pubkey())
key = ECKey()
key.generate()
pubkey = key.get_pubkey().get_bytes()

witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)])
witness_hash = sha256(witness_program)
Expand Down Expand Up @@ -1716,7 +1715,7 @@ def test_signature_version_1(self):

script = get_p2pkh_script(pubkeyhash)
sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL

# Check that we can't have a scriptSig
tx2.vin[0].scriptSig = CScript([signature, pubkey])
Expand Down

0 comments on commit 08bd21a

Please sign in to comment.