示例#1
0
 def raw_parse(cls, s):
     '''Returns a HDPrivateKey from a stream'''
     # first 4 bytes are the version
     version = s.read(4)
     # check that the version is one of the TESTNET or MAINNET
     #  private keys, if not raise a ValueError
     if version in (TESTNET_XPRV, TESTNET_YPRV, TESTNET_ZPRV):
         testnet = True
     elif version in (MAINNET_XPRV, MAINNET_YPRV, MAINNET_ZPRV):
         testnet = False
     else:
         raise ValueError('not an xprv, yprv or zprv: {}'.format(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)
     # the next byte should be b'\x00'
     if byte_to_int(s.read(1)) != 0:
         raise ValueError('private key should be preceded by a zero byte')
     # last 32 bytes should be the private key in big endian
     private_key = PrivateKey(secret=big_endian_to_int(s.read(32)))
     # return an instance of the class
     return cls(
         private_key=private_key,
         chain_code=chain_code,
         depth=depth,
         parent_fingerprint=parent_fingerprint,
         child_number=child_number,
         testnet=testnet,
     )
示例#2
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,
     )
示例#3
0
 def child(self, index):
     '''Returns the child HDPrivateKey at a particular index.
     Raises ValueError for indices >= 0x8000000.
     '''
     # if index >= 0x80000000, raise a ValueError
     if index >= 0x80000000:
         raise ValueError('child number should always be less than 2^31')
     # data is the SEC compressed and the index in 4 bytes big-endian
     data = self.point.sec() + int_to_big_endian(index, 4)
     # get hmac_sha512 with chain code, data
     h = hmac_sha512(self.chain_code, data)
     # the new public point is the current point +
     #  the first 32 bytes in big endian * G
     point = self.point + big_endian_to_int(h[:32]) * G
     # chain code is the last 32 bytes
     chain_code = h[32:]
     # depth is current depth + 1
     depth = self.depth + 1
     # parent_fingerprint is the fingerprint of this node
     parent_fingerprint = self.fingerprint()
     # child number is the index
     child_number = index
     # return the HDPublicKey instance
     return HDPublicKey(
         point=point,
         chain_code=chain_code,
         depth=depth,
         parent_fingerprint=parent_fingerprint,
         child_number=child_number,
         testnet=self.testnet,
     )
示例#4
0
def from_seed(cls, seed, testnet=False):
    h = hmac_sha512(b'Bitcoin seed', seed)
    private_key = PrivateKey(secret=big_endian_to_int(h[:32]))
    chain_code = h[32:]
    return cls(
        private_key=private_key,
        chain_code=chain_code,
        testnet=testnet,
    )
示例#5
0
 def verify_message(self, message, sig):
     '''Verify a message in the form of bytes. Assumes that the z
     is calculated using hash256 interpreted as a big-endian integer'''
     # calculate the hash256 of the message
     h256 = hash256(message)
     # z is the big-endian interpretation. use big_endian_to_int
     z = big_endian_to_int(h256)
     # verify the message using the self.verify method
     return self.verify(z, sig)
示例#6
0
 def sign_message(self, message):
     '''Sign a message in the form of bytes instead of the z. The z should
     be assumed to be the hash256 of the message interpreted as a big-endian
     integer.'''
     # compute the hash256 of the message
     h256 = hash256(message)
     # z is the big-endian interpretation. use big_endian_to_int
     z = big_endian_to_int(h256)
     # sign the message using the self.sign method
     return self.sign(z)
示例#7
0
 def from_seed(cls, seed, testnet=False):
     # get hmac_sha512 with b'Bitcoin seed' and seed
     h = hmac_sha512(b'Bitcoin seed', seed)
     # create the private key using the first 32 bytes in big endian
     private_key = PrivateKey(secret=big_endian_to_int(h[:32]))
     # chaincode is the last 32 bytes
     chain_code = h[32:]
     # return an instance of the class
     return cls(
         private_key=private_key,
         chain_code=chain_code,
         testnet=testnet,
     )
示例#8
0
def xprv_raw_parse(cls, s):
    version = s.read(4)
    if version in (TESTNET_XPRV, TESTNET_YPRV, TESTNET_ZPRV):
        testnet = True
    elif version in (MAINNET_XPRV, MAINNET_YPRV, MAINNET_ZPRV):
        testnet = False
    else:
        raise ValueError('not an xprv, yprv or zprv: {}'.format(version))
    depth = byte_to_int(s.read(1))
    parent_fingerprint = s.read(4)
    child_number = big_endian_to_int(s.read(4))
    chain_code = s.read(32)
    if byte_to_int(s.read(1)) != 0:
        raise ValueError('private key should be preceded by a zero byte')
    private_key = PrivateKey(secret=big_endian_to_int(s.read(32)))
    return cls(
        private_key=private_key,
        chain_code=chain_code,
        depth=depth,
        parent_fingerprint=parent_fingerprint,
        child_number=child_number,
        testnet=testnet,
    )
