Esempio n. 1
0
class IcxSigner(object):
    """ ICX Signature utility class.
    """
    def __init__(self, data: object = None, raw: object = None) -> object:
        """
        :param data bytes or der (object):
        :param raw: (bool) True(bytes) False(der)
        """
        self.__private_key = PrivateKey(data, raw)

    @property
    def private_key_bytes(self):
        return self.__private_key.private_key

    @private_key_bytes.setter
    def private_key(self, data):
        self.__private_key.set_raw_privkey(data)

    @property
    def public_key_bytes(self):
        return self.__private_key.pubkey.serialize(compressed=False)

    @property
    def address(self):
        public_key_bytes = self.public_key_bytes
        return hashlib.sha3_256(public_key_bytes[1:]).digest()[-20:]

    def sign(self, msg_hash):
        """Make a signature using the hash value of msg.

        :param msg_hash: Result of sha3_256(msg) type(bytes)
        :return:
        Signature. type(bytes)
        """
        private_key_object = self.__private_key
        signature = private_key_object.ecdsa_sign(msg_hash, raw=True)
        return private_key_object.ecdsa_serialize(signature)

    def sign_recoverable(self, msg_hash):
        """Make a recoverable signature using message hash data.
        We can extract public key from recoverable signature.

        :param msg_hash: Hash data of message. type(bytes)
        :return:
        type(tuple)
        type(bytes): 65 bytes data , type(int): recovery id
        """
        private_key_object = self.__private_key
        recoverable_signature = private_key_object.ecdsa_sign_recoverable(
            msg_hash, raw=True)
        return private_key_object.ecdsa_recoverable_serialize(
            recoverable_signature)

    @staticmethod
    def from_bytes(data):
        return IcxSigner(data, raw=True)

    @staticmethod
    def from_der(data):
        return IcxSigner(data, raw=False)
class Secp256k1_compact(object):
    def __init__(self):
        self.priv_key = PrivateKey()
        self.pub_key = PublicKey(pubkey=None, raw=False, flags=secp256k1.ALL_FLAGS)

    def ecdsa_compact_sign(self, msg32, privkey):
        if type(privkey) == unicode:
            privkey = privkey.encode('utf-8')
        self.priv_key.set_raw_privkey(privkey)
        sig = self.priv_key.ecdsa_sign_recoverable(msg32, raw=True)
        return self.priv_key.ecdsa_recoverable_serialize(sig)

    def ecdsa_compact_recover(self, msg32, sign):
        if not len(sign) == 2:
            sign = (sign[:64], ord(sign[64]))
        assert len(sign) == 2
        deserialized_sig = self.pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1])
        self.pub_key.public_key = self.pub_key.ecdsa_recover(msg32, deserialized_sig, raw=True)
        return self.pub_key.serialize(compressed=False)

    def ecdsa_compact_verify(self, msg32, sign, pub):
        # Check if pubkey has been bin_electrum encoded.
        # If so, append \04 to the front of the key, to make sure the length is 65
        if len(pub) == 64:
            pub = '\04'+pub
        pub_k = PublicKey().deserialize(pub)
        pub_key = PublicKey(pub_k, raw=False, flags=secp256k1.ALL_FLAGS)
        der_sig = pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1])
        raw_sig = pub_key.ecdsa_recoverable_convert(der_sig)
        return pub_key.ecdsa_verify(msg32, raw_sig, raw=True)
