示例#1
0
 def __init__(self, inputs, outputs, version=b'\x01\x00\x00\x00', lock_time=b'\x00\x00\x00\x00'):
     self.inputs = inputs
     self.outputs = outputs
     assert len(version) == 4, 'Invalid Version'
     assert len(lock_time) == 4, 'Invalid lock time'
     self._version = version[::-1]
     self.version = bytes_to_int(self._version)
     self._lock_time = lock_time[::-1]
     self.lock_time = bytes_to_int(self._lock_time)
示例#2
0
 def from_seed(cls, seed: Union[bytes, str], addresstype='P2PKH') -> 'Xprv':
     if isinstance(seed, str):
         seed = hex_to_bytes(seed)
     assert 16 <= len(seed) <= 64, 'Seed should be between 128 and 512 bits'
     I = hmac.new(key=b"Bitcoin seed", msg=seed,
                  digestmod=hashlib.sha512).digest()
     I_L, I_R = I[:32], I[32:]
     if bytes_to_int(I_L) == 0 or bytes_to_int(I_L) > CURVE.N:
         raise KeyDerivationError
     key, code = PrivateKey(I_L), I_R
     return cls(key, code, addresstype=addresstype)
示例#3
0
    def child(self, i: int) -> 'Xprv':
        hardened = i >= 1 << 31

        if hardened:
            I = hmac.new(key=self.code,
                         msg=self.keydata() +
                         int_to_bytes(i).rjust(4, b'\x00'),
                         digestmod=hashlib.sha512).digest()
        else:
            I = hmac.new(key=self.code,
                         msg=self.key.to_public().encode(compressed=True) +
                         int_to_bytes(i).rjust(4, b'\x00'),
                         digestmod=hashlib.sha512).digest()

        I_L, I_R = bytes_to_int(I[:32]), I[32:]
        key = (I_L + self.key.int()) % CURVE.N
        if I_L >= CURVE.N or key == 0:
            return self.child(i + 1)
        ret_code = I_R
        if hardened:
            path = self.path + f'/{i - 2**31}h'
        else:
            path = self.path + f'/{i}'
        return Xprv(PrivateKey.from_int(key),
                    ret_code,
                    depth=self.depth + 1,
                    i=i,
                    parent=self.fingerprint(),
                    path=path,
                    addresstype=self.type.value)
示例#4
0
    def decode(cls, key: bytes) -> 'PublicKey':
        if key.startswith(b'\x04'):        # uncompressed key
            assert len(key) == 65, 'An uncompressed public key must be 65 bytes long'
            x, y = bytes_to_int(key[1:33]), bytes_to_int(key[33:])
        else:                              # compressed key
            assert len(key) == 33, 'A compressed public key must be 33 bytes long'
            x = bytes_to_int(key[1:])
            root = modsqrt(CURVE.f(x), P)
            if key.startswith(b'\x03'):    # odd root
                y = root if root % 2 == 1 else -root % P
            elif key.startswith(b'\x02'):  # even root
                y = root if root % 2 == 0 else -root % P
            else:
                assert False, 'Wrong key format'

        return cls(Point(x, y))
示例#5
0
def encode(bts: bytes) -> str:
    n = bytes_to_int(bts)
    leading_zero_bytes = len(bts) - len(bts.lstrip(b'\x00'))
    int_digits = []
    while n:
        int_digits.append(int(n % BASE))
        n //= BASE
    for _ in range(leading_zero_bytes):
        int_digits.append(0)
    return ''.join(ALPHABET[i] for i in reversed(int_digits))
示例#6
0
 def read_var_int():
     """https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer"""
     byte = pop(1)
     if byte == b'\xfd':
         result = pop(2)
     elif byte == b'\xfe':
         result = pop(4)
     elif byte == b'\xff':
         result = pop(8)
     else:
         result = byte
     return bytes_to_int(result[::-1])
示例#7
0
    def sign_hash(self, hash):
        e = hex_to_int(hash) if isinstance(hash, str) else bytes_to_int(hash)
        r, s = 0, 0
        while r == 0 or s == 0:
            k = secrets.randbelow(N)
            point = CURVE.G * k
            r = point.x % N

            inv_k = mulinv(k, N)
            s = (inv_k * (e + r * self.int())) % N

        return message.Signature(r=r, s=s)