示例#9
0
 def parse(cls, wif):
     '''Converts WIF to a PrivateKey object'''
     raw = raw_decode_base58(wif)
     if len(raw) == 34:  # compressed
         if raw[-1] != 1:
             raise ValueError('Invalid WIF')
         raw = raw[:-1]
     secret = big_endian_to_int(raw[1:])
     if raw[0] == 0xef:
         testnet = True
     elif raw[0] == 0x80:
         testnet = False
     else:
         raise ValueError('Invalid WIF')
     return cls(secret, testnet=testnet)
示例#10
0
def xpub_child(self, index):
    if index >= 0x80000000:
        raise ValueError('child number should always be less than 2^31')
    data = self.point.sec() + int_to_big_endian(index, 4)
    h = hmac_sha512(key=self.chain_code, msg=data)
    point = self.point + big_endian_to_int(h[:32]) * G
    chain_code = h[32:]
    depth = self.depth + 1
    parent_fingerprint = self.fingerprint()
    child_number = index
    return HDPublicKey(
        point=point,
        chain_code=chain_code,
        depth=depth,
        parent_fingerprint=parent_fingerprint,
        child_number=child_number,
        testnet=self.testnet,
    )
示例#11
0
 def sig_hash(self, input_index, redeem_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     # create the serialization per spec
     # start with version: int_to_little_endian in 4 bytes
     s = int_to_little_endian(self.version, 4)
     # next, how many inputs there are: encode_varint
     s += encode_varint(len(self.tx_ins))
     # loop through each input: for i, tx_in in enumerate(self.tx_ins)
     for i, tx_in in enumerate(self.tx_ins):
         # if the input index is the one we're signing
         if i == input_index:
             # if the RedeemScript was passed in, that's the ScriptSig
             if redeem_script:
                 script_sig = redeem_script
             # otherwise the previous tx's ScriptPubkey is the ScriptSig
             else:
                 script_sig = tx_in.script_pubkey(self.testnet)
         # Otherwise, the ScriptSig is empty
         else:
             script_sig = None
         # create a TxIn object with the prev_tx, prev_index and sequence
         # the same as the current tx_in and the script_sig from above
         new_tx_in = TxIn(
             prev_tx=tx_in.prev_tx,
             prev_index=tx_in.prev_index,
             script_sig=script_sig,
             sequence=tx_in.sequence,
         )
         # add the serialization of the TxIn object
         s += new_tx_in.serialize()
     # add how many outputs there are using encode_varint
     s += encode_varint(len(self.tx_outs))
     # add the serialization of each output
     for tx_out in self.tx_outs:
         s += tx_out.serialize()
     # add the locktime using int_to_little_endian in 4 bytes
     s += int_to_little_endian(self.locktime, 4)
     # add SIGHASH_ALL using int_to_little_endian in 4 bytes
     s += int_to_little_endian(SIGHASH_ALL, 4)
     # hash256 the serialization
     h256 = hash256(s)
     # convert the result to an integer using big_endian_to_int(x)
     return big_endian_to_int(h256)
示例#12
0
 def sig_hash_bip143(self,
                     input_index,
                     redeem_script=None,
                     witness_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     # grab the input being signed by looking up the input_index
     tx_in = self.tx_ins[input_index]
     # start with the version in 4 bytes, little endian
     s = int_to_little_endian(self.version, 4)
     # add the HashPrevouts and HashSequence
     s += self.hash_prevouts() + self.hash_sequence()
     # add the previous transaction hash in little endian
     s += tx_in.prev_tx[::-1]
     # add the previous transaction index in 4 bytes, little endian
     s += int_to_little_endian(tx_in.prev_index, 4)
     # for p2wpkh, we need to compute the ScriptCode
     if redeem_script:
         # Exercise 8: for p2sh-p2wpkh, get the hash160 which is the 2nd command of the RedeemScript
         h160 = redeem_script.commands[1]
         # the ScriptCode is the P2PKHScriptPubKey created using the hash160
         script_code = P2PKHScriptPubKey(h160)
     else:
         # get the script pubkey associated with the previous output (remember testnet)
         script_pubkey = tx_in.script_pubkey(self.testnet)
         # next get the hash160 in the script_pubkey. for p2wpkh, it's the second command
         h160 = script_pubkey.commands[1]
         # finally the ScriptCode is the P2PKHScriptPubKey created using the hash160
         script_code = P2PKHScriptPubKey(h160)
     # add the serialized ScriptCode
     s += script_code.serialize()
     # add the value of the input in 8 bytes, little endian
     s += int_to_little_endian(tx_in.value(testnet=self.testnet), 8)
     # add the sequence of the input in 4 bytes, little endian
     s += int_to_little_endian(tx_in.sequence, 4)
     # add the HashOutputs
     s += self.hash_outputs()
     # add the locktime in 4 bytes, little endian
     s += int_to_little_endian(self.locktime, 4)
     # add the sighash (SIGHASH_ALL) in 4 bytes, little endian
     s += int_to_little_endian(SIGHASH_ALL, 4)
     # hash256 the whole thing, interpret the as a big endian integer using int_to_big_endian
     return big_endian_to_int(hash256(s))
示例#13
0
 def deterministic_k(self, z):
     k = b'\x00' * 32
     v = b'\x01' * 32
     if z > N:
         z -= N
     z_bytes = int_to_big_endian(z, 32)
     secret_bytes = int_to_big_endian(self.secret, 32)
     s256 = hashlib.sha256
     k = hmac.new(k, v + b'\x00' + secret_bytes + z_bytes, s256).digest()
     v = hmac.new(k, v, s256).digest()
     k = hmac.new(k, v + b'\x01' + secret_bytes + z_bytes, s256).digest()
     v = hmac.new(k, v, s256).digest()
     while True:
         v = hmac.new(k, v, s256).digest()
         candidate = big_endian_to_int(v)
         if candidate >= 1 and candidate < N:
             return candidate
         k = hmac.new(k, v + b'\x00', s256).digest()
         v = hmac.new(k, v, s256).digest()
示例#14
0
def xprv_child(self, index):
    if index >= 0x80000000:
        data = int_to_big_endian(self.private_key.secret, 33) + int_to_big_endian(index, 4)
    else:
        data = self.private_key.point.sec() + int_to_big_endian(index, 4)
    h = hmac_sha512(self.chain_code, data)
    secret = (big_endian_to_int(h[:32]) + self.private_key.secret) % N
    private_key = PrivateKey(secret=secret)
    chain_code = h[32:]
    depth = self.depth + 1
    parent_fingerprint = self.pub.hash160()[:4]
    child_number = index
    return HDPrivateKey(
        private_key=private_key,
        chain_code=chain_code,
        depth=depth,
        parent_fingerprint=parent_fingerprint,
        child_number=child_number,
        testnet=self.testnet,
    )
示例#15
0
    def parse(cls, s, compressed=True, testnet=False):
        b = decode_base58_checksum(s)
        # prepend b'\xef' on testnet, b'\x80' on mainnet
        if testnet:
            prefix = b'\xef'
        else:
            prefix = b'\x80'

        if prefix != b[:1]:
            raise RuntimeError("bad suffix or prefix")

        # append b'\x01' if compressed
        if compressed:
            suffix = b'\x01'
            if suffix != b[-1:]:
                raise RuntimeError("bad suffix or prefix")
            secret_bytes = b[1:-1]
        else:
            secret_bytes = b[1:]
        return cls(big_endian_to_int(secret_bytes))
示例#16
0
def xpub_raw_parse(cls, s):
    version = s.read(4)
    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))
    depth = byte_to_int(s.read(1))
    parent_fingerprint = s.read(4)
    child_number = big_endian_to_int(s.read(4))
    chain_code = s.read(32)
    point = S256Point.parse(s.read(33))
    return cls(
        point=point,
        chain_code=chain_code,
        depth=depth,
        parent_fingerprint=parent_fingerprint,
        child_number=child_number,
        testnet=testnet,
    )
