예제 #1
0
 def raw_parse(cls, s):
     '''Returns a HDPublicKey from a stream'''
     # first 4 bytes are the version
     version = s.read(4)
     # check that the version is one of the TESTNET or MAINNET
     #  public keys, if not raise a ValueError
     if version in (TESTNET_XPUB, TESTNET_YPUB, TESTNET_ZPUB):
         testnet = True
     elif version in (MAINNET_XPUB, MAINNET_YPUB, MAINNET_ZPUB):
         testnet = False
     else:
         raise ValueError('not an xpub, ypub or zpub: {} {}'.format(s, version))
     # the next byte is depth
     depth = byte_to_int(s.read(1))
     # next 4 bytes are the parent_fingerprint
     parent_fingerprint = s.read(4)
     # next 4 bytes is the child number in big-endian
     child_number = big_endian_to_int(s.read(4))
     # next 32 bytes are the chain code
     chain_code = s.read(32)
     # last 33 bytes should be the SEC
     point = S256Point.parse(s.read(33))
     # return an instance of the class
     return cls(
         point=point,
         chain_code=chain_code,
         depth=depth,
         parent_fingerprint=parent_fingerprint,
         child_number=child_number,
         testnet=testnet,
     )
 def test_pubpoint(self):
     # write a test that tests the public point for the following
     points = (
         # secret, x, y
         (7,
          0x5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc,
          0x6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da
          ),
         (1485,
          0xc982196a7466fbbbb0e27a940b6af926c1a74d5ad07128c82824a11b5398afda,
          0x7a91f9eae64438afb9ce6448a1c133db2d8fb9254e4546b6f001637d50901f55
          ),
         (2**128,
          0x8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da,
          0x662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82
          ),
         (2**240 + 2**31,
          0x9577ff57c8234558f293df502ca4f09cbc65a6572c842b39b366f21717945116,
          0x10b49c67fa9365ad7b90dab070be339a1daf9052373ec30ffae4f72d5e66d053
          ),
     )
     for secret, x, y in points:
         # initialize the secp256k1 point
         point = S256Point(x, y)
         # check that te secret*G is the same as the point
         self.assertEqual(secret * G, point)
예제 #3
0
def op_checkmultisig(stack, z):
    # m of n multi-sig
    if len(stack) < 1:
        return False
    n = decode_num(stack.pop())
    if len(stack) < n+1:
        return False
    sec_pubkeys = []
    for _ in range(n):
        sec_pubkeys.append(stack.pop())
    m = decode_num(stack.pop())
    if len(stack) < m+1:
        return False
    der_signatures = []
    for _ in range(m):
        der_signatures.append(stack.pop()[:-1])
    stack.pop() # Off-by-One bug
    try:
        pubPoints = [S256Point.parse(sec) for sec in sec_pubkeys]
        sigs = [Signature.parse(der) for der in der_signatures]
        for sig in sigs:
            if len(pubPoints) == 0:
                return False
            while pubPoints:
                pubPoint = pubPoints.pop(0)
                if pubPoint.verify(z, sig):
                    break
        stack.append(encode_num(1))
    except (ValueError, SyntaxError):
        return False
    return True
