示例#1
0
def main():
    # Mnemonics can be generated using `chia keys generate_and_print`, or `chia keys generate`. The latter stored
    # the key in the OS keychain (unencrypted file if linux).
    mnemonic: str = "neither medal holiday echo link dog sleep idea turkey logic security sword save taxi chapter artwork toddler wealth local mind manual never unlock narrow"

    seed: bytes = mnemonic_to_seed(mnemonic, passphrase="")
    master_private_key: PrivateKey = AugSchemeMPL.key_gen(seed)
    intermediate_sk: PrivateKey = AugSchemeMPL.derive_child_sk(
        master_private_key, 12381)
    intermediate_sk = AugSchemeMPL.derive_child_sk(intermediate_sk, 8444)
    intermediate_sk = AugSchemeMPL.derive_child_sk(intermediate_sk, 2)
    print(
        f"Parent public key is: {intermediate_sk.get_g1()}. Please use this within `create_unsigned_tx.py`"
    )

    # If you want to use hardened keys which are more secure against quantum computers, you need to export
    # The public keys
    # create_hardened_child_public_keys(mnemonic, 1000)

    try:
        with open("tx_3.json", "r") as f:
            spend_bundle_json = f.read()
    except Exception:
        print(
            "Error: create your transaction (spend bundle) json and put it into the json file."
        )
        return

    spend_bundle_json_dict: Dict = json.loads(spend_bundle_json)
    spend_bundle: SpendBundle = SpendBundle.from_json_dict(
        spend_bundle_json_dict)

    sign_tx(intermediate_sk, spend_bundle, use_hardened_keys=False)
示例#2
0
def private_key_from_mnemonic_seed_file(filename: Path) -> PrivateKey:
    """
    Create a private key from a mnemonic seed file.
    """

    mnemonic = filename.read_text().rstrip()
    seed = mnemonic_to_seed(mnemonic, "")
    return AugSchemeMPL.key_gen(seed)
示例#3
0
def mnemonic():
    # mnemonic = "imitate obvious arch square fan bike thumb hedgehog crystal innocent shoe glare share father romance local size gloom hurt maid denial weapon wave bulb"
    mnemonic = "turn acquire ring mind empower ahead section often habit sick sail mountain pen repair catch drum insect file dry trend venue junk novel laptop"
    seed = mnemonic_to_seed(mnemonic, "")
    master_private_key = AugSchemeMPL.key_gen(seed)
    child_private_key = master_sk_to_wallet_sk(master_private_key, 0)
    child_public_key = child_private_key.get_g1()
    puzzle = puzzle_for_pk(child_public_key)
    puzzle_hash = puzzle.get_tree_hash()
    address = encode_puzzle_hash(puzzle_hash, "txch")
示例#4
0
    def test_bip39_test_vectors_trezor(self):
        with open("tests/util/bip39_test_vectors.json") as f:
            all_vectors = json.loads(f.read())

        for vector_list in all_vectors["english"]:
            entropy_bytes = bytes.fromhex(vector_list[0])
            mnemonic = vector_list[1]
            seed = bytes.fromhex(vector_list[2])

            assert bytes_from_mnemonic(mnemonic) == entropy_bytes
            assert bytes_to_mnemonic(entropy_bytes) == mnemonic
            assert mnemonic_to_seed(mnemonic, "TREZOR") == seed