示例#17
0
 def child(self, index):
     '''Returns the child HDPrivateKey at a particular index.
     Hardened children return for indices >= 0x8000000.
     '''
     # if index >= 0x80000000
     if index >= 0x80000000:
         # the message data is the private key secret in 33 bytes in
         #  big-endian and the index in 4 bytes big-endian.
         data = int_to_big_endian(self.private_key.secret,
                                  33) + int_to_big_endian(index, 4)
     else:
         # the message data is the public key compressed SEC
         #  and the index in 4 bytes big-endian.
         data = self.private_key.point.sec() + int_to_big_endian(index, 4)
     # get the hmac_sha512 with chain code and data
     h = hmac_sha512(self.chain_code, data)
     # the new secret is the first 32 bytes as a big-endian integer
     #  plus the secret mod N
     secret = (big_endian_to_int(h[:32]) + self.private_key.secret) % N
     # create the PrivateKey object
     private_key = PrivateKey(secret=secret)
     # the chain code is the last 32 bytes
     chain_code = h[32:]
     # depth is whatever the current depth + 1
     depth = self.depth + 1
     # parent_fingerprint is the fingerprint of this node
     parent_fingerprint = self.fingerprint()
     # child number is the index
     child_number = index
     # return a new HDPrivateKey instance
     return HDPrivateKey(
         private_key=private_key,
         chain_code=chain_code,
         depth=depth,
         parent_fingerprint=parent_fingerprint,
         child_number=child_number,
         testnet=self.testnet,
     )
示例#18
0
文件: ecc.py 项目: jimmysong/minipy
 def encrypt_message(self, message: bytes) -> bytes:
     k = big_endian_to_int(token_bytes(32))
     private_key = PrivateKey(k)
     cipher = private_key.cipher(self)
     encrypted = cipher.encrypt(message)
     return private_key.point.sec() + encode_varstr(encrypted)