Esempio n. 3
0
def test_eth_sign(web3, skip_if_testrpc):
    skip_if_testrpc(web3)

    private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a'
    private_key = decode_hex(private_key_hex)

    # This imports the private key into the running geth instance and unlocks
    # the account so that it can sign things.
    # `0xa5df35f30ba0ce878b1061ae086289adff3ba1e0`
    address = web3.personal.importRawKey(private_key, "password")
    web3.personal.unlockAccount(address, "password")

    assert add_0x_prefix(encode_hex(privtoaddr(private_key))) == add_0x_prefix(address)
    assert address == '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0'

    # the data to be signed
    data = b'1234567890abcdefghijklmnopqrstuvwxyz'
    # the hash of the data `0x089c33d56ed10bd8b571a0f493cedb28db1ae0f40c6cd266243001528c06eab3`
    data_hash = web3.sha3(data, encoding=None)
    data_hash_bytes = decode_hex(data_hash)

    assert force_bytes(data_hash) == sha3(data)

    priv_key = PrivateKey(flags=ALL_FLAGS)
    priv_key.set_raw_privkey(private_key)

    # sanit check the extract_ecdsa_signer function works as expected.
    vector_sig = priv_key.ecdsa_sign_recoverable(data_hash_bytes, raw=True, digest=sha3_256)
    vector_sig_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(vector_sig)
    vector_sig_bytes_full = vector_sig_bytes + force_bytes(chr(rec_id))
    vector_address = force_text(extract_ecdsa_signer(data_hash_bytes, vector_sig_bytes_full))

    assert vector_address == address

    # Now have geth sign some data.
    signature_hex = web3.eth.sign(address, data)
    signature_bytes = decode_hex(signature_hex)

    actual_signer = extract_ecdsa_signer(data_hash_bytes, signature_bytes)

    assert actual_signer == address

    # Verify the signature against the public key derived from the
    # original private key.  It fails.
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    recoverable_signature = priv_key.ecdsa_recoverable_deserialize(
        signature_bytes[:64],
        rec_id,
    )
    signature = priv_key.ecdsa_recoverable_convert(recoverable_signature)
    is_valid = priv_key.pubkey.ecdsa_verify(
        msg=data,
        raw_sig=signature,
        digest=sha3_256,
    )

    assert is_valid
    def _inner_sign(account, data_to_sign):
        signature_hash_hex = web3.sha3(encode_hex(data_to_sign))
        signature_hash_bytes = decode_hex(signature_hash_hex)

        private_key = tester.keys[tester.accounts.index(decode_hex(account))]
        priv_key = PrivateKey(flags=ALL_FLAGS)
        priv_key.set_raw_privkey(private_key)

        signature_raw = priv_key.ecdsa_sign_recoverable(
            signature_hash_bytes,
            raw=True,
            digest=sha3_256,
        )
        signature_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(signature_raw)
        signature = signature_bytes + force_bytes(chr(rec_id))

        # Sanity check that the signature is valid.
        signer_address = force_text(extract_ecdsa_signer(
            signature_hash_bytes,
            signature,
        ))

        assert signer_address == account
        return signature
Esempio n. 5
0
def test_eth_sign(web3, skip_if_testrpc):
    skip_if_testrpc(web3)

    private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a'
    private_key = decode_hex(private_key_hex)

    # This imports the private key into the running geth instance and unlocks
    # the account so that it can sign things.
    # address = '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0'
    address = web3.personal.importRawKey(private_key, "password")
    web3.personal.unlockAccount(address, "password")

    assert add_0x_prefix(encode_hex(
        privtoaddr(private_key))) == add_0x_prefix(address)
    assert address == '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0'

    # the data to be signed
    data = b'1234567890abcdefghijklmnopqrstuvwxyz'
    # the hash of the data `0x089c33d56ed10bd8b571a0f493cedb28db1ae0f40c6cd266243001528c06eab3`
    data_hash = web3.sha3(data, encoding=None)
    data_hash_bytes = decode_hex(data_hash)

    assert force_bytes(data_hash) == sha3(data)

    priv_key = PrivateKey(flags=ALL_FLAGS)
    priv_key.set_raw_privkey(private_key)

    # sanit check the extract_ecdsa_signer function works as expected.
    vector_sig = priv_key.ecdsa_sign_recoverable(data_hash_bytes,
                                                 raw=True,
                                                 digest=hashlib.sha3_256)
    vector_sig_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(vector_sig)
    vector_sig_bytes_full = vector_sig_bytes + force_bytes(chr(rec_id))
    vector_address = force_text(
        extract_ecdsa_signer(data_hash_bytes, vector_sig_bytes_full))

    assert vector_address == address

    # Now have geth sign some data.
    signature_hex = web3.eth.sign(address, data)
    signature_bytes = decode_hex(signature_hex)

    # geth prefix message before signing
    geth_prefix_data = eth_message_prefix_hash(web3, data.decode())

    actual_signer = extract_ecdsa_signer(force_bytes(geth_prefix_data),
                                         signature_bytes)

    assert actual_signer == address

    # Verify the signature against the public key derived from the
    # original private key.  It fails.
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    recoverable_signature = priv_key.ecdsa_recoverable_deserialize(
        signature_bytes[:64],
        rec_id,
    )
    signature = priv_key.ecdsa_recoverable_convert(recoverable_signature)
    is_valid = priv_key.pubkey.ecdsa_verify(
        msg=data,
        raw_sig=signature,
        digest=hashlib.sha3_256,
    )

    assert is_valid