def prove_range( amount, last_mask=None, use_asnl=False, mem_opt=True, backend_impl=False, decode=False, byte_enc=False, rsig=None, ): """ Range proof generator. In order to minimize the memory consumption and CPU usage during transaction generation the returned values are returned encoded. :param amount: :param last_mask: :param use_asnl: ASNL range proof, insecure :param mem_opt: memory optimized :param backend_impl: backend implementation, if available :param decode: decodes output :param byte_enc: decodes output :param rsig: buffer for rsig :return: """ if use_asnl and mem_opt: raise ValueError("ASNL not in memory optimized variant") if backend_impl and use_asnl: raise ValueError("ASNL not supported in backend") if backend_impl and crypto.get_backend().has_rangeproof_borromean(): if byte_enc and decode: raise ValueError("Conflicting options byte_enc, decode") C, a, R = crypto.prove_range(amount, last_mask)[:3] # backend returns encoded if not byte_enc: R = monero.inflate_rsig(R) if decode: R = monero.inflate_rsig(R) R = monero.recode_rangesig(R, encode=False) return C, a, R ret = None if use_asnl and not mem_opt: ret = prove_range_orig(amount, last_mask=last_mask, use_asnl=True) else: ret = prove_range_mem(amount, last_mask=last_mask) # Encoding C, a, R = ret[:3] if byte_enc: R = monero.recode_rangesig(R, encode=True) R = monero.flatten_rsig(R) elif not decode: R = monero.recode_rangesig(R, encode=True) return C, a, R
def test_range_proof3(self): proof = ring_ct.prove_range(123456789) rsig = proof[2] monero.recode_rangesig(rsig, encode=False) monero.recode_rangesig(rsig, encode=True) res = ring_ct.ver_range(proof[0], rsig) self.assertTrue(res)
def ver_range(C=None, rsig=None, use_bulletproof=False, decode=True): """ Verifies that \sum Ci = C and that each Ci is a commitment to 0 or 2^i :param C: :param rsig: :param use_bulletproof: bulletproof :param decode: decodes encoded range proof :return: """ n = ATOMS CiH = [None] * n C_tmp = crypto.identity() c_H = crypto.xmr_H() if decode and not use_bulletproof: rsig = monero.recode_rangesig(rsig, encode=False, copy=True) if not use_bulletproof: for i in range(0, n): CiH[i] = crypto.point_sub(rsig.Ci[i], c_H) C_tmp = crypto.point_add(C_tmp, rsig.Ci[i]) c_H = crypto.point_double(c_H) if C is not None and not crypto.point_eq(C_tmp, C): return 0 if use_bulletproof: bp = bulletproof.BulletProofBuilder() return bp.verify(rsig) return mlsag2.ver_borromean(rsig.Ci, CiH, rsig.asig.s0, rsig.asig.s1, rsig.asig.ee)
def ver_range(C=None, rsig=None, use_asnl=False, decode=True): """ Verifies that \sum Ci = C and that each Ci is a commitment to 0 or 2^i :param C: :param rsig: :param use_asnl: use ASNL, used before Borromean, insecure! :param decode: decodes encoded range proof :return: """ n = ATOMS CiH = [None] * n C_tmp = crypto.identity() c_H = crypto.gen_H() if decode: rsig = monero.recode_rangesig(rsig, encode=False, copy=True) for i in range(0, n): CiH[i] = crypto.point_sub(rsig.Ci[i], c_H) C_tmp = crypto.point_add(C_tmp, rsig.Ci[i]) c_H = crypto.point_double(c_H) if C is not None and not crypto.point_eq(C_tmp, C): return 0 if use_asnl: return asnl.ver_asnl(rsig.Ci, CiH, rsig.asig.s0, rsig.asig.s1, rsig.asig.ee) else: return mlsag2.ver_borromean(rsig.Ci, CiH, rsig.asig.s0, rsig.asig.s1, rsig.asig.ee)