Esempio n. 1
0
    def test_basic_add_delete(self):
        kc: Keychain = Keychain(testing=True)
        kc.delete_all_keys()

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

        mnemonic = generate_mnemonic()
        seed = seed_from_mnemonic(mnemonic)
        mnemonic_2 = generate_mnemonic()
        seed_2 = seed_from_mnemonic(mnemonic_2)

        kc.add_private_key_seed(seed)
        assert kc._get_free_private_key_seed_index() == 1
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 1

        kc.add_private_key_seed(seed_2)
        kc.add_private_key_seed(seed_2)  # checks to not add duplicates
        assert kc._get_free_private_key_seed_index() == 2
        assert kc._get_free_private_key_index() == 0
        assert len(kc.get_all_private_keys()) == 2

        raw = ExtendedPrivateKey.from_seed(b"123")
        kc.add_private_key(raw)
        kc.add_private_key(raw)
        kc.add_private_key(raw)
        kc.add_private_key(raw)  # Checks to not add duplicates
        raw_2 = ExtendedPrivateKey.from_seed(b"1234")
        kc.add_private_key(raw_2)

        assert kc._get_free_private_key_seed_index() == 2
        assert kc._get_free_private_key_index() == 2
        assert len(kc.get_all_private_keys()) == 4
        assert len(kc.get_all_public_keys()) == 4
        assert raw in [k for (k, s) in kc.get_all_private_keys()]

        kc.delete_key_by_fingerprint(raw_2.get_public_key().get_fingerprint())
        assert kc._get_free_private_key_index() == 1
        assert len(kc.get_all_private_keys()) == 3

        seed_key_2 = ExtendedPrivateKey.from_seed(seed_2)
        kc.delete_key_by_fingerprint(seed_key_2.get_public_key().get_fingerprint())
        assert kc._get_free_private_key_seed_index() == 1
        assert len(kc.get_all_private_keys()) == 2

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

        kc.add_private_key_not_extended(raw_2.get_private_key())
        assert kc._get_free_private_key_seed_index() == 0
        assert kc._get_free_private_key_index() == 1
        assert len(kc.get_all_private_keys()) == 1
        assert raw_2 not in [k for (k, s) in kc.get_all_private_keys()]
        assert raw_2.get_private_key() in [
            k.get_private_key() for (k, s) in kc.get_all_private_keys()
        ]
Esempio n. 2
0
    def delete_key_by_fingerprint(self, fingerprint: int):
        """
        Deletes all keys which have the given public key fingerprint.
        """

        index = 0
        key_hex = self._get_stored_entropy(self._get_private_key_user(index))

        while key_hex is not None and len(key_hex) > 0:
            key = ExtendedPrivateKey.from_bytes(hexstr_to_bytes(key_hex))
            if key.get_public_key().get_fingerprint() == fingerprint:
                keyring.delete_password(
                    self._get_service(), self._get_private_key_user(index)
                )
            index += 1
            key_hex = self._get_stored_entropy(self._get_private_key_user(index))

        index = 0
        seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
        while seed_hex is not None and len(seed_hex) > 0:
            key = ExtendedPrivateKey.from_seed(hexstr_to_bytes(seed_hex))
            if key.get_public_key().get_fingerprint() == fingerprint:
                keyring.delete_password(
                    self._get_service(), self._get_private_key_seed_user(index)
                )
            index += 1
            seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
