def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]): sigs = [] solution: Program puzzle: Program for puzzle, solution in spends: # type: ignore # noqa pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash) secretkey = BLSPrivateKey(secretkey) code_ = [puzzle, solution.solution] sexp = Program.to(code_) err, con, cost = conditions_for_solution(sexp) if not con: return conditions_dict = conditions_by_opcode(con) for _ in hash_key_pairs_for_conditions_dict( conditions_dict, bytes(solution.coin)): signature = secretkey.sign(_.message_hash) sigs.append(signature) aggsig = BLSSignature.aggregate(sigs) solution_list: List[CoinSolution] = [ CoinSolution(coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])) for (puzzle, coin_solution) in spends ] spend_bundle = SpendBundle(solution_list, aggsig) return spend_bundle
async def get_sigs_for_innerpuz_with_innersol( self, innerpuz: Program, innersol: Program) -> List[BLSSignature]: puzzle_hash = innerpuz.get_tree_hash() pubkey, private = await self.wallet_state_manager.get_keys(puzzle_hash) private = BLSPrivateKey(private) sigs: List[BLSSignature] = [] code_ = [innerpuz, innersol] sexp = Program.to(code_) error, conditions, cost = conditions_dict_for_solution(sexp) if conditions is not None: for _ in hash_key_pairs_for_conditions_dict(conditions): signature = private.sign(_.message_hash) sigs.append(signature) return sigs
async def sign_transaction( self, spends: List[Tuple[Program, CoinSolution]] ) -> Optional[SpendBundle]: signatures = [] for puzzle, solution in spends: # Get keys keys = await self.wallet_state_manager.get_keys(solution.coin.puzzle_hash) if not keys: self.log.error( f"Sign transaction failed, No Keys for puzzlehash {solution.coin.puzzle_hash}" ) return None pubkey, secretkey = keys secretkey = BLSPrivateKey(secretkey) code_ = [puzzle, solution.solution] sexp = clvm.to_sexp_f(code_) # Get AGGSIG conditions err, con, cost = conditions_for_solution(sexp) if err or not con: self.log.error(f"Sign transcation failed, con:{con}, error: {err}") return None conditions_dict = conditions_by_opcode(con) # Create signature for pk_message in hash_key_pairs_for_conditions_dict( conditions_dict, bytes(solution.coin) ): signature = secretkey.sign(pk_message.message_hash) signatures.append(signature) # Aggregate signatures aggsig = BLSSignature.aggregate(signatures) solution_list: List[CoinSolution] = [ CoinSolution( coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution]) ) for (puzzle, coin_solution) in spends ] spend_bundle = SpendBundle(solution_list, aggsig) return spend_bundle
def bls_private_key_for_index(index): return BLSPrivateKey.from_bytes( bytes(HIERARCHICAL_PRIVATE_KEY.private_child(index).get_private_key()))
def add_secret_exponents(self, secret_exponents): for _ in secret_exponents: bls_private_key = BLSPrivateKey.from_secret_exponent(_) self[bls_private_key.public_key()] = bls_private_key
def sign(self, value, pubkey): privatekey = self.extended_secret_key.private_child( self.pubkey_num_lookup[pubkey]).get_private_key() blskey = BLSPrivateKey(privatekey) return blskey.sign(value)
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) ] }) puzzle = puzzle_for_pk(public_key) puzzles.append(puzzle) solutions.append(solution) private_keys.append(private_key) public_keys.append(public_key) # Run Puzzle 1000 times puzzle_start = time.time()