def derivation_to_scalar(derivation, output_index): """ H_s(derivation || varint(output_index)) :param derivation: :param output_index: :return: """ check_ed25519point(derivation) buf2 = encodepoint(derivation) + xmrserialize.dump_uvarint_b(output_index) return hash_to_scalar(buf2, len(buf2))
async def set_input(self, src_entr): """ :param src_entr: :type src_entr: xmrtypes.TxSourceEntry :return: """ self.inp_idx += 1 if src_entr.real_output >= len(src_entr.outputs): raise ValueError( "real_output index %s bigger than output_keys.size()" % (src_entr.real_output, len(src_entr.outputs)) ) self.summary_inputs_money += src_entr.amount out_key = crypto.decodepoint(src_entr.outputs[src_entr.real_output][1].dest) tx_key = crypto.decodepoint(src_entr.real_out_tx_key) additional_keys = [ crypto.decodepoint(x) for x in src_entr.real_out_additional_tx_keys ] secs = monero.generate_key_image_helper( self.trezor.creds, self.subaddresses, out_key, tx_key, additional_keys, src_entr.real_output_in_tx_index, ) xi, ki, di = secs self.input_secrets.append((xi,)) self.input_rcts.append(src_entr.rct) # Construct tx.vin vini = xmrtypes.TxinToKey( amount=src_entr.amount, k_image=crypto.encodepoint(ki) ) vini.key_offsets = [x[0] for x in src_entr.outputs] vini.key_offsets = monero.absolute_output_offsets_to_relative(vini.key_offsets) self.tx.vin.append(vini) # HMAC(T_in,i || vin_i) kwriter = monero.get_keccak_writer() ar = xmrserialize.Archive(kwriter, True) await ar.message(src_entr, xmrtypes.TxSourceEntry) await ar.message(vini, xmrtypes.TxinToKey) hmac_key_vini = crypto.keccak_hash( self.key_hmac + b"txin" + xmrserialize.dump_uvarint_b(self.inp_idx) ) hmac_vini = crypto.compute_hmac(hmac_key_vini, kwriter.get_digest()) return vini, hmac_vini
def compute_hash(rr): """ Hash over output to ki-sync :param rr: :type rr: TransferDetails :return: """ kck = crypto.get_keccak() kck.update(rr.out_key) kck.update(rr.tx_pub_key) if rr.additional_tx_pub_keys: for x in rr.additional_tx_pub_keys: kck.update(x) kck.update(xmrserialize.dump_uvarint_b(rr.internal_output_index)) return kck.digest()
def _generate_clsag( message: bytes, P: List[bytes], p: Sc25519, C_nonzero: List[bytes], z: Sc25519, Cout: Ge25519, index: int, mg_buff: List[bytes], ) -> List[bytes]: sI = crypto.new_point() # sig.I sD = crypto.new_point() # sig.D sc1 = crypto.new_scalar() # sig.c1 a = crypto.random_scalar() H = crypto.new_point() D = crypto.new_point() Cout_bf = crypto.encodepoint(Cout) tmp_sc = crypto.new_scalar() tmp = crypto.new_point() tmp_bf = bytearray(32) crypto.hash_to_point_into(H, P[index]) crypto.scalarmult_into(sI, H, p) # I = p*H crypto.scalarmult_into(D, H, z) # D = z*H crypto.sc_mul_into(tmp_sc, z, crypto.sc_inv_eight()) # 1/8*z crypto.scalarmult_into(sD, H, tmp_sc) # sig.D = 1/8*z*H sD = crypto.encodepoint(sD) hsh_P = crypto.get_keccak() # domain, I, D, P, C, C_offset hsh_C = crypto.get_keccak() # domain, I, D, P, C, C_offset hsh_P.update(_HASH_KEY_CLSAG_AGG_0) hsh_C.update(_HASH_KEY_CLSAG_AGG_1) def hsh_PC(x): nonlocal hsh_P, hsh_C hsh_P.update(x) hsh_C.update(x) for x in P: hsh_PC(x) for x in C_nonzero: hsh_PC(x) hsh_PC(crypto.encodepoint_into(tmp_bf, sI)) hsh_PC(sD) hsh_PC(Cout_bf) mu_P = crypto.decodeint(hsh_P.digest()) mu_C = crypto.decodeint(hsh_C.digest()) del (hsh_PC, hsh_P, hsh_C) c_to_hash = crypto.get_keccak() # domain, P, C, C_offset, message, aG, aH c_to_hash.update(_HASH_KEY_CLSAG_ROUND) for i in range(len(P)): c_to_hash.update(P[i]) for i in range(len(P)): c_to_hash.update(C_nonzero[i]) c_to_hash.update(Cout_bf) c_to_hash.update(message) chasher = c_to_hash.copy() crypto.scalarmult_base_into(tmp, a) chasher.update(crypto.encodepoint_into(tmp_bf, tmp)) # aG crypto.scalarmult_into(tmp, H, a) chasher.update(crypto.encodepoint_into(tmp_bf, tmp)) # aH c = crypto.decodeint(chasher.digest()) del (chasher, H) L = crypto.new_point() R = crypto.new_point() c_p = crypto.new_scalar() c_c = crypto.new_scalar() i = (index + 1) % len(P) if i == 0: crypto.sc_copy(sc1, c) mg_buff.append(xmrserialize.dump_uvarint_b(len(P))) for _ in range(len(P)): mg_buff.append(bytearray(32)) while i != index: crypto.random_scalar_into(tmp_sc) crypto.encodeint_into(mg_buff[i + 1], tmp_sc) crypto.sc_mul_into(c_p, mu_P, c) crypto.sc_mul_into(c_c, mu_C, c) # L = tmp_sc * G + c_P * P[i] + c_c * C[i] crypto.add_keys2_into(L, tmp_sc, c_p, crypto.decodepoint_into(tmp, P[i])) crypto.decodepoint_into(tmp, C_nonzero[i]) # C = C_nonzero - Cout crypto.point_sub_into(tmp, tmp, Cout) crypto.scalarmult_into(tmp, tmp, c_c) crypto.point_add_into(L, L, tmp) # R = tmp_sc * HP + c_p * I + c_c * D crypto.hash_to_point_into(tmp, P[i]) crypto.add_keys3_into(R, tmp_sc, tmp, c_p, sI) crypto.point_add_into(R, R, crypto.scalarmult_into(tmp, D, c_c)) chasher = c_to_hash.copy() chasher.update(crypto.encodepoint_into(tmp_bf, L)) chasher.update(crypto.encodepoint_into(tmp_bf, R)) crypto.decodeint_into(c, chasher.digest()) P[i] = None C_nonzero[i] = None i = (i + 1) % len(P) if i == 0: crypto.sc_copy(sc1, c) # if i & 3 == 0: # gc.collect() # Final scalar = a - c * (mu_P * p + mu_c * Z) crypto.sc_mul_into(tmp_sc, mu_P, p) crypto.sc_muladd_into(tmp_sc, mu_C, z, tmp_sc) crypto.sc_mulsub_into(tmp_sc, c, tmp_sc, a) crypto.encodeint_into(mg_buff[index + 1], tmp_sc) mg_buff.append(crypto.encodeint(sc1)) mg_buff.append(sD) return mg_buff