Esempio n. 3
0
def additional_python_methods():
    private_key = PrivateKey.from_seed(b'123')
    s1 = private_key.sign(b'message')
    s2 = private_key.sign_prepend(b'message')
    assert s1.get_insecure_sig().verify([Util.hash256(b'message')],
                                        [private_key.get_public_key()])
    assert s2.get_insecure_sig().verify([
        Util.hash256(private_key.get_public_key().serialize() +
                     Util.hash256(b'message'))
    ], [private_key.get_public_key()])
    s1_b = Signature.from_insecure_sig(s1.get_insecure_sig())
    s2_b = PrependSignature.from_insecure_sig(s2.get_insecure_sig())
    assert s1 == s1_b and s2 == s2_b

    s3 = private_key.sign_insecure_prehashed(Util.hash256(b'456'))
    assert s3.verify([Util.hash256(b'456')], [private_key.get_public_key()])

    esk = ExtendedPrivateKey.from_seed(b'789')
    epk = esk.get_public_key()
    s3 = private_key.sign(b'message3')
    s4 = private_key.sign_insecure(b'message3')

    assert bytes(private_key) == private_key.serialize()
    assert deepcopy(private_key) == private_key
    assert deepcopy(s1) == s1
    assert deepcopy(s2) == s2
    assert deepcopy(s3) == s3
    assert deepcopy(s4) == s4
    assert deepcopy(
        private_key.get_public_key()) == private_key.get_public_key()
    assert deepcopy(esk) == esk
    assert deepcopy(epk) == epk
    assert deepcopy(esk.get_chain_code()) == esk.get_chain_code()
Esempio n. 4
0
    def get_all_private_keys(self) -> List[Tuple[ExtendedPrivateKey, Optional[bytes]]]:
        """
        Returns all private keys (both seed-derived keys and raw ExtendedPrivateKeys), and
        the second value in the tuple is the bytes seed if it exists, otherwise None.
        """
        all_keys: List[Tuple[ExtendedPrivateKey, Optional[bytes]]] = []

        # Keys that have a seed are added first
        index = 0
        seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
        while seed_hex is not None and len(seed_hex) > 0:
            key = ExtendedPrivateKey.from_seed(hexstr_to_bytes(seed_hex))
            all_keys.append((key, hexstr_to_bytes(seed_hex)))
            index += 1
            seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))

        # Keys without a seed are added after
        index = 0
        key_hex = self._get_stored_entropy(self._get_private_key_user(index))
        while key_hex is not None and len(key_hex) > 0:
            key = ExtendedPrivateKey.from_bytes(hexstr_to_bytes(key_hex))
            all_keys.append((key, None))
            index += 1
            key_hex = self._get_stored_entropy(self._get_private_key_user(index))
        return all_keys
Esempio n. 5
0
 def __init__(self):
     self.current_balance = 0
     self.my_utxos: set = set()
     self.seed = urandom(1024)
     self.extended_secret_key = ExtendedPrivateKey.from_seed(self.seed)
     self.generator_lookups: Dict = {}
     self.name = "MyChiaWallet"
     self.puzzle_pk_cache: Dict = {}
Esempio n. 6
0
def generate(args, parser):
    root_path = args.root_path
    keys_yaml = "keys.yaml"
    key_config_filename = config_path_for_filename(root_path, keys_yaml)
    if args.keys != ["keys"]:
        parser.print_help()
        print("\nTry `chia generate keys`")
        return 1
    if key_config_filename.exists():
        # If the file exists, warn the user
        yn = input(
            f"The keys file {key_config_filename} already exists. Are you sure"
            f" you want to override the keys? Plots might become invalid. (y/n): "
        )
        if not (yn.lower() == "y" or yn.lower() == "yes"):
            return 1
    else:
        # Create the file if if doesn't exist
        mkdir(key_config_filename.parent)
        open(key_config_filename, "a").close()

    key_config = load_config(root_path, keys_yaml)
    if key_config is None:
        key_config = {}

    wallet_target = None
    if args.wallet:
        wallet_sk = ExtendedPrivateKey.from_seed(token_bytes(32))
        wallet_target = create_puzzlehash_for_pk(
            BLSPublicKey(bytes(wallet_sk.public_child(0).get_public_key()))
        )
        key_config["wallet_sk"] = bytes(wallet_sk).hex()
        key_config["wallet_target"] = wallet_target.hex()
        save_config(root_path, keys_yaml, key_config)
    if args.harvester:
        # Replaces the harvester's sk seed. Used to generate plot private keys, which are
        # used to sign farmed blocks.
        key_config["sk_seed"] = token_bytes(32).hex()
        save_config(root_path, keys_yaml, key_config)
    if args.pool:
        # Replaces the pools keys and targes. Only useful if running a pool, or doing
        # solo farming. The pool target allows spending of the coinbase.
        pool_sks = [PrivateKey.from_seed(token_bytes(32)) for _ in range(2)]
        if wallet_target is None:
            pool_target = create_puzzlehash_for_pk(
                BLSPublicKey(bytes(pool_sks[0].get_public_key()))
            )
        else:
            pool_target = wallet_target
        key_config["pool_sks"] = [bytes(pool_sk).hex() for pool_sk in pool_sks]
        key_config["pool_target"] = pool_target.hex()
        save_config(root_path, keys_yaml, key_config)
    if args.pooltarget:
        # Compute a new pool target and save it to the config
        assert "wallet_target" in key_config
        key_config["pool_target"] = key_config["wallet_target"]
        save_config(root_path, keys_yaml, key_config)