示例#5
0
    def test_utf8_nfkd(self):
        # Test code from trezor:
        # Copyright (c) 2013 Pavol Rusnak
        # Copyright (c) 2017 mruddy
        # https://github.com/trezor/python-mnemonic/blob/master/test_mnemonic.py
        # The same sentence in various UTF-8 forms
        words_nfkd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"  # noqa: E501
        words_nfc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"  # noqa: E501
        words_nfkc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"  # noqa: E501
        words_nfd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"  # noqa: E501

        passphrase_nfkd = "Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
        passphrase_nfc = "Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
        passphrase_nfkc = "Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
        passphrase_nfd = "Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"

        seed_nfkd = mnemonic_to_seed(words_nfkd, passphrase_nfkd)
        seed_nfc = mnemonic_to_seed(words_nfc, passphrase_nfc)
        seed_nfkc = mnemonic_to_seed(words_nfkc, passphrase_nfkc)
        seed_nfd = mnemonic_to_seed(words_nfd, passphrase_nfd)

        assert seed_nfkd == seed_nfc
        assert seed_nfkd == seed_nfkc
        assert seed_nfkd == seed_nfd
    def test_bip39_eip2333_test_vector(self):
        kc: Keychain = Keychain(testing=True)
        kc.delete_all_keys()

        mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
        passphrase = "TREZOR"
        print("entropy to seed:", mnemonic_to_seed(mnemonic, passphrase).hex())
        master_sk = kc.add_private_key(mnemonic, passphrase)
        tv_master_int = 5399117110774477986698372024995405256382522670366369834617409486544348441851
        tv_child_int = 11812940737387919040225825939013910852517748782307378293770044673328955938106
        assert master_sk == PrivateKey.from_bytes(
            tv_master_int.to_bytes(32, "big"))
        child_sk = AugSchemeMPL.derive_child_sk(master_sk, 0)
        assert child_sk == PrivateKey.from_bytes(
            tv_child_int.to_bytes(32, "big"))
    async def get_key_for_fingerprint(self, fingerprint: Optional[int]) -> Optional[PrivateKey]:
        """
        Locates and returns a private key matching the provided fingerprint
        """
        key: Optional[PrivateKey] = None
        if self.use_local_keychain():
            private_keys = self.keychain.get_all_private_keys()
            if len(private_keys) == 0:
                raise KeyringIsEmpty()
            else:
                if fingerprint is not None:
                    for sk, _ in private_keys:
                        if sk.get_g1().get_fingerprint() == fingerprint:
                            key = sk
                            break
                else:
                    key = private_keys[0][0]
        else:
            response, success = await self.get_response_for_request(
                "get_key_for_fingerprint", {"fingerprint": fingerprint}
            )
            if success:
                pk = response["data"].get("pk", None)
                ent = response["data"].get("entropy", None)
                if pk is None or ent is None:
                    err = f"Missing pk and/or ent in {response.get('command')} response"
                    self.log.error(f"{err}")
                    raise MalformedKeychainResponse(f"{err}")
                else:
                    mnemonic = bytes_to_mnemonic(bytes.fromhex(ent))
                    seed = mnemonic_to_seed(mnemonic, passphrase="")
                    private_key = AugSchemeMPL.key_gen(seed)
                    if bytes(private_key.get_g1()).hex() == pk:
                        key = private_key
                    else:
                        err = "G1Elements don't match"
                        self.log.error(f"{err}")
            else:
                self.handle_error(response)

        return key
示例#8
0
def create_hardened_child_public_keys(mnemonic: str, number: int = 5000):
    """
    Creates child public keys, derived from the master private key, using hardened derivation. This method is more
    secure than public key derivation since it's following the EIP-2333 spec for quantum security.
    """

    seed: bytes = mnemonic_to_seed(mnemonic, passphrase="")
    master_private_key: PrivateKey = AugSchemeMPL.key_gen(seed)

    intermediate_sk: PrivateKey = AugSchemeMPL.derive_child_sk(
        master_private_key, 12381)
    intermediate_sk = AugSchemeMPL.derive_child_sk(intermediate_sk, 8444)
    intermediate_sk = AugSchemeMPL.derive_child_sk(intermediate_sk, 2)

    all_pks: List[G1Element] = []
    for i in range(number):
        child_sk: PrivateKey = AugSchemeMPL.derive_child_sk(intermediate_sk, i)
        child_pk: G1Element = child_sk.get_g1()
        all_pks.append(child_pk)

    with open("child_public_keys.txt", "w") as f:
        lines = [f"{bytes(pk).hex()}\n" for pk in all_pks]
        f.writelines(lines)
    async def get_first_private_key(self) -> Optional[PrivateKey]:
        """
        Forwards to Keychain.get_first_private_key()
        """
        key: Optional[PrivateKey] = None
        if self.use_local_keychain():
            sk_ent = self.keychain.get_first_private_key()
            if sk_ent:
                key = sk_ent[0]
        else:
            response, success = await self.get_response_for_request("get_first_private_key", {})
            if success:
                private_key = response["data"].get("private_key", None)
                if private_key is None:
                    err = f"Missing private_key in {response.get('command')} response"
                    self.log.error(f"{err}")
                    raise MalformedKeychainResponse(f"{err}")
                else:
                    pk = private_key.get("pk", None)
                    ent_str = private_key.get("entropy", None)
                    if pk is None or ent_str is None:
                        err = f"Missing pk and/or ent in {response.get('command')} response"
                        self.log.error(f"{err}")
                        raise MalformedKeychainResponse(f"{err}")
                    ent = bytes.fromhex(ent_str)
                    mnemonic = bytes_to_mnemonic(ent)
                    seed = mnemonic_to_seed(mnemonic, passphrase="")
                    sk = AugSchemeMPL.key_gen(seed)
                    if bytes(sk.get_g1()).hex() == pk:
                        key = sk
                    else:
                        err = "G1Elements don't match"
                        self.log.error(f"{err}")
            else:
                self.handle_error(response)

        return key