예제 #4
0
def op_checksig(stack, z):
    # check that there are at least 2 elements on the stack
    if len(stack) < 2:
        return False

    # the top element of the stack is the SEC pubkey
    sec_pubkey = stack.pop()
    print(f'stack sec:{sec_pubkey.hex()}')

    # the next element of the stack is the DER signature
    der_signature = stack.pop()[:-1]
    print(f'stack der:{der_signature}')

    # take off the last byte of the signature as that's the hash_type
    hash_type = der_signature[-1:]
    print(f'hash_type:{hash_type.hex()}')

    # parse the serialized pubkey and signature into objects
    try:
        point = S256Point.parse(sec_pubkey)
        der_signature = Signature.parse(der_signature)
        print(f'point:{point}')
        print(f'sig:{der_signature}')
    except (ValueError, SyntaxError) as e:
        return False
    if point.verify(z, der_signature):
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True
예제 #5
0
def op_checksig(stack, z):
    # check that there are at least 2 elements on the stack
    if len(stack) < 2:
        return False

    # the top element of the stack is the SEC pubkey
    pubkey_bin = stack.pop()

    # the next element of the stack is the DER signature
    sig_bin = stack.pop()

    # take off the last byte of the signature as that's the hash_type
    hash_type = sig_bin[-1]
    sig_bin = sig_bin[:-1]

    # parse the serialized pubkey and signature into objects
    pubkey = S256Point.parse(pubkey_bin)
    sig = Signature.parse(sig_bin)

    # verify the signature using S256Point.verify()
    valid = pubkey.verify(z, sig)

    # push an encoded 1 or 0 depending on whether the signature verified
    stack.append(encode_num(1) if valid else encode_num(0))

    return True
예제 #6
0
def op_checksig(stack, z):
    # check that there are at least 2 elements on the stack
    if len(stack) < 2:
        return False
    # the top element of the stack is the SEC pubkey
    sec_pubkey = stack.pop()
    # the next element of the stack is the DER signature
    # take off the last byte of the signature as that's the hash_type
    # We will explain what this means when we explain validation of transactions next!!! Please be patient!
    # More at https://en.bitcoin.it/wiki/OP_CHECKSIG
    der_signature = stack.pop()[:-1]
    # parse the serialized pubkey and signature into objects
    try:
        point = S256Point.parse(sec_pubkey)
        sig = Signature.parse(der_signature)
    except (ValueError, SyntaxError):
        #print('Parse fail', point)
        return False
    # verify the signature using S256Point.verify()
    # push an encoded 1 or 0 depending on whether the signature verified
    if point.verify(z, sig):
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True
예제 #7
0
파일: seed.py 프로젝트: Pure-Wallet/crypto
 def derive_pub_child(self, i):
     if i >= HARD_CAP:
         return ValueError("Chosen i is not in range [0, 2**32-1]")
     # Not quite sure if this is true
     # if int.from_bytes(self.child_num, 'big') >= SOFT_CAP:
     # 	raise TypeError("Hardened Public Keys cannot derive child keys. Use Extended Private key.")
     if i >= SOFT_CAP:
         raise TypeError(
             "Hardened Keys cannot be be derived from Extended Pub Keys. Use Extended Private key."
         )
     else:
         ii = hmac.new(self.chaincode,
                       self.key + i.to_bytes(4, 'big'),
                       digestmod=sha512).digest()
     fingerprint = hash160(self.key)[:4]
     # edge case: invalid keys
     key_num = int.from_bytes(ii[:32], 'big')
     point = key_num * G
     if key_num >= N or point.x is None:
         raise ValueError(INVALID_KEY_MSG)
     child_key = point + S256Point.parse(self.key)
     child_chaincode = ii[32:]
     #assemble new xpub
     child_xpub = self.pfx
     child_xpub += (self.depth[0] + 1).to_bytes(1, 'big')
     child_xpub += fingerprint
     child_xpub += i.to_bytes(4, 'big')
     child_xpub += child_chaincode
     child_xpub += child_key.sec()
     checksum = hash256(child_xpub)[:4]
     child_xpub += checksum
     return self.__class__(child_xpub)
예제 #8
0
파일: tx.py 프로젝트: cloydse/hardforkhelp
 def verify_input(self, input_index):
     '''Returns whether the input has a valid signature'''
     # get the relevant input
     tx_in = self.tx_ins[input_index]
     # get the number of signatures required. This is available in tx_in.script_sig.num_sigs_required()
     sigs_required = tx_in.script_sig.num_sigs_required()
     # iterate over the sigs required and check each signature
     for sig_num in range(sigs_required):
         # get the point from the sec format
         sec = tx_in.sec_pubkey(index=sig_num)
         # get the sec_pubkey at current signature index
         point = S256Point.parse(sec)
         # get the der sig and hash_type from input
         # get the der_signature at current signature index
         der, hash_type = tx_in.der_signature(index=sig_num)
         # get the signature from der format
         signature = Signature.parse(der)
         # get the hash to sign
         if tx_in.is_segwit():
             h160 = hash160(tx_in.script_sig.redeem_script())
             if h160 != tx_in.script_pubkey(self.testnet).elements[1]:
                 return False
             pubkey_h160 = tx_in.script_sig.redeem_script()[-20:]
             if pubkey_h160 != point.h160():
                 return False
             z = self.sig_hash_bip143(input_index, hash_type)
         else:
             z = self.sig_hash(input_index, hash_type)
         # use point.verify on the hash to sign and signature
         if not point.verify(z, signature):
             return False
     return True