Esempio n. 7
0
    async def add_key(self, request):
        if "mnemonic" in request:
            # Adding a key from 24 word mnemonic
            mnemonic = request["mnemonic"]
            seed = seed_from_mnemonic(mnemonic)
            self.keychain.add_private_key_seed(seed)
            esk = ExtendedPrivateKey.from_seed(seed)
        elif "hexkey" in request:
            # Adding a key from hex private key string. Two cases: extended private key (HD)
            # which is 77 bytes, and int private key which is 32 bytes.
            if len(request["hexkey"]) != 154 and len(request["hexkey"]) != 64:
                return {"success": False}
            if len(request["hexkey"]) == 64:
                sk = PrivateKey.from_bytes(bytes.fromhex(request["hexkey"]))
                self.keychain.add_private_key_not_extended(sk)
                key_bytes = bytes(sk)
                new_extended_bytes = bytearray(
                    bytes(ExtendedPrivateKey.from_seed(token_bytes(32))))
                final_extended_bytes = bytes(
                    new_extended_bytes[:-len(key_bytes)] + key_bytes)
                esk = ExtendedPrivateKey.from_bytes(final_extended_bytes)
            else:
                esk = ExtendedPrivateKey.from_bytes(
                    bytes.fromhex(request["hexkey"]))
                self.keychain.add_private_key(esk)

        else:
            return {"success": False}

        fingerprint = esk.get_public_key().get_fingerprint()
        await self.stop_wallet()
        # Makes sure the new key is added to config properly
        check_keys(self.root_path)

        # Starts the wallet with the new key selected
        started = await self.start_wallet(fingerprint)

        response = {"success": started}
        return response
Esempio n. 8
0
 def __init__(self):
     self.current_balance = 0
     self.my_utxos = set()
     self.seed = urandom(1024)
     self.extended_secret_key = ExtendedPrivateKey.from_seed(self.seed)
     # self.contacts = {}  # {'name': (puzzlegenerator, last, extradata)}
     self.generator_lookups = {}  # {generator_hash: generator}
     self.name = "MyChiaWallet"
     self.generator_lookups[
         self.puzzle_generator_id] = self.puzzle_generator
     self.temp_utxos = set()
     self.temp_balance = 0
     self.all_additions = {}
     self.all_deletions = {}
Esempio n. 9
0
def no_throw_bad_sig():
    private_key = ExtendedPrivateKey.from_seed(b"foo").get_private_key()

    message_hash = bytes([9] * 32)

    sig = private_key.sign_prepend_prehashed(message_hash).serialize()
    sig = sig[:-1] + bytes([0])

    public_key = private_key.get_public_key()

    try:
        bad_signature = PrependSignature.from_bytes(sig)
    except ValueError:
        return
    assert (False)