示例#10
0
    async def get_all_private_keys(self) -> List[Tuple[PrivateKey, bytes]]:
        """
        Forwards to Keychain.get_all_private_keys()
        """
        keys: List[Tuple[PrivateKey, bytes]] = []
        if self.use_local_keychain():
            keys = self.keychain.get_all_private_keys()
        else:
            response, success = await self.get_response_for_request("get_all_private_keys", {})
            if success:
                private_keys = response["data"].get("private_keys", None)
                if private_keys is None:
                    err = f"Missing private_keys in {response.get('command')} response"
                    self.log.error(f"{err}")
                    raise MalformedKeychainResponse(f"{err}")
                else:
                    for key_dict in private_keys:
                        pk = key_dict.get("pk", None)
                        ent_str = key_dict.get("entropy", None)
                        if pk is None or ent_str is None:
                            err = f"Missing pk and/or ent in {response.get('command')} response"
                            self.log.error(f"{err}")
                            continue  # We'll skip the incomplete key entry
                        ent = bytes.fromhex(ent_str)
                        mnemonic = bytes_to_mnemonic(ent)
                        seed = mnemonic_to_seed(mnemonic, passphrase="")
                        key = AugSchemeMPL.key_gen(seed)
                        if bytes(key.get_g1()).hex() == pk:
                            keys.append((key, ent))
                        else:
                            err = "G1Elements don't match"
                            self.log.error(f"{err}")
            else:
                self.handle_error(response)

        return keys
示例#11
0
    async def add_private_key(self, mnemonic: str, passphrase: str) -> PrivateKey:
        """
        Forwards to Keychain.add_private_key()
        """
        key: PrivateKey
        if self.use_local_keychain():
            key = self.keychain.add_private_key(mnemonic, passphrase)
        else:
            response, success = await self.get_response_for_request(
                "add_private_key", {"mnemonic": mnemonic, "passphrase": passphrase}
            )
            if success:
                seed = mnemonic_to_seed(mnemonic, passphrase)
                key = AugSchemeMPL.key_gen(seed)
            else:
                error = response["data"].get("error", None)
                if error == KEYCHAIN_ERR_KEYERROR:
                    error_details = response["data"].get("error_details", {})
                    word = error_details.get("word", "")
                    raise KeyError(word)
                else:
                    self.handle_error(response)

        return key