示例#8
0
    def deserialize(cls, bts: bytes) -> 'ExtendedKey':
        def read(n):
            nonlocal bts
            data, bts = bts[:n], bts[n:]
            return data

        net = read(4)
        is_private = net in network('extended_prv').values()
        is_public = net in network('extended_pub').values()
        assert is_public ^ is_private, f'Invalid network bytes : {bytes_to_hex(net)}'
        address_lookup = {
            val: key
            for key, val in (network('extended_prv') if is_private else
                             network('extended_pub')).items()
        }
        constructor = Xprv if is_private else Xpub
        depth = bytes_to_int(read(1))
        assert depth in range(256), f'Invalid depth : {depth}'
        fingerprint = read(4)
        i = bytes_to_int(read(4))
        if depth == 0:
            i = None
            path = None
        else:
            ih = f'{i}' if i < 2**31 else f"{i - 2**31}h"
            path = '/'.join([constructor.root_path] +
                            ['x' for _ in range(depth - 1)] + [ih])

        code = read(32)
        key = read(33)
        key = PrivateKey(key) if is_private else PublicKey.decode(key)
        assert not bts, 'Leftover bytes'
        return constructor(key,
                           code,
                           depth=depth,
                           i=i,
                           parent=fingerprint,
                           path=path,
                           addresstype=address_lookup[net])
示例#9
0
 def __init__(self, output, index, script, sequence=b'\xff\xff\xff\xff', witness=None, referenced_tx=None):
     # Parameters should be bytes as transmitted i.e reversed
     assert isinstance(output, bytes) and len(output) == 32
     self.output = output[::-1]  # referenced tx hash
     self.index = index if isinstance(index, int) else bytes_to_int(index[::-1])
     assert self.index <= 0xffffffff
     self.script = script
     self.sequence = sequence[::-1]
     self._referenced_tx = referenced_tx
     self._referenced_output = None
     self.witness = witness
     self._parent = None
     self.tx_index = None  # index of this input in it's parent tx
     self.parent_id = None
示例#10
0
    def child(self, i: int) -> 'Xprv':
        hardened = i >= 1 << 31

        if hardened:
            I = hmac.new(key=self.code,
                         msg=self.keydata() +
                         int_to_bytes(i).rjust(32, b'\x00'),
                         digestmod=hashlib.sha512).digest()
        else:
            I = hmac.new(key=self.code,
                         msg=self.key.to_public().encode(compressed=True) +
                         int_to_bytes(i).rjust(32, b'\x00'),
                         digestmod=hashlib.sha512).digest()

        I_L, I_R = bytes_to_int(I[:32]), I[32:]
        key = I_L + self.key.int() % CURVE.N
        if I_L >= CURVE.N or key == 0:
            return self.child(i + 1)
        ret_code = I_R
        return Xprv(key, ret_code, depth=self.depth + 1, i=i)
示例#11
0
 def _receive(self, value: int):
     """Creates an output that sends to this address"""
     addr_type = self.type()
     output = Output(value=value, script=b'')
     if addr_type == ADDRESS.P2PKH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         keyhash = address[1:-4]
         output.script = OP.DUP.byte + OP.HASH160.byte + push(
             keyhash) + OP.EQUALVERIFY.byte + OP.CHECKSIG.byte
     elif addr_type == ADDRESS.P2SH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         scripthash = address[1:-4]
         output.script = OP.HASH160.byte + push(scripthash) + OP.EQUAL.byte
     elif addr_type in (ADDRESS.P2WPKH, ADDRESS.P2WSH):
         witness_version, witness_program = bech32.decode(
             network('hrp'), self.address)
         output.script = OP(bytes_to_int(
             witness_byte(witness_version))).byte + push(
                 bytes(witness_program))
     else:
         raise ValidationError(f"Cannot create output of type {addr_type}")
     return output
示例#12
0
def asm(script):
    """Turns a script into a symbolic representation"""
    if isinstance(script, str):
        script = hex_to_bytes(script)
    else:
        script = copy(script)

    def read(n):
        nonlocal script
        data = script[:n]
        assert data or n == 0, 'EOF'
        script = script[n:]
        return data

    results = []
    while script:
        byte = bytes_to_int(read(1))
        op = OP(byte)
        if byte in range(1, 76):
            results.append(bytes_to_hex(read(byte)))
        else:
            results.append(str(op))

    return ' '.join(results)
示例#13
0
 def step(self):
     """Executes one script operation"""
     byte = bytes_to_int(self.read(1))
     opcode = OP(byte)
     self.op(opcode)
示例#14
0
 def __init__(self, bts):
     assert bytes_to_int(bts) < N, 'Key larger than Curve Order'
     super().__init__(bts)
示例#15
0
 def index(self):
     return bytes_to_int(self._index)
示例#16
0
 def sequence(self):
     return bytes_to_int(self._sequence)
示例#17
0
 def value(self):
     return bytes_to_int(self._value)