def generate_recovery_transaction(self, coins, root_public_key, secret_key, escrow_duration): recovery_pubkey = root_public_key.public_child( 0).get_public_key().serialize() signatures = [] coin_solutions = [] secret_key = BLSPrivateKey(secret_key) for coin in coins: pubkey = self.find_pubkey_for_escrow_puzzle( coin, root_public_key, escrow_duration) puzzle = self.get_escrow_puzzle_with_params( recovery_pubkey, pubkey.serialize(), escrow_duration) op_create_coin = ConditionOpcode.CREATE_COIN[0] puzzlehash = f'0x' + str(hexbytes(self.get_new_puzzlehash())) solution_src = sexp( quote(sexp(sexp(op_create_coin, puzzlehash, coin.amount))), sexp(), 1) solution = Program(binutils.assemble(solution_src)) puzzle_solution_list = clvm.to_sexp_f([puzzle, solution]) coin_solution = CoinSolution(coin, puzzle_solution_list) coin_solutions.append(coin_solution) conditions_dict = conditions_by_opcode( conditions_for_solution(puzzle_solution_list)) for _ in hash_key_pairs_for_conditions_dict(conditions_dict): signature = secret_key.sign(_.message_hash) signatures.append(signature) coin_solution_list = CoinSolutionList(coin_solutions) aggsig = BLSSignature.aggregate(signatures) spend_bundle = SpendBundle(coin_solution_list, aggsig) return spend_bundle
def ap_generate_signatures(self, puzhashes, oldpuzzlehash, b_pubkey_used): puzhash_signature_list = [] pubkey, secretkey = self.get_keys(oldpuzzlehash, None, b_pubkey_used) blskey = BLSPrivateKey(secretkey) signature = blskey.sign(oldpuzzlehash) puzhash_signature_list.append((oldpuzzlehash, signature)) for p in puzhashes: signature = blskey.sign(p) puzhash_signature_list.append((p, signature)) return puzhash_signature_list
def rl_sign_transaction(self, spends: (Program, [CoinSolution])): sigs = [] for puzzle, solution in spends: pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash) secretkey = BLSPrivateKey(secretkey) signature = secretkey.sign(ProgramHash(Program(solution.solution))) sigs.append(signature) aggsig = BLSSignature.aggregate(sigs) solution_list = CoinSolutionList([ 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 get_private_keys(self): return [ BLSPrivateKey( self.extended_secret_key.private_child( child).get_private_key()) for child in range(self.next_address) ]
def sign_recovery_transaction(self, spends, secret_key): sigs = [] for puzzle, solution in spends: secret_key = BLSPrivateKey(secret_key) code_ = [puzzle, solution.solution] sexp = clvm.to_sexp_f(code_) conditions_dict = conditions_by_opcode( conditions_for_solution(sexp)) for _ in hash_key_pairs_for_conditions_dict(conditions_dict): signature = secret_key.sign(_.message_hash) sigs.append(signature) aggsig = BLSSignature.aggregate(sigs) solution_list = CoinSolutionList([ 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 test_BLSSignature(): eprv_k = blspy.ExtendedPrivateKey.from_seed(b"foo") prv_k = eprv_k.get_private_key() pub_k = prv_k.get_public_key() bls_prv_k = BLSPrivateKey(prv_k) msg = b"bar" msg_hash = bls_hash(msg) sig = bls_prv_k.sign(msg_hash) print(sig) pair = sig.aggsig_pair(BLSPublicKey(pub_k.serialize()), msg_hash) ok = sig.validate([pair]) assert ok eprv_k2 = blspy.ExtendedPrivateKey.from_seed(b"foobar") prv_k2 = eprv_k2.get_private_key() pub_k2 = prv_k2.get_public_key() pair = sig.aggsig_pair(BLSPublicKey(pub_k2.serialize()), msg_hash) ok = sig.validate([pair]) assert not ok
def test_BLSSignature_aggregate(): eprv_k = blspy.ExtendedPrivateKey.from_seed(b"foo") prv_0 = eprv_k.private_child(0).get_private_key() pub_0 = prv_0.get_public_key() prv_1 = eprv_k.private_child(1).get_private_key() pub_1 = prv_1.get_public_key() bls_prv_0 = BLSPrivateKey(prv_0) msg_0 = b"bar" msg_0_hash = bls_hash(msg_0) sig_0 = bls_prv_0.sign(msg_0_hash) print(sig_0) pair_0 = sig_0.aggsig_pair(BLSPublicKey(pub_0.serialize()), msg_0_hash) ok = sig_0.validate([pair_0]) assert ok pair_0_bad = sig_0.aggsig_pair(BLSPublicKey(pub_1.serialize()), msg_0_hash) ok = sig_0.validate([pair_0_bad]) assert not ok bls_prv_1 = BLSPrivateKey(prv_1) msg_1 = b"baz" msg_1_hash = bls_hash(msg_1) sig_1 = bls_prv_1.sign(msg_1_hash) print(sig_1) pair_1 = sig_1.aggsig_pair(BLSPublicKey(pub_1.serialize()), msg_1_hash) ok = sig_1.validate([pair_1]) assert ok total_sig = sig_0.aggregate([sig_0, sig_1]) ok = total_sig.validate([pair_0, pair_1]) assert ok
def test_streaming(self): for _ in range(1, 128): p0 = bls12_381_generator * _ blob_clvm = bls12_381_to_bytes(p0) q0 = BLSPrivateKey.from_secret_exponent(_).public_key() blob_blspy = bytes(q0) assert blob_clvm.hex() == blob_blspy.hex() p1 = bls12_381_from_bytes(blob_clvm) assert p0 == p1 q1 = BLSPublicKey.from_bytes(blob_blspy) assert q0 == q1
def sign_transaction(self, spends: (Program, CoinSolution)): sigs = [] for puzzle, solution in spends: val = self.get_keys(solution.coin.puzzle_hash) if val is None: continue pubkey, secretkey = val secretkey = BLSPrivateKey(secretkey) code_ = [puzzle, solution.solution] sexp = clvm.to_sexp_f(code_) conditions_dict = conditions_by_opcode( conditions_for_solution(sexp)) for _ in hash_key_pairs_for_conditions_dict(conditions_dict): signature = secretkey.sign(_.message_hash) sigs.append(signature) aggsig = BLSSignature.aggregate(sigs) solution_list = CoinSolutionList([ 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 rl_generate_signed_aggregation_transaction(self): list_of_coinsolutions = [] if self.aggregation_coins is False: # empty sets evaluate to false in python return consolidating_coin = self.aggregation_coins.pop() pubkey, secretkey = self.get_keys(self.rl_coin.puzzle_hash) # Spend wallet coin puzzle = self.rl_puzzle_for_pk(pubkey.serialize(), self.limit, self.interval, self.rl_origin, self.rl_clawback_pk) if isinstance(self.rl_parent, Coin): solution = self.rl_make_solution_mode_2( self.rl_coin.puzzle_hash, consolidating_coin.parent_coin_info, consolidating_coin.puzzle_hash, consolidating_coin.amount, self.rl_coin.parent_coin_info, self.rl_coin.amount, self.rl_parent.amount, self.rl_parent.parent_coin_info) else: solution = self.rl_make_solution_mode_2( self.rl_coin.puzzle_hash, consolidating_coin.parent_coin_info, consolidating_coin.puzzle_hash, consolidating_coin.amount, self.rl_coin.parent_coin_info, self.rl_coin.amount, self.rl_parent["amount"], self.rl_parent["parent_coin_info"]) signature = BLSPrivateKey(secretkey).sign(ProgramHash(solution)) list_of_coinsolutions.append( CoinSolution(self.rl_coin, clvm.to_sexp_f([puzzle, solution]))) # Spend consolidating coin puzzle = self.rl_make_aggregation_puzzle(self.rl_coin.puzzle_hash) solution = self.rl_make_aggregation_solution( consolidating_coin.name(), self.rl_coin.parent_coin_info, self.rl_coin.amount) list_of_coinsolutions.append( CoinSolution(consolidating_coin, clvm.to_sexp_f([puzzle, solution]))) # Spend lock puzstring = "(r (c (q 0x" + hexlify( consolidating_coin.name()).decode('ascii') + ") (q ())))" puzzle = Program(binutils.assemble(puzstring)) solution = Program(binutils.assemble("()")) list_of_coinsolutions.append( CoinSolution(Coin(self.rl_coin, ProgramHash(puzzle), 0), clvm.to_sexp_f([puzzle, solution]))) aggsig = BLSSignature.aggregate([signature]) solution_list = CoinSolutionList(list_of_coinsolutions) return SpendBundle(solution_list, aggsig)
def ap_generate_signed_aggregation_transaction(self): list_of_coinsolutions = [] if self.aggregation_coins is False: # empty sets evaluate to false in python return consolidating_coin = self.aggregation_coins.pop() pubkey, secretkey = self.get_keys( self.temp_coin.puzzle_hash, self.a_pubkey) # Spend wallet coin puzzle = ap_make_puzzle(self.a_pubkey, pubkey.serialize()) solution = self.ap_make_solution_mode_2(self.temp_coin.puzzle_hash, consolidating_coin.parent_coin_info, consolidating_coin.puzzle_hash, consolidating_coin.amount, self.temp_coin.parent_coin_info, self.temp_coin.amount) signature = BLSPrivateKey(secretkey).sign(ProgramHash(solution)) list_of_coinsolutions.append(CoinSolution( self.temp_coin, clvm.to_sexp_f([puzzle, solution]))) # Spend consolidating coin #puzzle = Program(clvm.eval_f(clvm.eval_f, binutils.assmeble(self.puzzle_generator), binutils.assemble("(0x" + self.AP_puzzlehash + ")"))) puzzle = ap_make_aggregation_puzzle(self.temp_coin.puzzle_hash) solution = self.ac_make_aggregation_solution(consolidating_coin.name( ), self.temp_coin.parent_coin_info, self.temp_coin.amount) list_of_coinsolutions.append(CoinSolution( consolidating_coin, clvm.to_sexp_f([puzzle, solution]))) # Spend lock puzstring = f"(r (c (q 0x{hexlify(consolidating_coin.name()).decode('ascii')}) (q ())))" puzzle = Program(binutils.assemble(puzstring)) solution = Program(binutils.assemble("()")) list_of_coinsolutions.append(CoinSolution(Coin(self.temp_coin, ProgramHash( puzzle), 0), clvm.to_sexp_f([puzzle, solution]))) self.temp_coin = Coin(self.temp_coin, self.temp_coin.puzzle_hash, self.temp_coin.amount + consolidating_coin.amount) aggsig = BLSSignature.aggregate([signature]) solution_list = CoinSolutionList(list_of_coinsolutions) return SpendBundle(solution_list, aggsig)
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 make_default_keychain(): private_keys = [BLSPrivateKey(private_key_for_index(_)) for _ in range(10)] return dict((_.public_key(), _) for _ in private_keys)
def private_key(self): return BLSPrivateKey(self._bls_private_hd_key.get_private_key())
def ap_sign_output_newpuzzlehash(self, puzzlehash, newpuzzlehash, b_pubkey_used): pubkey, secretkey = self.get_keys(puzzlehash, None, b_pubkey_used) signature = BLSPrivateKey(secretkey).sign(newpuzzlehash) return signature
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)
def bls_private_key_for_index(index): return BLSPrivateKey.from_bytes( HIERARCHICAL_PRIVATE_KEY.private_child(index).get_private_key().serialize() )