示例#12
0
    def test_basic_add_delete(self):
        kc: Keychain = Keychain(user="******",
                                service="chia-testing-1.8.0")
        kc.delete_all_keys()

        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 0
        assert kc.get_first_private_key() is None
        assert kc.get_first_public_key() is None

        mnemonic = generate_mnemonic()
        entropy = bytes_from_mnemonic(mnemonic)
        assert bytes_to_mnemonic(entropy) == mnemonic
        mnemonic_2 = generate_mnemonic()

        # misspelled words in the mnemonic
        bad_mnemonic = mnemonic.split(" ")
        bad_mnemonic[6] = "ZZZZZZ"
        self.assertRaisesRegex(
            ValueError,
            "'ZZZZZZ' is not in the mnemonic dictionary; may be misspelled",
            bytes_from_mnemonic,
            " ".join(bad_mnemonic),
        )

        kc.add_private_key(mnemonic, "")
        assert kc._get_free_private_key_index() == 1
        assert len(kc.get_all_private_keys()) == 1

        kc.add_private_key(mnemonic_2, "")
        kc.add_private_key(mnemonic_2, "")  # checks to not add duplicates
        assert kc._get_free_private_key_index() == 2
        assert len(kc.get_all_private_keys()) == 2

        assert kc._get_free_private_key_index() == 2
        assert len(kc.get_all_private_keys()) == 2
        assert len(kc.get_all_public_keys()) == 2
        assert kc.get_all_private_keys()[0] == kc.get_first_private_key()
        assert kc.get_all_public_keys()[0] == kc.get_first_public_key()

        assert len(kc.get_all_private_keys()) == 2

        seed_2 = mnemonic_to_seed(mnemonic, "")
        seed_key_2 = AugSchemeMPL.key_gen(seed_2)
        kc.delete_key_by_fingerprint(seed_key_2.get_g1().get_fingerprint())
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 1

        kc.delete_all_keys()
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 0

        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase")
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "")
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)),
                           "third passphrase")

        assert len(kc.get_all_public_keys()) == 3
        assert len(kc.get_all_private_keys()) == 1
        assert len(kc.get_all_private_keys(["my passphrase", ""])) == 2
        assert len(
            kc.get_all_private_keys(
                ["my passphrase", "", "third passphrase", "another"])) == 3
        assert len(kc.get_all_private_keys(["my passhrase wrong"])) == 0

        assert kc.get_first_private_key() is not None
        assert kc.get_first_private_key(["bad passphrase"]) is None
        assert kc.get_first_public_key() is not None

        kc.delete_all_keys()
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase")
        assert kc.get_first_public_key() is not None
示例#13
0
    def test_basic_add_delete(self):
        kc: Keychain = Keychain(testing=True)
        kc.delete_all_keys()

        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 0
        assert kc.get_first_private_key() is None
        assert kc.get_first_public_key() is None

        mnemonic = generate_mnemonic()
        entropy = bytes_from_mnemonic(mnemonic)
        assert bytes_to_mnemonic(entropy) == mnemonic
        mnemonic_2 = generate_mnemonic()

        kc.add_private_key(mnemonic, "")
        assert kc._get_free_private_key_index() == 1
        assert len(kc.get_all_private_keys()) == 1

        kc.add_private_key(mnemonic_2, "")
        kc.add_private_key(mnemonic_2, "")  # checks to not add duplicates
        assert kc._get_free_private_key_index() == 2
        assert len(kc.get_all_private_keys()) == 2

        assert kc._get_free_private_key_index() == 2
        assert len(kc.get_all_private_keys()) == 2
        assert len(kc.get_all_public_keys()) == 2
        assert kc.get_all_private_keys()[0] == kc.get_first_private_key()
        assert kc.get_all_public_keys()[0] == kc.get_first_public_key()

        assert len(kc.get_all_private_keys()) == 2

        seed_2 = mnemonic_to_seed(mnemonic, "")
        seed_key_2 = AugSchemeMPL.key_gen(seed_2)
        kc.delete_key_by_fingerprint(seed_key_2.get_g1().get_fingerprint())
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 1

        kc.delete_all_keys()
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 0

        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase")
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "")
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)),
                           "third passphrase")

        assert len(kc.get_all_public_keys()) == 3
        assert len(kc.get_all_private_keys()) == 1
        assert len(kc.get_all_private_keys(["my passphrase", ""])) == 2
        assert len(
            kc.get_all_private_keys(
                ["my passphrase", "", "third passphrase", "another"])) == 3
        assert len(kc.get_all_private_keys(["my passhrase wrong"])) == 0

        assert kc.get_first_private_key() is not None
        assert kc.get_first_private_key(["bad passphrase"]) is None
        assert kc.get_first_public_key() is not None

        kc.delete_all_keys()
        kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase")
        assert kc.get_first_public_key() is not None