From 61e282b62d7d4f0bca435c6e1b836d3b2c3a0874 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 14 Sep 2016 21:00:29 -0400 Subject: [qa] Add support for compactblocks v2 to mininode Github-Pull: #8393 Rebased-From: 422fac649f75c907cad6ab7e2768b9032b9eae42 --- qa/rpc-tests/test_framework/mininode.py | 35 +++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'qa/rpc-tests/test_framework') diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 88a3b7e0f7..b7e4737489 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -755,6 +755,9 @@ class PrefilledTransaction(object): r += self.tx.serialize_without_witness() return r + def serialize_with_witness(self): + return self.serialize(with_witness=True) + def __repr__(self): return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) @@ -779,6 +782,7 @@ class P2PHeaderAndShortIDs(object): self.prefilled_txn = deser_vector(f, PrefilledTransaction) self.prefilled_txn_length = len(self.prefilled_txn) + # When using version 2 compact blocks, we must serialize with_witness. def serialize(self, with_witness=False): r = b"" r += self.header.serialize() @@ -787,12 +791,20 @@ class P2PHeaderAndShortIDs(object): for x in self.shortids: # We only want the first 6 bytes r += struct.pack(" Date: Sat, 17 Sep 2016 22:11:00 -0400 Subject: [qa] Fix bug in mininode witness deserialization Also improve tx printing Github-Pull: #8393 Rebased-From: f5b9b8f437c040205896ad0d7a6656efa08b5601 --- qa/rpc-tests/test_framework/mininode.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'qa/rpc-tests/test_framework') diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index b7e4737489..4d238c08d9 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -452,7 +452,7 @@ class CTransaction(object): else: self.vout = deser_vector(f, CTxOut) if flags != 0: - self.wit.vtxinwit = [CTxInWitness()]*len(self.vin) + self.wit.vtxinwit = [CTxInWitness() for i in range(len(self.vin))] self.wit.deserialize(f) self.nLockTime = struct.unpack(" Date: Wed, 24 Aug 2016 14:44:17 +0800 Subject: Make test framework produce lowS signatures Github-Pull: #8499 Rebased-From: 9f0397aff7afa2afa9328daea0a2053122e79d44 --- qa/rpc-tests/test_framework/key.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'qa/rpc-tests/test_framework') diff --git a/qa/rpc-tests/test_framework/key.py b/qa/rpc-tests/test_framework/key.py index ba3038fe04..c63a15c1e0 100644 --- a/qa/rpc-tests/test_framework/key.py +++ b/qa/rpc-tests/test_framework/key.py @@ -75,6 +75,9 @@ ssl.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, # this specifies the curve used with ECDSA. NID_secp256k1 = 714 # from openssl/obj_mac.h +SECP256K1_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2 + # Thx to Sam Devlin for the ctypes magic 64-bit fix. def _check_result(val, func, args): if val == 0: @@ -147,7 +150,7 @@ class CECKey(object): r = self.get_raw_ecdh_key(other_pubkey) return kdf(r) - def sign(self, hash): + def sign(self, hash, low_s = True): # FIXME: need unit tests for below cases if not isinstance(hash, bytes): raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) @@ -159,7 +162,25 @@ class CECKey(object): mb_sig = ctypes.create_string_buffer(sig_size0.value) result = ssl.ECDSA_sign(0, hash, len(hash), mb_sig, ctypes.byref(sig_size0), self.k) assert 1 == result - return mb_sig.raw[:sig_size0.value] + assert mb_sig.raw[0] == 0x30 + assert mb_sig.raw[1] == sig_size0.value - 2 + total_size = mb_sig.raw[1] + assert mb_sig.raw[2] == 2 + r_size = mb_sig.raw[3] + assert mb_sig.raw[4 + r_size] == 2 + s_size = mb_sig.raw[5 + r_size] + s_value = int.from_bytes(mb_sig.raw[6+r_size:6+r_size+s_size], byteorder='big') + if (not low_s) or s_value <= SECP256K1_ORDER_HALF: + return mb_sig.raw[:sig_size0.value] + else: + low_s_value = SECP256K1_ORDER - s_value + low_s_bytes = (low_s_value).to_bytes(33, byteorder='big') + while len(low_s_bytes) > 1 and low_s_bytes[0] == 0 and low_s_bytes[1] < 0x80: + low_s_bytes = low_s_bytes[1:] + new_s_size = len(low_s_bytes) + new_total_size_byte = (total_size + new_s_size - s_size).to_bytes(1,byteorder='big') + new_s_size_byte = (new_s_size).to_bytes(1,byteorder='big') + return b'\x30' + new_total_size_byte + mb_sig.raw[2:5+r_size] + new_s_size_byte + low_s_bytes def verify(self, hash, sig): """Verify a DER signature""" -- cgit v1.2.3 From fef7b468415e77e1876225988a177eed70418eb1 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 15 Oct 2016 02:29:39 +0800 Subject: test segwit uncompressed key fixes Github-Pull: #8499 Rebased-From: 9260085377e89e666d0cb95b462261d7e3a9c82f --- qa/rpc-tests/test_framework/address.py | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 qa/rpc-tests/test_framework/address.py (limited to 'qa/rpc-tests/test_framework') diff --git a/qa/rpc-tests/test_framework/address.py b/qa/rpc-tests/test_framework/address.py new file mode 100644 index 0000000000..50b999be61 --- /dev/null +++ b/qa/rpc-tests/test_framework/address.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# address.py +# +# This file encodes and decodes BASE58 P2PKH and P2SH addresses +# + +from .script import hash256, hash160, sha256, CScript, OP_0 +from .util import bytes_to_hex_str, hex_str_to_bytes + +chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + +def byte_to_base58(b, version): + result = '' + str = bytes_to_hex_str(b) + str = bytes_to_hex_str(chr(version).encode('latin-1')) + str + checksum = bytes_to_hex_str(hash256(hex_str_to_bytes(str))) + str += checksum[:8] + value = int('0x'+str,0) + while value > 0: + result = chars[value % 58] + result + value //= 58 + while (str[:2] == '00'): + result = chars[0] + result + str = str[2:] + return result + +# TODO: def base58_decode + +def keyhash_to_p2pkh(hash, main = False): + assert (len(hash) == 20) + version = 0 if main else 111 + return byte_to_base58(hash, version) + +def scripthash_to_p2sh(hash, main = False): + assert (len(hash) == 20) + version = 5 if main else 196 + return byte_to_base58(hash, version) + +def key_to_p2pkh(key, main = False): + key = check_key(key) + return keyhash_to_p2pkh(hash160(key), main) + +def script_to_p2sh(script, main = False): + script = check_script(script) + return scripthash_to_p2sh(hash160(script), main) + +def key_to_p2sh_p2wpkh(key, main = False): + key = check_key(key) + p2shscript = CScript([OP_0, hash160(key)]) + return script_to_p2sh(p2shscript, main) + +def script_to_p2sh_p2wsh(script, main = False): + script = check_script(script) + p2shscript = CScript([OP_0, sha256(script)]) + return script_to_p2sh(p2shscript, main) + +def check_key(key): + if (type(key) is str): + key = hex_str_to_bytes(key) # Assuming this is hex string + if (type(key) is bytes and (len(key) == 33 or len(key) == 65)): + return key + assert(False) + +def check_script(script): + if (type(script) is str): + script = hex_str_to_bytes(script) # Assuming this is hex string + if (type(script) is bytes or type(script) is CScript): + return script + assert(False) -- cgit v1.2.3