Esempio n. 10
0
 def add_private_key_seed(self, seed: bytes):
     """
     Adds a private key seed to the keychain. This is the best way to add keys, since they can
     be backed up to mnemonics. A seed is used to generate a BLS ExtendedPrivateKey.
     """
     index = self._get_free_private_key_seed_index()
     key = ExtendedPrivateKey.from_seed(seed)
     if key.get_public_key().get_fingerprint() in [
         epk.get_public_key().get_fingerprint() for epk in self.get_all_public_keys()
     ]:
         # Prevents duplicate add
         return
     keyring.set_password(
         self._get_service(), self._get_private_key_seed_user(index), seed.hex()
     )
Esempio n. 11
0
def test_vectors3():
    seed = bytes([1, 50, 6, 244, 24, 199, 1, 25])
    esk = ExtendedPrivateKey.from_seed(seed)
    assert (esk.get_public_key().get_fingerprint() == 0xa4700b27)
    assert (esk.get_chain_code().serialize().hex() ==
            "d8b12555b4cc5578951e4a7c80031e22019cc0dce168b3ed88115311b8feb1e3")
    esk77 = esk.private_child(77 + 2**31)
    assert (esk77.get_chain_code().serialize().hex() ==
            "f2c8e4269bb3e54f8179a5c6976d92ca14c3260dd729981e9d15f53049fd698b")
    assert (esk77.get_public_key().get_fingerprint() == 0xa8063dcf)

    assert (esk.private_child(3).private_child(
        17).get_public_key().get_fingerprint() == 0xff26a31f)

    assert (esk.get_extended_public_key().public_child(3).public_child(
        17).get_public_key().get_fingerprint() == 0xff26a31f)
Esempio n. 12
0
    async def add_key(self, request):
        await self.stop_wallet()
        mnemonic = request["mnemonic"]
        self.log.info(f"Mnemonic {mnemonic}")
        seed = seed_from_mnemonic(mnemonic)
        self.log.info(f"Seed {seed}")
        fingerprint = (
            ExtendedPrivateKey.from_seed(seed).get_public_key().get_fingerprint()
        )
        self.keychain.add_private_key_seed(seed)
        check_keys(self.root_path)

        started = await self.start_wallet(fingerprint)

        response = {"success": started}
        return response
Esempio n. 13
0
    def add_private_key_not_extended(self, key_not_extended: PrivateKey):
        """
        Creates a new key, and takes only the prefix information (chain code, version, etc).
        This is used to migrate pool_sks from keys.yaml, which are not extended. Then adds
        the key to the keychain.
        """

        key_bytes = bytes(key_not_extended)
        new_extended_bytes = bytearray(
            bytes(ExtendedPrivateKey.from_seed(token_bytes(32)))
        )
        final_extended_bytes = bytes(new_extended_bytes[: -len(key_bytes)] + key_bytes)
        key = ExtendedPrivateKey.from_bytes(final_extended_bytes)
        assert len(final_extended_bytes) == len(new_extended_bytes)
        assert key.get_private_key() == key_not_extended
        self.add_private_key(key)
Esempio n. 14
0
def throw_wrong_type():
    private_key = ExtendedPrivateKey.from_seed(b"foo").get_private_key()

    message_hash = bytes([10] * 32)

    sig_prepend = private_key.sign_prepend_prehashed(message_hash).serialize()
    sig_secure = private_key.sign_prehashed(message_hash).serialize()

    try:
        Signature.from_bytes(sig_prepend)
    except ValueError:
        try:
            PrependSignature.from_bytes(sig_secure)
        except ValueError:
            return
        assert False
    assert False