예제 #9
0
 def test_example_4(self):
     sec = bytes.fromhex('0349fc4e631e3624a545de3f89f5d8684c7b8138bd94bdd531d2e213bf016b278a')
     der = bytes.fromhex('3045022100ed81ff192e75a3fd2304004dcadb746fa5e24c5031ccfcf21320b0277457c98f02207a986d955c6e0cb35d446a89d3f56100f4d7f67801c31967743a9c8e10615bed')
     z = 0x27e0c5994dec7824e56dec6b2fcb342eb7cdb0d0957c2fce9882f715e85d81a6
     point = S256Point.parse(sec)
     signature = Signature.parse(der)
     self.assertTrue(point.verify(z, signature))
 def test_verify_ch3_example8(self):
     z = 0xbc62d4b80d9e36da29c16c5d4d9f11731f36052c72401a76c23c0fb5a9b74423
     r = 0x37206a0610995c58074999cb9767b87af4c4978db68c06e8e6e81d282047a7c6
     s = 0x8ca63759c1157ebeaec0d03cecca119fc9a75bf8e6d0fa65c841c8e2738cdaec
     px = 0x04519fac3d910ca7e7138f7013706f619fa8f033e6ec6e09370ea38cee6a7574
     py = 0x82b51eab8c27c66e26c858a079bcdf4f1ada34cec420cafc7eac1a42216fb6c4
     point = S256Point(px, py)
     self.assertTrue(point.verify(z, Signature(r, s)))
예제 #11
0
 def test_example_8(self):
     point = S256Point(0x5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC, 0x6AEBCA40BA255960A3178D6D861A54DBA813D0B813FDE7B5A5082628087264DA)
     uncompressed = b'\x04' + point.x.num.to_bytes(32, 'big') + point.y.num.to_bytes(32, 'big')
     if point.y.num % 2 == 1:
         compressed = b'\x03' + point.x.num.to_bytes(32, 'big')
     else:
         compressed = b'\x02' + point.x.num.to_bytes(32, 'big')
     self.assertEqual(uncompressed.hex(), '045cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da')
     self.assertEqual(compressed.hex(), '025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc')
예제 #12
0
 def test_exercise_2(self):
     der = bytes.fromhex(
         '304402201f62993ee03fca342fcb45929993fa6ee885e00ddad8de154f268d98f083991402201e1ca12ad140c04e0e022c38f7ce31da426b8009d02832f0b44f39a6b178b7a1'
     )
     sec = bytes.fromhex(
         '0204519fac3d910ca7e7138f7013706f619fa8f033e6ec6e09370ea38cee6a7574'
     )
     z = int.from_bytes(hash256(b'ECDSA is awesome!'), 'big')
     sig = Signature.parse(der)
     point = S256Point.parse(sec)
     self.assertTrue(point.verify(z, sig))
