def load_pool_config(root_path: Path) -> List[PoolWalletConfig]: config = load_config(root_path, "config.yaml") ret_list: List[PoolWalletConfig] = [] if "pool_list" in config["pool"]: for pool_config_dict in config["pool"]["pool_list"]: try: pool_config = PoolWalletConfig( bytes32.from_hexstr(pool_config_dict["launcher_id"]), pool_config_dict["pool_url"], pool_config_dict["payout_instructions"], bytes32.from_hexstr( pool_config_dict["target_puzzle_hash"]), bytes32.from_hexstr( pool_config_dict["p2_singleton_puzzle_hash"]), G1Element.from_bytes( hexstr_to_bytes(pool_config_dict["owner_public_key"])), G1Element.from_bytes( hexstr_to_bytes( pool_config_dict["authentication_public_key"])), ) ret_list.append(pool_config) except Exception as e: log.error(f"Exception loading config: {pool_config_dict} {e}") return ret_list
async def test_keys_missing(test_environment: TestEnvironment) -> None: env: TestEnvironment = test_environment not_in_keychain_plots: List[Path] = get_test_plots("not_in_keychain") dir_not_in_keychain: TestDirectory = TestDirectory( env.root_path / "plots" / "not_in_keychain", not_in_keychain_plots ) expected_result = PlotRefreshResult() # The plots in "not_in_keychain" directory have infinity g1 elements as farmer/pool key so they should be plots # with missing keys for now add_plot_directory(env.root_path, str(dir_not_in_keychain.path)) expected_result.loaded = [] expected_result.removed = [] expected_result.processed = len(dir_not_in_keychain) expected_result.remaining = 0 for i in range(2): await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.no_key_filenames) == len(dir_not_in_keychain) for path in env.refresh_tester.plot_manager.no_key_filenames: assert path in dir_not_in_keychain.plots # Delete one of the plots and make sure it gets dropped from the no key filenames list drop_plot = dir_not_in_keychain.path_list()[0] dir_not_in_keychain.drop(drop_plot) drop_plot.unlink() assert drop_plot in env.refresh_tester.plot_manager.no_key_filenames expected_result.processed -= 1 await env.refresh_tester.run(expected_result) assert drop_plot not in env.refresh_tester.plot_manager.no_key_filenames # Now add the missing keys to the plot manager's key lists and make sure the plots are getting loaded env.refresh_tester.plot_manager.farmer_public_keys.append(G1Element()) env.refresh_tester.plot_manager.pool_public_keys.append(G1Element()) expected_result.loaded = dir_not_in_keychain.plot_info_list() # type: ignore[assignment] expected_result.processed = len(dir_not_in_keychain) await env.refresh_tester.run(expected_result) # And make sure they are dropped from the list of plots with missing keys assert len(env.refresh_tester.plot_manager.no_key_filenames) == 0
async def resolve(self) -> PlotKeys: if self.resolved_keys is not None: return self.resolved_keys keychain_proxy: Optional[KeychainProxy] = None if self.connect_to_daemon: keychain_proxy = await connect_to_keychain_and_validate(self.root_path, self.log) else: keychain_proxy = wrap_local_keychain(Keychain(), log=self.log) farmer_public_key: G1Element if self.farmer_public_key is not None: farmer_public_key = G1Element.from_bytes(bytes.fromhex(self.farmer_public_key)) else: farmer_public_key = await self.get_farmer_public_key(keychain_proxy) pool_public_key: Optional[G1Element] = None if self.pool_public_key is not None: if self.pool_contract_address is not None: raise RuntimeError("Choose one of pool_contract_address and pool_public_key") pool_public_key = G1Element.from_bytes(bytes.fromhex(self.pool_public_key)) else: if self.pool_contract_address is None: # If nothing is set, farms to the provided key (or the first key) pool_public_key = await self.get_pool_public_key(keychain_proxy) self.resolved_keys = PlotKeys(farmer_public_key, pool_public_key, self.pool_contract_address) return self.resolved_keys
def parse_plot_info(memo: bytes) -> Tuple[G1Element, G1Element, PrivateKey]: # Parses the plot info bytes into keys assert len(memo) == (48 + 48 + 32) return ( G1Element.from_bytes(memo[:48]), G1Element.from_bytes(memo[48:96]), PrivateKey.from_bytes(memo[96:]), )
def op_point_add(items): cost = POINT_ADD_BASE_COST p = G1Element.generator() * 0 for _ in items.as_iter(): try: p += G1Element.from_bytes(_.as_atom()) cost += POINT_ADD_COST_PER_ARG except Exception as ex: raise EvalError("point_add expects blob, got %s: %s" % (_, ex), items) return cost, items.to(p)
def op_point_add(items: SExp): cost = POINT_ADD_BASE_COST p = G1Element() for _ in items.as_iter(): if _.pair: raise EvalError("point_add on list", _) try: p += G1Element.from_bytes(_.as_atom()) cost += POINT_ADD_COST_PER_ARG except Exception as ex: raise EvalError("point_add expects blob, got %s: %s" % (_, ex), items) return malloc_cost(cost, items.to(p))
def test_1(self): for main_secret_exponent in range(500, 600): hidden_puzzle_hash = DEFAULT_HIDDEN_PUZZLE.get_tree_hash() main_pubkey = G1Element.generator() * main_secret_exponent offset = calculate_synthetic_offset(main_pubkey, hidden_puzzle_hash) offset_pubkey = G1Element.generator() * offset spk1 = main_pubkey + offset_pubkey spk2 = calculate_synthetic_public_key(main_pubkey, hidden_puzzle_hash) assert spk1 == spk2 return 0
def pkm_pairs_for_conditions_dict( conditions_dict: Dict[ConditionOpcode, List[ConditionVarPair]], coin_name: bytes32 = None, ) -> List[Tuple[G1Element, bytes]]: ret: List[Tuple[G1Element, bytes]] = [] for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG, []): # TODO: check types # assert len(_) == 3 assert cvp.var2 is not None ret.append((G1Element.from_bytes(cvp.var1), cvp.var2)) if coin_name is not None: for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []): ret.append((G1Element.from_bytes(cvp.var1), cvp.var2 + coin_name)) return ret
def puzzle(): # public key --> puzzle pb = "b95e11eccf667b4312588094db0725257f4ce440835d808ed749c9ec39dc5c3afbfdfda7bbf24f2adb58335e848a7a94" g: G1Element = G1Element.from_bytes(bytes.fromhex(pb)) puzzle = puzzle_for_pk(g) h = "ff02ffff01ff02ffff01ff02ffff03ff0bffff01ff02ffff03ffff09ff05ffff1dff0bffff1effff0bff0bffff02ff06ffff04ff02ffff04ff17ff8080808080808080ffff01ff02ff17ff2f80ffff01ff088080ff0180ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff17ff80808080ff80808080ffff02ff17ff2f808080ff0180ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0a76f5e6a0fdb34124b18b492de6cb6ba637571df77c7e8be29a8e9127c4b94cee5cf385ad0c867b67d762fece5993a7eff018080" return str(puzzle) == h
async def get_derivation_record( self, index: uint32, wallet_id: uint32, hardened: bool ) -> Optional[DerivationRecord]: """ Returns the derivation record by index and wallet id. """ if hardened: hard = 1 else: hard = 0 cursor = await self.db_connection.execute( "SELECT * FROM derivation_paths WHERE derivation_index=? and wallet_id=? and hardened=?;", (index, wallet_id, hard), ) row = await cursor.fetchone() await cursor.close() if row is not None and row[0] is not None: return DerivationRecord( uint32(row[0]), bytes32.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), WalletType(row[3]), uint32(row[4]), bool(row[5]), ) return None
def test_cached_bls(self): n_keys = 10 seed = b"a" * 31 sks = [AugSchemeMPL.key_gen(seed + bytes([i])) for i in range(n_keys)] pks = [bytes(sk.get_g1()) for sk in sks] msgs = [("msg-%d" % (i,)).encode() for i in range(n_keys)] sigs = [AugSchemeMPL.sign(sk, msg) for sk, msg in zip(sks, msgs)] agg_sig = AugSchemeMPL.aggregate(sigs) pks_half = pks[: n_keys // 2] msgs_half = msgs[: n_keys // 2] sigs_half = sigs[: n_keys // 2] agg_sig_half = AugSchemeMPL.aggregate(sigs_half) assert AugSchemeMPL.aggregate_verify([G1Element.from_bytes(pk) for pk in pks], msgs, agg_sig) # Verify with empty cache and populate it assert cached_bls.aggregate_verify(pks_half, msgs_half, agg_sig_half, True) # Verify with partial cache hit assert cached_bls.aggregate_verify(pks, msgs, agg_sig, True) # Verify with full cache hit assert cached_bls.aggregate_verify(pks, msgs, agg_sig) # Use a small cache which can not accommodate all pairings local_cache = LRUCache(n_keys // 2) # Verify signatures and cache pairings one at a time for pk, msg, sig in zip(pks_half, msgs_half, sigs_half): assert cached_bls.aggregate_verify([pk], [msg], sig, True, local_cache) # Verify the same messages with aggregated signature (full cache hit) assert cached_bls.aggregate_verify(pks_half, msgs_half, agg_sig_half, False, local_cache) # Verify more messages (partial cache hit) assert cached_bls.aggregate_verify(pks, msgs, agg_sig, False, local_cache)
def test_g1element(self): b = fh( "b3b8ac537f4fd6bde9b26221d49b54b17a506be147347dae5" "d081c0a6572b611d8484e338f3432971a9823976c6a232b" ) v = SExp.to(G1Element(b)) self.assertEqual(v.atom, b)
async def get_derivation_record( self, index: uint32, wallet_id: uint32) -> Optional[DerivationRecord]: """ Returns the derivation record by index and wallet id. """ cursor = await self.db_connection.execute( "SELECT * FROM derivation_paths WHERE derivation_index=? and wallet_id=?;", ( index, wallet_id, ), ) row = await cursor.fetchone() await cursor.close() if row is not None and row[0] is not None: return DerivationRecord( row[0], bytes.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), row[3], row[4], ) return None
def test_stream(self): for _ in range(1, 64): p = PrivateKey.from_bytes(_.to_bytes(32, "big")).get_g1() blob = bytes(p) p1 = G1Element.from_bytes(blob) self.assertEqual(len(blob), 48) self.assertEqual(p, p1)
def __init__( self, root_path: Path, farmer_config: Dict, pool_config: Dict, keychain: Keychain, consensus_constants: ConsensusConstants, ): self._root_path = root_path self.config = farmer_config # Keep track of all sps, keyed on challenge chain signage point hash self.sps: Dict[bytes32, List[farmer_protocol.NewSignagePoint]] = {} # Keep track of harvester plot identifier (str), target sp index, and PoSpace for each challenge self.proofs_of_space: Dict[bytes32, List[Tuple[str, ProofOfSpace]]] = {} # Quality string to plot identifier and challenge_hash, for use with harvester.RequestSignatures self.quality_str_to_identifiers: Dict[bytes32, Tuple[str, bytes32, bytes32, bytes32]] = {} # number of responses to each signage point self.number_of_responses: Dict[bytes32, int] = {} # A dictionary of keys to time added. These keys refer to keys in the above 4 dictionaries. This is used # to periodically clear the memory self.cache_add_time: Dict[bytes32, uint64] = {} self.cache_clear_task: asyncio.Task self.constants = consensus_constants self._shut_down = False self.server: Any = None self.keychain = keychain self.state_changed_callback: Optional[Callable] = None self.log = log all_sks = self.keychain.get_all_private_keys() self._private_keys = [master_sk_to_farmer_sk(sk) for sk, _ in all_sks] + [ master_sk_to_pool_sk(sk) for sk, _ in all_sks ] if len(self.get_public_keys()) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # This is the farmer configuration self.farmer_target_encoded = self.config["xch_target_address"] self.farmer_target = decode_puzzle_hash(self.farmer_target_encoded) self.pool_public_keys = [G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"]] # This is the pool configuration, which should be moved out to the pool once it exists self.pool_target_encoded = pool_config["xch_target_address"] self.pool_target = decode_puzzle_hash(self.pool_target_encoded) self.pool_sks_map: Dict = {} for key in self.get_private_keys(): self.pool_sks_map[bytes(key.get_g1())] = key assert len(self.farmer_target) == 32 assert len(self.pool_target) == 32 if len(self.pool_sks_map) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str)
async def did_recovery_spend(self, request): wallet_id = int(request["wallet_id"]) wallet: DIDWallet = self.service.wallet_state_manager.wallets[ wallet_id] if len(request["attest_filenames"] ) < wallet.did_info.num_of_backup_ids_needed: return {"success": False, "reason": "insufficient messages"} ( info_list, message_spend_bundle, ) = await wallet.load_attest_files_for_recovery_spend( request["attest_filenames"]) if "pubkey" in request: pubkey = G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])) else: assert wallet.did_info.temp_pubkey is not None pubkey = wallet.did_info.temp_pubkey if "puzhash" in request: puzhash = hexstr_to_bytes(request["puzhash"]) else: assert wallet.did_info.temp_puzhash is not None puzhash = wallet.did_info.temp_puzhash success = await wallet.recovery_spend( wallet.did_info.temp_coin, puzhash, info_list, pubkey, message_spend_bundle, ) return {"success": success}
async def get_farmer_records_for_p2_singleton_phs(self, puzzle_hashes: Set[bytes32]) -> List[FarmerRecord]: if len(puzzle_hashes) == 0: return [] puzzle_hashes_db = tuple([ph.hex() for ph in list(puzzle_hashes)]) cursor = await self.connection.execute( f'SELECT * from farmer WHERE p2_singleton_puzzle_hash in ({"?," * (len(puzzle_hashes_db) - 1)}?) ', puzzle_hashes_db, ) rows = await cursor.fetchall() records: List[FarmerRecord] = [] for row in rows: record = FarmerRecord( bytes.fromhex(row[0]), G1Element.from_bytes(bytes.fromhex(row[1])), bytes.fromhex(row[2]), row[3], bytes.fromhex(row[4]), row[5], bytes.fromhex(row[6]), row[7], row[8], bytes.fromhex(row[9]), True if row[10] == 1 else False, ) records.append(record) return records
async def test_create_new_pool_wallet_farm_to_pool(self, one_wallet_node_and_rpc, fee): client, wallet_node_0, full_node_api = one_wallet_node_and_rpc wallet_0 = wallet_node_0.wallet_state_manager.main_wallet our_ph = await wallet_0.get_new_puzzlehash() summaries_response = await client.get_wallets() for summary in summaries_response: if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET: assert False creation_tx: TransactionRecord = await client.create_new_pool_wallet( our_ph, "http://pool.example.com", 10, "localhost:5000", "new", "FARMING_TO_POOL", fee) await time_out_assert( 10, full_node_api.full_node.mempool_manager.get_spendbundle, creation_tx.spend_bundle, creation_tx.name, ) await self.farm_blocks(full_node_api, our_ph, 6) assert full_node_api.full_node.mempool_manager.get_spendbundle( creation_tx.name) is None summaries_response = await client.get_wallets() wallet_id: Optional[int] = None for summary in summaries_response: if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET: wallet_id = summary["id"] assert wallet_id is not None status: PoolWalletInfo = (await client.pw_status(wallet_id))[0] assert status.current.state == PoolSingletonState.FARMING_TO_POOL.value assert status.target is None assert status.current.owner_pubkey == G1Element.from_bytes( bytes.fromhex( "b286bbf7a10fa058d2a2a758921377ef00bb7f8143e1bd40dd195ae918dbef42cfc481140f01b9eae13b430a0c8fe304" )) assert status.current.pool_url == "http://pool.example.com" assert status.current.relative_lock_height == 10 assert status.current.version == 1 # Check that config has been written properly full_config: Dict = load_config( wallet_0.wallet_state_manager.root_path, "config.yaml") pool_list: List[Dict] = full_config["pool"]["pool_list"] assert len(pool_list) == 1 pool_config = pool_list[0] assert ( pool_config["authentication_public_key"] == "0xb3c4b513600729c6b2cf776d8786d620b6acc88f86f9d6f489fa0a0aff81d634262d5348fb7ba304db55185bb4c5c8a4" ) # It can be one of multiple launcher IDs, due to selecting a different coin assert pool_config["launcher_id"] in { "0x78a1eadf583a2f27a129d7aeba076ec6a5200e1ec8225a72c9d4180342bf91a7", "0x2bcab0310e78a7ab04e251ac6bdd5dfc80ce6895132e64f97265029db3d8309a", "0x09edf686c318c138cd3461c38e9b4e10e7f21fc476a0929b4480e126b6efcb81", } assert pool_config["pool_url"] == "http://pool.example.com"
def get_pubkey_from_innerpuz(innerpuz: Program) -> G1Element: ret = uncurry_innerpuz(innerpuz) if ret is not None: pubkey_program = ret[0] else: raise ValueError("Unable to extract pubkey") pubkey = G1Element.from_bytes(pubkey_program.as_atom()) return pubkey
def pkm_pairs_for_conditions_dict( conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]], coin_name: bytes32, additional_data: bytes) -> List[Tuple[G1Element, bytes]]: assert coin_name is not None ret: List[Tuple[G1Element, bytes]] = [] for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_UNSAFE, []): assert len(cwa.vars) == 2 assert cwa.vars[0] is not None and cwa.vars[1] is not None ret.append((G1Element.from_bytes(cwa.vars[0]), cwa.vars[1])) for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []): assert len(cwa.vars) == 2 assert cwa.vars[0] is not None and cwa.vars[1] is not None ret.append((G1Element.from_bytes(cwa.vars[0]), cwa.vars[1] + coin_name + additional_data)) return ret
def parse_plot_info(memo: bytes) -> Tuple[Union[G1Element, bytes32], G1Element, PrivateKey]: # Parses the plot info bytes into keys if len(memo) == (48 + 48 + 32): # This is a public key memo return ( G1Element.from_bytes(memo[:48]), G1Element.from_bytes(memo[48:96]), PrivateKey.from_bytes(memo[96:]), ) elif len(memo) == (32 + 48 + 32): # This is a pool_contract_puzzle_hash memo return ( bytes32(memo[:32]), G1Element.from_bytes(memo[32:80]), PrivateKey.from_bytes(memo[80:]), ) else: raise ValueError(f"Invalid number of bytes {len(memo)}")
def row_to_record(self, row) -> DerivationRecord: return DerivationRecord( uint32(row[0]), bytes32.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), WalletType(row[3]), uint32(row[4]), bool(row[6]), )
def test_schemes(): # fmt: off 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 ]) # fmt: on msg = bytes([100, 2, 254, 88, 90, 45, 23]) msg2 = bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) sk = BasicSchemeMPL.key_gen(seed) pk = sk.get_g1() assert sk == PrivateKey.from_bytes(bytes(sk)) assert pk == G1Element.from_bytes(bytes(pk)) for Scheme in (BasicSchemeMPL, AugSchemeMPL, PopSchemeMPL): sig = Scheme.sign(sk, msg) assert sig == G2Element.from_bytes(bytes(sig)) assert Scheme.verify(pk, msg, sig) seed = bytes([1]) + seed[1:] sk1 = BasicSchemeMPL.key_gen(seed) pk1 = sk1.get_g1() seed = bytes([2]) + seed[1:] sk2 = BasicSchemeMPL.key_gen(seed) pk2 = sk2.get_g1() for Scheme in (BasicSchemeMPL, AugSchemeMPL, PopSchemeMPL): # Aggregate same message agg_pk = pk1 + pk2 if Scheme is AugSchemeMPL: sig1 = Scheme.sign(sk1, msg, agg_pk) sig2 = Scheme.sign(sk2, msg, agg_pk) else: sig1 = Scheme.sign(sk1, msg) sig2 = Scheme.sign(sk2, msg) agg_sig = Scheme.aggregate([sig1, sig2]) assert Scheme.verify(agg_pk, msg, agg_sig) # Aggregate different message sig1 = Scheme.sign(sk1, msg) sig2 = Scheme.sign(sk2, msg2) agg_sig = Scheme.aggregate([sig1, sig2]) assert Scheme.aggregate_verify([pk1, pk2], [msg, msg2], agg_sig) # HD keys child = Scheme.derive_child_sk(sk1, 123) childU = Scheme.derive_child_sk_unhardened(sk1, 123) childUPk = Scheme.derive_child_pk_unhardened(pk1, 123) sig_child = Scheme.sign(child, msg) assert Scheme.verify(child.get_g1(), msg, sig_child) sigU_child = Scheme.sign(childU, msg) assert Scheme.verify(childUPk, msg, sigU_child)
def op_pubkey_for_exp(args): (i0, ) = args_as_int_list("pubkey_for_exp", args, 1) i0 %= 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 try: r = args.to(bytes(G1Element.generator() * i0)) cost = PUBKEY_BASE_COST cost += limbs_for_int(i0) // PUBKEY_COST_PER_BYTE_DIVIDER return cost, r except Exception as ex: raise EvalError("problem in op_pubkey_for_exp: %s" % ex, args)
def test_vectors_invalid(): # Invalid inputs from https://github.com/algorand/bls_sigs_ref/blob/master/python-impl/serdesZ.py invalid_inputs_1 = [ # infinity points: too short "c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # infinity points: not all zeros "c00000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000", # bad tags "3a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa", "7a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa", "fa0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa", # wrong length for compresed point "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa", "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaaaa", # invalid x-coord "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa", # invalid elm of Fp --- equal to p (must be strictly less) "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", ] invalid_inputs_2 = [ # infinity points: too short "c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # infinity points: not all zeros "c00000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000", # bad tags "3a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "7a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "fa0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # wrong length for compressed point "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # invalid x-coord "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa7", # invalid elm of Fp --- equal to p (must be strictly less) "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", ] for s in invalid_inputs_1: bytes_ = binascii.unhexlify(s) try: g1 = G1Element(bytes_) assert False, "Failed to disallow creation of G1 element." except Exception as e: pass for s in invalid_inputs_2: bytes_ = binascii.unhexlify(s) try: g2 = G2Element(bytes_) assert False, "Failed to disallow creation of G2 element." except Exception as e: pass
def aggregate_verify(pks: List[G1Element], msgs: List[bytes], sig: G2Element, force_cache: bool = False, cache: LRUCache = LOCAL_CACHE): pairings: List[GTElement] = get_pairings(cache, pks, msgs, force_cache) if len(pairings) == 0: return AugSchemeMPL.aggregate_verify(pks, msgs, sig) pairings_prod: GTElement = functools.reduce(GTElement.__mul__, pairings) return pairings_prod == sig.pair(G1Element.generator())
async def get_keys_pk(self, clawback_pubkey: bytes): """ Return keys for pubkey """ index_for_pubkey = await self.wallet_state_manager.puzzle_store.index_for_pubkey( G1Element.from_bytes(clawback_pubkey)) if index_for_pubkey is None: raise Exception("index_for_pubkey is None") private = master_sk_to_wallet_sk(self.private_key, index_for_pubkey) pubkey = private.get_g1() return pubkey, private
def test_standard_puzzle(self): coin_spend = CoinSpend( COIN, puzzle_for_pk(G1Element()), SOLUTION, ) compressed = compress_object_with_puzzles(bytes(coin_spend), LATEST_VERSION) assert len(bytes(coin_spend)) > len(compressed) assert coin_spend == CoinSpend.from_bytes( decompress_object_with_puzzles(compressed)) self.compression_factors["standard_puzzle"] = len( bytes(compressed)) / len(bytes(coin_spend))
def __init__( self, farmer_config: Dict, pool_config: Dict, keychain: Keychain, consensus_constants: ConsensusConstants, ): self.config = farmer_config self.harvester_responses_proofs: Dict[Tuple, ProofOfSpace] = {} self.harvester_responses_proof_hash_to_info: Dict[bytes32, Tuple] = {} self.header_hash_to_pos: Dict[bytes32, ProofOfSpace] = {} self.challenges: Dict[ uint128, List[farmer_protocol.ProofOfSpaceFinalized]] = {} self.challenge_to_weight: Dict[bytes32, uint128] = {} self.challenge_to_height: Dict[bytes32, uint32] = {} self.challenge_to_best_iters: Dict[bytes32, uint64] = {} self.challenge_to_estimates: Dict[bytes32, List[float]] = {} self.seen_challenges: Set[bytes32] = set() self.unfinished_challenges: Dict[uint128, List[bytes32]] = {} self.current_weight: uint128 = uint128(0) self.proof_of_time_estimate_ips: uint64 = uint64(100000) self.constants = consensus_constants self._shut_down = False self.server = None self.keychain = keychain self.state_changed_callback: Optional[Callable] = None if len(self._get_public_keys()) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # This is the farmer configuration self.wallet_target = decode_puzzle_hash( self.config["xch_target_address"]) self.pool_public_keys = [ G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"] ] # This is the pool configuration, which should be moved out to the pool once it exists self.pool_target = decode_puzzle_hash( pool_config["xch_target_address"]) self.pool_sks_map: Dict = {} for key in self._get_private_keys(): self.pool_sks_map[bytes(key.get_g1())] = key assert len(self.wallet_target) == 32 assert len(self.pool_target) == 32 if len(self.pool_sks_map) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str)
def _row_to_farmer_record(row) -> FarmerRecord: return FarmerRecord( bytes.fromhex(row[0]), bytes.fromhex(row[1]), row[2], bytes.fromhex(row[3]), G1Element.from_bytes(bytes.fromhex(row[4])), CoinSpend.from_bytes(row[5]), PoolState.from_bytes(row[6]), row[7], row[8], row[9], True if row[10] == 1 else False, )