Esempio n. 15
0
def add_private_key_seed(mnemonic):
    """
    Add a private key seed to the keyring, with the given mnemonic.
    """

    try:
        seed = seed_from_mnemonic(mnemonic)
        fingerprint = (ExtendedPrivateKey.from_seed(
            seed).get_public_key().get_fingerprint())
        print(
            f"Adding private key with public key fingerprint {fingerprint} and mnemonic"
        )
        print(f"{mnemonic_to_string(mnemonic)}")

        keychain.add_private_key_seed(seed)
    except ValueError as e:
        print(e)
        return
Esempio n. 16
0
def test1():
    seed = bytes([
        0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18,
        102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22
    ])
    sk = PrivateKey.from_seed(seed)
    pk = sk.get_public_key()

    msg = bytes([100, 2, 254, 88, 90, 45, 23])

    sig = sk.sign(msg)

    sk_bytes = sk.serialize()
    pk_bytes = pk.serialize()
    sig_bytes = sig.serialize()

    sk = PrivateKey.from_bytes(sk_bytes)
    pk = PublicKey.from_bytes(pk_bytes)
    sig = Signature.from_bytes(sig_bytes)

    sig.set_aggregation_info(AggregationInfo.from_msg(pk, msg))
    ok = sig.verify()
    assert (ok)

    seed = bytes([1]) + seed[1:]
    sk1 = PrivateKey.from_seed(seed)
    seed = bytes([2]) + seed[1:]
    sk2 = PrivateKey.from_seed(seed)

    pk1 = sk1.get_public_key()
    sig1 = sk1.sign(msg)

    pk2 = sk2.get_public_key()
    sig2 = sk2.sign(msg)

    agg_sig = Signature.aggregate([sig1, sig2])
    agg_pubkey = PublicKey.aggregate([pk1, pk2])

    agg_sig.set_aggregation_info(AggregationInfo.from_msg(agg_pubkey, msg))
    assert (agg_sig.verify())

    seed = bytes([3]) + seed[1:]
    sk3 = PrivateKey.from_seed(seed)
    pk3 = sk3.get_public_key()
    msg2 = bytes([100, 2, 254, 88, 90, 45, 23])

    sig1 = sk1.sign(msg)
    sig2 = sk2.sign(msg)
    sig3 = sk3.sign(msg2)
    agg_sig_l = Signature.aggregate([sig1, sig2])
    agg_sig_final = Signature.aggregate([agg_sig_l, sig3])

    sig_bytes = agg_sig_final.serialize()

    agg_sig_final = Signature.from_bytes(sig_bytes)
    a1 = AggregationInfo.from_msg(pk1, msg)
    a2 = AggregationInfo.from_msg(pk2, msg)
    a3 = AggregationInfo.from_msg(pk3, msg2)
    a1a2 = AggregationInfo.merge_infos([a1, a2])
    a_final = AggregationInfo.merge_infos([a1a2, a3])
    print(a_final)
    agg_sig_final.set_aggregation_info(a_final)
    ok = agg_sig_final.verify()

    ok = agg_sig_l.verify()
    agg_sig_final = agg_sig_final.divide_by([agg_sig_l])

    ok = agg_sig_final.verify()

    agg_sk = PrivateKey.aggregate([sk1, sk2], [pk1, pk2])
    agg_sk.sign(msg)

    seed = bytes([
        1, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18,
        102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22
    ])

    esk = ExtendedPrivateKey.from_seed(seed)
    epk = esk.get_extended_public_key()

    sk_child = esk.private_child(0).private_child(5)
    pk_child = epk.public_child(0).public_child(5)

    buffer1 = pk_child.serialize()
    buffer2 = sk_child.serialize()

    print(len(buffer1), buffer1)
    print(len(buffer2), buffer2)
    assert (sk_child.get_extended_public_key() == pk_child)