예제 #13
0
def op_checksig(stack, z):
    if len(stack) < 2:
        return False
    sec_pubkey = stack.pop()
    der_signature = stack.pop()[:-1]
    point = S256Point.parse(sec_pubkey)
    sig = Signature.parse(der_signature)
    if point.verify(z, sig):
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True
예제 #14
0
def op_checkmultisig(stack, z): 
    if len(stack) < 1:
        return False
    # n is the number of public keys
    n = decode_num(stack.pop())
    if len(stack) < n + 1:
        return False
    # get all the public keys into a list.
    pubkeys = []
    for _ in range(n):
        pubkeys.append(stack.pop())
    if len(stack) < 1:
        return False
    # m is the number of signatures
    m = decode_num(stack.pop())
    # m + 2 because of the additional element at the bottom of the stack that is added.
    if len(stack) < m + 1:
        return False
    # get all the signatures.
    signatures = []
    for _ in range(m):
        # take off last byte, which is the hashtype
        signatures.append(stack.pop()[:-1])
    if len(stack) < 1:
        return False
    # we remove the last element from the stack (the one included because the off by one error)
    stack.pop()
    # verify all the signatures against all pubkeys. If a signature isn't valid for any pubkeys, fail.
    try:
        sigs = [Signature.parse(signature) for signature in signatures]
        points = [S256Point.parse(pubkey) for pubkey in pubkeys]
    except (ValueError, SyntaxError) as e:
        LOGGER.info(e)
        return False
    # variable to count the number of valid signatures.
    count = 0
    # in the next loop, we check that each signature is valid for a pubkey.
    while len(points) > 0:
        # point is popped so each signature can only be valid for 1 point.
        point = points.pop()
        for sig in sigs:
            # if the signature is valid for this pubkey, increase the count and break from the while
            # to check next signature.
            if point.verify(z, sig):
                count += 1
    # if the number of valid signatures is m = each signature is valid for some pubkey, then script is valid.
    if count == m:
        stack.append(encode_num(1))
    # else, script should fail.
    else:
        stack.append(encode_num(0))
    return True
예제 #15
0
def getaddress(x, y, testnet=True, compressed=True):
    p = S256Point(x, y)
    comp = p.sec(compressed)
    h160 = hash160(comp)
    prefix = b'\00'
    if testnet:
        prefix = b'\x6f'
    else:
        prefix = b'\00'
    raw = prefix + h160
    checksum = double_sha256(raw)[:4]
    total = raw + checksum
    return encode_base58(total)
def connect_peer(host, port, node):

    sock = SocketClient(host, port)
    sock.connect()

    peer_address = sock.receive()
    sock.send(str.encode(node.address))
    peer_pub_key = sock.receive()
    sock.send(node.public_key.sec())

    peer_pub_key_point = S256Point.parse(peer_pub_key)
    peer_sym_key = node.secret * peer_pub_key_point

    return Peer(sock, peer_address, peer_pub_key_point, peer_sym_key)
예제 #17
0
파일: seed.py 프로젝트: Pure-Wallet/crypto
 def __init__(self, xpub):
     self.pfx = xpub[:4]
     self.depth = xpub[4:5]
     self.parent = xpub[5:9]
     self.child_num = xpub[9:13]
     self.chaincode = xpub[13:45]
     self.key = xpub[45:-4]
     self.checksum = xpub[-4:]
     if not self.check_sum():
         raise ConfigurationError("Invalid Checksum for ExtendedPrivKey")
     try:  #TODO use assert
         point = S256Point.parse(self.key)
     except ValueError:
         raise ConfigurationError("Point is not on the curve, invalid key.")
def listen_for_new_peer(host, port, node):

    sock = SocketServer(host, port)
    sock.listen()

    sock.send(str.encode(node.address))
    peer_address = sock.receive()
    sock.send(node.public_key.sec())
    peer_pub_key = sock.receive()

    peer_pub_key_point = S256Point.parse(peer_pub_key)
    peer_sym_key = node.secret * peer_pub_key_point

    return Peer(sock, peer_address, peer_pub_key_point, peer_sym_key)
예제 #19
0
def op_checksig(stack, z):
    if len(stack) < 2:
        return False
    pub_sec = stack.pop()
    sig_der = stack.pop()[:-1] # except hash_type
    try:
        pub_point = S256Point.parse(pub_sec)
        sig = Signature.parse(sig_der)
    except (ValueError, SyntaxError) as e:
        return False
    if pub_point.verify(z, sig):
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True