def main():
    """
    Allows replacing keys of farmer, harvester, and pool, all default to True.
    """

    root_path = DEFAULT_ROOT_PATH
    keys_yaml = "keys.yaml"
    parser = argparse.ArgumentParser(description="Chia key generator script.")
    parser.add_argument(
        "-a",
        "--harvester",
        type=str2bool,
        nargs="?",
        const=True,
        default=True,
        help="Regenerate plot key seed",
    )
    parser.add_argument(
        "-p",
        "--pool",
        type=str2bool,
        nargs="?",
        const=True,
        default=True,
        help="Regenerate pool keys",
    )
    parser.add_argument(
        "-w",
        "--wallet",
        type=str2bool,
        nargs="?",
        const=True,
        default=True,
        help="Regenerate wallet keys",
    )
    args = parser.parse_args()

    key_config_filename = config_path_for_filename(root_path, keys_yaml)
    if key_config_filename.exists():
        # If the file exists, warn the user
        yn = input(
            f"The keys file {key_config_filename} already exists. Are you sure"
            f" you want to override the keys? Plots might become invalid. (y/n): "
        )
        if not (yn.lower() == "y" or yn.lower() == "yes"):
            quit()
    else:
        # Create the file if if doesn't exist
        mkdir(key_config_filename.parent)
        open(key_config_filename, "a").close()

    key_config = load_config(root_path, keys_yaml)
    if key_config is None:
        key_config = {}

    wallet_target = None
    if args.wallet:
        wallet_sk = ExtendedPrivateKey.from_seed(token_bytes(32))
        wallet_target = create_puzzlehash_for_pk(
            BLSPublicKey(bytes(wallet_sk.public_child(0).get_public_key())))
        key_config["wallet_sk"] = bytes(wallet_sk).hex()
        key_config["wallet_target"] = wallet_target.hex()
        save_config(root_path, keys_yaml, key_config)
    if args.harvester:
        # Replaces the harvester's sk seed. Used to generate plot private keys, which are
        # used to sign farmed blocks.
        key_config["sk_seed"] = token_bytes(32).hex()
        save_config(root_path, keys_yaml, key_config)
    if args.pool:
        # Replaces the pools keys and targes. Only useful if running a pool, or doing
        # solo farming. The pool target allows spending of the coinbase.
        pool_sks = [PrivateKey.from_seed(token_bytes(32)) for _ in range(2)]
        if wallet_target is None:
            pool_target = create_puzzlehash_for_pk(
                BLSPublicKey(bytes(pool_sks[0].get_public_key())))
        else:
            pool_target = wallet_target
        key_config["pool_sks"] = [bytes(pool_sk).hex() for pool_sk in pool_sks]
        key_config["pool_target"] = pool_target.hex()
        save_config(root_path, keys_yaml, key_config)
Esempio n. 18
0
    print(f"cost of one_greater is: {one_greater}")
    print(f"cost of one_equal is: {one_equal}")
    print(f"cost of one_if is: {one_if}")
    print(f"cost of one_sha256 is: {one_sha256}")
    print(f"cost of one_pubkey_for_exp is: {one_pubkey_for_exp}")
    print(f"cost of one_point_add is: {one_point_add}")


if __name__ == "__main__":
    """
    Naive way to calculate cost ratio between vByte and CLVM cost unit.
    AggSig has assigned cost of 20vBytes, simple CLVM program is benchmarked against it.
    """
    wallet_tool = WalletTool()
    benchmark_all_operators()
    extended_secret_key: ExtendedPrivateKey = ExtendedPrivateKey.from_seed(
        b"a")
    puzzles = []
    solutions = []
    private_keys = []
    public_keys = []

    for i in range(0, 1000):
        private_key: BLSPrivateKey = BLSPrivateKey(
            extended_secret_key.private_child(i).get_private_key())
        public_key = private_key.public_key()
        solution = wallet_tool.make_solution({
            ConditionOpcode.ASSERT_MY_COIN_ID: [
                ConditionVarPair(ConditionOpcode.ASSERT_MY_COIN_ID,
                                 token_bytes(), None)
            ]
        })