def test_prove_2(self): bpi = bp.BulletProofBuilder() val = crypto.sc_init((1 << 30) - 1 + 16) mask = crypto.random_scalar() bp_res = bpi.prove(val, mask) bpi.verify(bp_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 test_prove_batch(self): self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() sv = [ crypto.sc_init(123), crypto.sc_init(768), crypto.sc_init(1231), crypto.sc_init(7681), crypto.sc_init(1232), crypto.sc_init(7682), crypto.sc_init(1232), crypto.sc_init(7682), ] gamma = [ crypto.sc_init(456), crypto.sc_init(901), crypto.sc_init(4561), crypto.sc_init(9011), crypto.sc_init(4562), crypto.sc_init(9012), crypto.sc_init(4562), crypto.sc_init(9012), ] proof = bpi.prove_batch(sv, gamma) bpi.verify_batch([proof])
def test_prove(self): bpi = bp.BulletProofBuilder() val = crypto.sc_init(123) mask = crypto.sc_init(432) bp_res = bpi.prove(val, mask) self.assertTrue(bpi.verify(bp_res))
def test_masks(self): bpi = bp.BulletProofBuilder() self.mask_consistency_check(bpi) # Randomized masks bpi.use_det_masks = False self.mask_consistency_check(bpi)
def test_prove_random_masks(self): bpi = bp.BulletProofBuilder() bpi.use_det_masks = False # trully randomly generated mask vectors val = crypto.sc_init((1 << 30) - 1 + 16) mask = crypto.random_scalar() bp_res = bpi.prove(val, mask) bpi.verify(bp_res)
def test_prove_testnet_2(self): self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() val = crypto.sc_init((1 << 30) - 1 + 16) mask = crypto.random_scalar() bp_res = bpi.prove_testnet(val, mask) bpi.verify_testnet(bp_res)
async def prove_range_bp_batch(amounts, masks): from monero_glue.xmr import bulletproof as bp bpi = bp.BulletProofBuilder() bp_proof = bpi.prove_batch([crypto.sc_init(a) for a in amounts], masks) del (bpi, bp) gc.collect() return bp_proof
def test_constants(self): """ Bulletproof constants testing :return: """ self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() Gi, Hi = bp.init_exponents() res = bp.init_constants()
def test_verify_batch_1(self): bpi = bp.BulletProofBuilder() bpi.verify_batch([self.bproof_1()]) bpi.verify_batch([self.bproof_2()]) bpi.verify_batch([self.bproof_4()]) bpi.verify_batch([self.bproof_8()]) bpi.verify_batch([self.bproof_16()]) with self.assertRaises(Exception): bpi.verify_batch([self.bproof_2_invalid()]) with self.assertRaises(Exception): bpi.verify_batch([self.bproof_2_invalid()])
async def run_mpc_booltest(self, m=4): runner = bpcl.BulletproofMPCRunner() async def step_messenger(p1=0, p2=0, params=None, buffers=None): return await runner.step(p1, p2, params, buffers) cl = bpcl.BulletproofClient(m, messenger=step_messenger) proof = await cl.compute_bp() bpi = bp.BulletProofBuilder() bpi.verify_batch([proof]) logger.info('M: %s, Nmsgs %s, Sent %s, Recv %s, time %.2f' % (m, cl.n_msgs, cl.n_sent, cl.n_recv, cl.prove_time))
def test_prove_testnet(self): self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() val = crypto.sc_init(123) mask = crypto.sc_init(432) bp_res = bpi.prove_testnet(val, mask) bpi.verify_testnet(bp_res) try: bp_res.S[0] += 1 bpi.verify(bp_res) self.fail("Verification should have failed") except: pass
async def verify_bp(bp_proof, amounts=None, masks=None): from monero_glue.xmr import bulletproof as bp if amounts: bp_proof.V = [] for i in range(len(amounts)): C = crypto.gen_c(masks[i], amounts[i]) crypto.scalarmult_into(C, C, crypto.sc_inv_eight()) bp_proof.V.append(crypto.encodepoint(C)) bpi = bp.BulletProofBuilder() res = bpi.verify(bp_proof) gc.collect() # Return as struct as the hash(BP_struct) != hash(BP_serialized) # as the original hashing does not take vector lengths into account which are dynamic # in the serialization scheme (and thus extraneous) return res
async def test_bp_off(self): if not self.do_bp_off: self.skipTest("BP offloading not tested") ln = int(os.getenv('BP_M', '16')) async def diagMessenger(p1=0, p2=0, params=None, buffers=None): msg = DebugMoneroDiagRequest(ins=7, p1=p1, p2=p2, pd=params, data3=buffers) return (await self.trezor_proxy.call(msg)).data3 cl = bpcl.BulletproofClient(ln, messenger=diagMessenger) proof = await cl.compute_bp() bpi = bp.BulletProofBuilder() bpi.verify_batch([proof]) logger.info('M: %s, Nmsgs %s, Sent %s, Recv %s, time %.2f' % (ln, cl.n_msgs, cl.n_sent, cl.n_recv, cl.prove_time))
def test_verify(self): self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() # fmt: off bp_proof = Bulletproof( V=[ unhexlify( b"3c705e1da4bbe43a0535a5ad3a8e6c148fb8c1a4118ba6b65412b2fe6511b261" ), ], A=unhexlify( b"fd0336a21efd088edc4634153f6795ff18707815d32d6e07abfd52dbceaf65b5" ), S=unhexlify( b"3716a1ece9ad971ab9339aae011c343e4aadeee8b7316c928deb4a1678b4d540" ), T1=unhexlify( b"744a9ec79e7dcd263fc2e4e828b885ae3286e4dcca0fc43d1ad0f82bb5e84097" ), T2=unhexlify( b"5d61e98dce355faaa7498e3b3453e4a25c40a002596dfe8066b804963fb70de3" ), taux=unhexlify( b"2cc0207a5d8c0ce4f56fe381f451a44d6f1123516b3ee34c84c5bd73681e950b" ), mu=unhexlify( b"35554b56e85392ba9ef955019cdd0336b44e361f50eba6c8aa1b8e520ee32a03" ), L=[ unhexlify( b"511e4e6c210dff90ce6dd9b42f99922d052a6d3a233ee1dcd247355fc2d1c6f3" ), unhexlify( b"a1d4a8f563f5beb5301df7f9b77cac6cb1750f41e32a87c448035476fabd95fb" ), unhexlify( b"f35d024182a47b2f1c6fd63a81e261de4a4c6304c08081c8f6be7ea376403de6" ), unhexlify( b"55f3c43c4e4b739b0c5b778594d89a0b8898dadcc344d33f0b9ebb17c6902c56" ), unhexlify( b"f284735fb774f653686cba437ed79e3a220491ba63b87154b02fb50531b22793" ), unhexlify( b"01aa0cb066bc7e4fd8da3a0a822c0bc40f6568b9ff7c3c22c2bbd506444ae079" ), ], R=[ unhexlify( b"8e202216359b2883edc516546d03aa6308b3403fcf78e771508aa17fb15dafd9" ), unhexlify( b"0dc6d53f7651cd1efdc434af1ab732ef96ff2a2df00ba41fe746edd1261e7303" ), unhexlify( b"0bf935f41ef1a97f8f75321f164a1951b3a6e12a4099a6751d6158abccb3b613" ), unhexlify( b"45f3ef0dae0bdac2f19142bffc57db12cf9dd2a6038d317467491788ff53ba88" ), unhexlify( b"bbfcf74131f8cb51db3ff1d25f01a8b27cbc8ad2b5a22ea53f196e82f68aef37" ), unhexlify( b"ca5a73f4770c0fd6bcce7d13f61bea6d0947840dd13c832544d37f75c875d0ae" ), ], a=unhexlify( b"f77e9ce6aa4e2ee83b437d18c1683ec50cdfe43d0d05af2094cbb5a5e79c5f09" ), b=unhexlify( b"1ab637c922e87d9690f9b6d754d501277ca14935f69197cbf64b7f83f5a07e01" ), t=unhexlify( b"9e7e8ca9e482d8ab601139fa862649328c00aac2e567aefdefc1c41b505cf202" )) # fmt: on self.assertTrue(bpi.verify(bp_proof)) with self.assertRaises(ValueError): bp_proof.S = bp_proof.A self.assertTrue(bpi.verify(bp_proof))
def test_verify_testnet(self): self.skip_if_cannot_test() bpi = bp.BulletProofBuilder() # fmt: off bp_proof = Bulletproof( V=[ bytes([ 0x67, 0x54, 0xbf, 0x40, 0xcb, 0x45, 0x63, 0x0d, 0x4b, 0xea, 0x08, 0x9e, 0xd7, 0x86, 0xec, 0x3c, 0xe5, 0xbd, 0x4e, 0xed, 0x8f, 0xf3, 0x25, 0x76, 0xae, 0xca, 0xb8, 0x9e, 0xf2, 0x5e, 0x41, 0x16 ]) ], A=bytes([ 0x96, 0x10, 0x17, 0x66, 0x87, 0x7e, 0xef, 0x97, 0xb3, 0x82, 0xfb, 0x8e, 0x0c, 0x2a, 0x93, 0x68, 0x9e, 0x05, 0x22, 0x07, 0xe3, 0x30, 0x94, 0x20, 0x58, 0x6f, 0x5d, 0x01, 0x6d, 0x4e, 0xd5, 0x88 ]), S=bytes([ 0x50, 0x51, 0x38, 0x32, 0x96, 0x20, 0x7c, 0xc9, 0x60, 0x4d, 0xac, 0x7c, 0x7c, 0x21, 0xf9, 0xad, 0x1c, 0xc2, 0x2d, 0xee, 0x88, 0x7b, 0xa2, 0xe2, 0x61, 0x81, 0x46, 0xf5, 0x99, 0xc3, 0x12, 0x57 ]), T1=bytes([ 0x1a, 0x7d, 0x06, 0x51, 0x41, 0xe6, 0x12, 0xbe, 0xad, 0xd7, 0x68, 0x60, 0x85, 0xfc, 0xc4, 0x86, 0x0b, 0x39, 0x4b, 0x06, 0xf7, 0xca, 0xb3, 0x29, 0xdf, 0x1d, 0xbf, 0x96, 0x5f, 0xbe, 0x8c, 0x87 ]), T2=bytes([ 0x57, 0xae, 0x91, 0x04, 0xfa, 0xac, 0xf3, 0x73, 0x75, 0xf2, 0x83, 0xd6, 0x9a, 0xcb, 0xef, 0xe4, 0xfc, 0xe5, 0x37, 0x55, 0x52, 0x09, 0xb5, 0x60, 0x6d, 0xab, 0x46, 0x85, 0x01, 0x23, 0x9e, 0x47 ]), taux=bytes([ 0x44, 0x7a, 0x87, 0xd9, 0x5f, 0x1b, 0x17, 0xed, 0x53, 0x7f, 0xc1, 0x4f, 0x91, 0x9b, 0xca, 0x68, 0xce, 0x20, 0x43, 0xc0, 0x88, 0xf1, 0xdf, 0x12, 0x7b, 0xd7, 0x7f, 0xe0, 0x27, 0xef, 0xef, 0x0d ]), mu=bytes([ 0x32, 0xf9, 0xe4, 0xe1, 0xc2, 0xd8, 0xe4, 0xb0, 0x0d, 0x49, 0xd1, 0x02, 0xbc, 0xcc, 0xf7, 0xa2, 0x5a, 0xc7, 0x28, 0xf3, 0x05, 0xb5, 0x64, 0x2e, 0xde, 0xcf, 0x01, 0x61, 0xb8, 0x62, 0xfb, 0x0d ]), L=[ bytes([ 0xde, 0x71, 0xca, 0x09, 0xf9, 0xd9, 0x1f, 0xa2, 0xae, 0xdf, 0x39, 0x49, 0x04, 0xaa, 0x6b, 0x58, 0x67, 0x9d, 0x61, 0xa6, 0xfa, 0xec, 0x81, 0xf6, 0x4c, 0x15, 0x09, 0x9d, 0x10, 0x21, 0xff, 0x39 ]), bytes([ 0x90, 0x47, 0xbf, 0xf0, 0x1f, 0x72, 0x47, 0x4e, 0xd5, 0x58, 0xfb, 0xc1, 0x16, 0x43, 0xb7, 0xd8, 0xb1, 0x00, 0xa4, 0xa3, 0x19, 0x9b, 0xda, 0x5b, 0x27, 0xd3, 0x6c, 0x5a, 0x87, 0xf8, 0xf0, 0x28 ]), bytes([ 0x03, 0x45, 0xef, 0x57, 0x19, 0x8b, 0xc7, 0x38, 0xb7, 0xcb, 0x9c, 0xe7, 0xe8, 0x23, 0x27, 0xbb, 0xd3, 0x54, 0xcb, 0x38, 0x3c, 0x24, 0x8a, 0x60, 0x11, 0x20, 0x92, 0x99, 0xec, 0x35, 0x71, 0x9f ]), bytes([ 0x7a, 0xb6, 0x36, 0x42, 0x36, 0x83, 0xf3, 0xa6, 0xc1, 0x24, 0xc5, 0x63, 0xb0, 0x4c, 0x8b, 0xef, 0x7c, 0x77, 0x25, 0x83, 0xa8, 0xbb, 0x8b, 0x57, 0x75, 0x1c, 0xb6, 0xd7, 0xca, 0xc9, 0x0d, 0x78 ]), bytes([ 0x9d, 0x79, 0x66, 0x21, 0x64, 0x72, 0x97, 0x08, 0xa0, 0x5a, 0x94, 0x5a, 0x94, 0x7b, 0x11, 0xeb, 0x4e, 0xe9, 0x43, 0x2f, 0x08, 0xa2, 0x57, 0xa5, 0xd5, 0x99, 0xb0, 0xa7, 0xde, 0x78, 0x80, 0xb7 ]), bytes([ 0x9f, 0x88, 0x5c, 0xa5, 0xeb, 0x08, 0xef, 0x1a, 0xcf, 0xbb, 0x1d, 0x04, 0xc5, 0x47, 0x24, 0x37, 0x49, 0xe4, 0x4e, 0x9c, 0x5d, 0x56, 0xd0, 0x97, 0xfd, 0x8a, 0xe3, 0x23, 0x1d, 0xab, 0x16, 0x03 ]), ], R=[ bytes([ 0xae, 0x89, 0xeb, 0xa8, 0x5b, 0xd5, 0x65, 0xd6, 0x9f, 0x2a, 0xfd, 0x04, 0x66, 0xad, 0xb1, 0xf3, 0x5e, 0xf6, 0x60, 0xa7, 0x26, 0x94, 0x3b, 0x72, 0x5a, 0x5c, 0x80, 0xfa, 0x0f, 0x75, 0x48, 0x27 ]), bytes([ 0xc9, 0x1a, 0x61, 0x70, 0x6d, 0xea, 0xea, 0xb2, 0x42, 0xff, 0x27, 0x3b, 0x8e, 0x94, 0x07, 0x75, 0x40, 0x7d, 0x33, 0xde, 0xfc, 0xbd, 0x53, 0xa0, 0x2a, 0xf9, 0x0c, 0x36, 0xb0, 0xdd, 0xbe, 0x8d ]), bytes([ 0xb7, 0x39, 0x7a, 0x0e, 0xa1, 0x42, 0x0f, 0x94, 0x62, 0x24, 0xcf, 0x54, 0x75, 0xe3, 0x0b, 0x0f, 0xfb, 0xcb, 0x67, 0x7b, 0xbc, 0x98, 0x36, 0x01, 0x9f, 0x73, 0xa0, 0x70, 0xa1, 0x7e, 0xf0, 0xcf ]), bytes([ 0x40, 0x06, 0xd4, 0xfa, 0x22, 0x7c, 0x82, 0xbf, 0xe8, 0xe0, 0x35, 0x13, 0x28, 0xa2, 0xb9, 0x51, 0xa3, 0x37, 0x34, 0xc0, 0xa6, 0x43, 0xd6, 0xb7, 0x7a, 0x40, 0xae, 0xf9, 0x36, 0x0e, 0xe3, 0xcc ]), bytes([ 0x88, 0x38, 0x64, 0xe9, 0x63, 0xe3, 0x33, 0xd9, 0xf6, 0xca, 0x47, 0xc4, 0xc7, 0x36, 0x70, 0x01, 0xd2, 0xe4, 0x8c, 0x9f, 0x25, 0xc2, 0xce, 0xcf, 0x81, 0x89, 0x4f, 0x24, 0xcb, 0xb8, 0x40, 0x73 ]), bytes([ 0xdc, 0x35, 0x65, 0xed, 0x6b, 0xb0, 0xa7, 0x1a, 0x1b, 0xf3, 0xd6, 0xfb, 0x47, 0x00, 0x48, 0x00, 0x20, 0x6d, 0xd4, 0xeb, 0xff, 0xb9, 0xdc, 0x43, 0x30, 0x8a, 0x90, 0xfe, 0x43, 0x74, 0x75, 0x68 ]), ], a=bytes([ 0xb4, 0x8e, 0xc2, 0x31, 0xce, 0x05, 0x9a, 0x7a, 0xbc, 0x82, 0x8c, 0x30, 0xb3, 0xe3, 0x80, 0x86, 0x05, 0xb8, 0x4c, 0x93, 0x9a, 0x8e, 0xce, 0x39, 0x0f, 0xb6, 0xee, 0x28, 0xf6, 0x7e, 0xd5, 0x07 ]), b=bytes([ 0x47, 0x10, 0x62, 0xc2, 0xad, 0xc7, 0xe2, 0xc9, 0x14, 0x6f, 0xf4, 0xd1, 0xfe, 0x52, 0xa9, 0x1a, 0xe4, 0xb6, 0xd0, 0x25, 0x4b, 0x19, 0x80, 0x7c, 0xcd, 0x62, 0x62, 0x1d, 0x97, 0x20, 0x71, 0x0b ]), t=bytes([ 0x47, 0x06, 0xea, 0x76, 0x8f, 0xdb, 0xa3, 0x15, 0xe0, 0x2c, 0x6b, 0x25, 0xa1, 0xf7, 0x3c, 0xc8, 0x1d, 0x97, 0xa6, 0x52, 0x48, 0x75, 0x37, 0xf9, 0x1e, 0x14, 0xac, 0xb1, 0x2a, 0x34, 0xc6, 0x06 ])) # fmt: on self.assertTrue(bpi.verify_testnet(bp_proof))
def test_prove_batch16(self): bpi = bp.BulletProofBuilder() sv = [crypto.sc_init(137 * i) for i in range(16)] gamma = [crypto.sc_init(991 * i) for i in range(16)] proof = bpi.prove_batch(sv, gamma) bpi.verify_batch([proof])
def test_prove_batch(self): bpi = bp.BulletProofBuilder() sv = [crypto.sc_init(123), crypto.sc_init(768)] gamma = [crypto.sc_init(456), crypto.sc_init(901)] proof = bpi.prove_batch(sv, gamma) bpi.verify_batch([proof])
async def compute_bp(self): ln = self.M self.MN = 64 * ln bpi = bp.BulletProofBuilder() l = bytearray() r = bytearray() aprime = l bprime = r logger.debug('Batching: %s, MN: %s, chunks: %s, M: %s' % (self.batching, self.MN, self.MN // self.batching, ln)) ttstart = time.time() l0, r0 = dechunk_res( await self.bp_start(ln, self.off_method, self.nprime_thresh, self.off2_thresh, self.batching), 2) l += l0 r += r0 for i in range(1, self.MN // self.batching): logger.debug('.. l, r: %s' % i) l0, r0 = dechunk_res(await self.bp_tx_buffers(None), 2) l += l0 r += r0 logger.debug('l, r finished') rrcons = await self.bp_tx_buffers(None) logger.debug('Phase 1 finishing: %s' % rrcons) logger.debug('Phase 1 finished') y = rrcons[0] if rrcons and len(rrcons) > 0 else None # First while-loop iteration, dot-product computation, lC, lR, Lc, Lr, w, winv if self.off_method == 0: # round 0 - aLow, bHigh logger.debug('r0, cLcR aLow') for i in range(self.MN // self.batching // 2): ia0, ia1, ib0, ib1 = comp_fold_idx(self.batching, self.MN // 2, i) logger.debug(' .. i: %s, %s:%s, %s:%s' % (i, ia0, ia1, ib0, ib1)) rrcons = await self.bp_tx_buffers((l[ia0:ia1], r[ib0:ib1])) logger.debug(rrcons) # round 0 - aHigh, bLow logger.debug('r0, cLcR aHigh') for i in range(self.MN // self.batching // 2): ib0, ib1, ia0, ia1 = comp_fold_idx(self.batching, self.MN // 2, i) logger.debug(' .. i: %s, %s:%s, %s:%s' % (i, ia0, ia1, ib0, ib1)) rrcons = await self.bp_tx_buffers((l[ia0:ia1], r[ib0:ib1])) logger.debug(rrcons) else: # round 0 - aLow, bHigh; aHigh, bLow in memory logger.debug('r0, cLcR off, nprime: %s' % str(self.MN // 2)) yinvpow = vect_clone(None, bp.KeyVPowers(self.MN, bp.invert(None, y))) Gprec = vect_clone(None, bpi._gprec_aux(self.MN)) Hprec = vect_clone(None, bpi._hprec_aux(self.MN)) Hprime = vect_clone( None, bp.KeyVEval( self.MN, lambda i, d: bp.scalarmult_key(d, Hprec[i], yinvpow[i]))) cL, cR, LcA, LcB, RcA, RcB = comp_offdots(Gprec, Hprime, bp.KeyV(self.MN, l), bp.KeyV(self.MN, r), self.MN // 2) rrcons = await self.bp_tx_buffers((cL, cR, LcA, LcB, RcA, RcB)) logger.debug(rrcons) # round 0 folding, G, H, a, b Gprime = bytearray() Hprime = bytearray() app = bytearray() bpp = bytearray() cbatch = max(1, self.MN // 2 // self.batching // 2) logger.debug('r0, fold G') for i in range(cbatch): cres = dechunk_res(await self.bp_tx_buffers(None)) if cres: Gprime += cres logger.debug('r0, fold H') for i in range(cbatch): cres = dechunk_res(await self.bp_tx_buffers(None)) if cres: Hprime += cres Gprime = bp.KeyV(self.MN // 2, Gprime) Hprime = bp.KeyV(self.MN // 2, Hprime) if self.off_method == 3: logger.debug('r0 in-mem meth3 fold Gprime') Gprec = vect_clone(None, bpi._gprec_aux(self.MN)) comp_folding(rrcons, self.MN // 2, Gprec, 0) logger.debug('r0 in-mem meth3 fold Hprime') Hprec_ = vect_clone(None, bpi._hprec_aux(self.MN)) ypowinv = vect_clone( None, bp.KeyVPowers(self.MN, bp.invert(_tmp_bf_0, y))) Hprec = vect_clone( None, bp.KeyVEval( self.MN, lambda i, d: bp.scalarmult_key( d, Hprec_.to(i), yinvpow[i]))) comp_folding(rrcons, self.MN // 2, Hprec, 1) logger.debug('r0 in-mem meth3 correct G, H') for i in range(self.MN // 2): crypto.decodepoint_into(_tmp_pt_1, Gprec.to(i)) crypto.decodepoint_into(_tmp_pt_2, Gprime.to(i)) crypto.point_sub_into(_tmp_pt_1, _tmp_pt_1, _tmp_pt_2) crypto.encodepoint_into(_tmp_bf_0, _tmp_pt_1) Gprime.read(i, _tmp_bf_0) crypto.decodepoint_into(_tmp_pt_1, Hprec.to(i)) crypto.decodepoint_into(_tmp_pt_2, Hprime.to(i)) crypto.point_sub_into(_tmp_pt_1, _tmp_pt_1, _tmp_pt_2) crypto.encodepoint_into(_tmp_bf_0, _tmp_pt_1) Hprime.read(i, _tmp_bf_0) if self.off_method >= 2: logger.debug('in-mem fold for a, b') aprime = bp.KeyV(self.MN, l) bprime = bp.KeyV(self.MN, r) comp_folding(rrcons, self.MN // 2, aprime, 2) comp_folding(rrcons, self.MN // 2, bprime, 3) else: logger.debug('r0, fold a') for i in range(self.MN // self.batching // 2): ia0, ia1, ib0, ib1 = comp_fold_idx(self.batching, self.MN // 2, i) cres = dechunk_res(await self.bp_tx_buffers( (aprime[ia0:ia1], aprime[ib0:ib1]))) if cres: app += cres logger.debug('r0, fold b') for i in range(self.MN // self.batching // 2): ia0, ia1, ib0, ib1 = comp_fold_idx(self.batching, self.MN // 2, i) cres = dechunk_res(await self.bp_tx_buffers( (bprime[ia0:ia1], bprime[ib0:ib1]))) if cres: bpp += cres aprime = bp.KeyV(self.MN // 2, app) bprime = bp.KeyV(self.MN // 2, bpp) logger.debug('0PC r: %s, ap %s %s' % (0, len(aprime), ubinascii.hexlify(aprime.d[-64:]))) logger.debug('0PC r: %s, bp %s %s' % (0, len(bprime), ubinascii.hexlify(bprime.d[-64:]))) logger.debug('0PC r: %s, Gp %s %s' % (0, len(Gprime), ubinascii.hexlify(Gprime.d[-64:]))) logger.debug('0PC r: %s, Hp %s %s' % (0, len(Hprime), ubinascii.hexlify(Hprime.d[-64:]))) # Loops: # - clcr part, compute blinded cL, cR, LcA, LcB, RcA, RcB nprime = self.MN // 4 round = 0 while round == 0 or nprime >= self.nprime_thresh or ( self.off_method >= 2 and nprime >= self.off2_thresh): npr2 = nprime * 2 round += 1 logger.debug( 'Client, BPI nprime: %s, CLI nprime: %s, |Gprime|: %s' % (nprime, nprime, len(Gprime))) if self.off_method == 0: # round 0 - aLow, bHigh logger.debug('r%s, cLcR aLow' % round) for i in range(nprime // self.batching): ia0, ia1, ib0, ib1 = comp_fold_idx(self.batching, nprime, i) logger.debug(' .. i: %s, %s:%s, %s:%s' % (i, ia0, ia1, ib0, ib1)) rrcons = await self.bp_tx_buffers( (aprime.d[ia0:ia1], bprime.d[ib0:ib1], Gprime.d[ib0:ib1], Hprime.d[ia0:ia1])) logger.debug(rrcons) # round 0 - aHigh, bLow logger.debug('r%s, cLcR aHigh' % round) for i in range(nprime // self.batching): ib0, ib1, ia0, ia1 = comp_fold_idx(self.batching, nprime, i) logger.debug(' .. i: %s, %s:%s, %s:%s' % (i, ia0, ia1, ib0, ib1)) rrcons = await self.bp_tx_buffers( (aprime.d[ia0:ia1], bprime.d[ib0:ib1], Gprime.d[ib0:ib1], Hprime.d[ia0:ia1])) logger.debug(rrcons) else: # Computing dot products in-memory, blinded cL, cR, LcA, LcB, RcA, RcB = comp_offdots( Gprime, Hprime, aprime, bprime, nprime) logger.debug('clcr step, r %s' % round) rrcons = await self.bp_tx_buffers((cL, cR, LcA, LcB, RcA, RcB)) logger.debug(rrcons) for ix, v in enumerate((Gprime, Hprime, aprime, bprime)): logger.debug('Folding IX: %s, r %s' % (ix, round)) # Offloaded folding up to batching limit / limit defined by Trezor # Can be e.g. 8 elements. Remaining 8 computed in memory in the Trezor if self.off_method >= 2 and rrcons: logger.debug('.. PC: in-memory fold, len: %s; %s' % (len(v), nprime)) comp_folding(rrcons, nprime, v, ix) if ix == 3: nprime >>= 1 continue # Ordinary folding for methods [0, 1] bf = v.d nf = bytearray() cbatching = min(self.batching, nprime) for i in range(max(1, nprime // cbatching)): ia0, ia1, ib0, ib1 = comp_fold_idx(self.batching, nprime, i) logger.debug(' .. i: %s, %s:%s, %s:%s' % (i, ia0, ia1, ib0, ib1)) lo = bf[ia0:ia1] hi = bf[ib0:ib1] cres = dechunk_res(await self.bp_tx_buffers((lo, hi))) if cres: nf += cres nf = bp.KeyV(nprime // 2, nf) if ix == 0: Gprime = nf elif ix == 1: Hprime = nf elif ix == 2: aprime = nf elif ix == 3: bprime = nf nprime >>= 1 logger.debug( 'wPC r: %s, ap %s %s' % (round, len(aprime), ubinascii.hexlify(aprime.d[-64:]))) logger.debug( 'wPC r: %s, bp %s %s' % (round, len(bprime), ubinascii.hexlify(bprime.d[-64:]))) logger.debug( 'wPC r: %s, Gp %s %s' % (round, len(Gprime), ubinascii.hexlify(Gprime.d[-64:]))) logger.debug( 'wPC r: %s, Hp %s %s' % (round, len(Hprime), ubinascii.hexlify(Hprime.d[-64:]))) proof = await self.bp_final() proof = await tmisc.parse_msg(proof[0], BulletproofFull()) self.prove_time = time.time() - ttstart return proof
async def step(self, p1=0, p2=2, params=None, buffers=None): if p1 == 0: self.bpp(None) # clear old state self.check_mem("+++BP START: %s; %s" % (p1, p2)) # gc.collect() self.log_trace("BP START") # Crypto function call number reporting not implemented here # It is in git: ph4r05/trezor-firmware/pr/bpoff-counting-exp bpi, res = None, None if p1 == 0: # crypto.report_reset() bp.set_prng(crypto.prng(bp.ZERO)) bpi = bp.BulletProofBuilder() # bpi.gc_fnc = gc.collect bpi.gc_trace = self.log_trace sv = [crypto.sc_init(137 * i) for i in range(p2)] gamma = [crypto.sc_init(991 * i) for i in range(p2)] bpi.off_method = 2 if not params and len( params) <= 1 else params[0] if params and len(params) >= 4: bpi.nprime_thresh = params[1] bpi.off2_thresh = params[2] bpi.batching = params[3] res = bpi.prove_batch_off(sv, gamma, buffers) # crypto.report() state = bpi.dump_state() # del (bp, bpi) # gc.collect() self.log_trace("BP STATE") self.bpp((state, None)) # self.bpp((state, crypto.report_get())) # del (crypto) # gc.collect() self.log_trace("BP STATE2") else: # crypto.report_reset() state, fncs = self.bpp() bpi = bp.BulletProofBuilder() bpi.load_state(state) del (state) self.bpp(None) # gc.collect() self.log_trace("From state") # bp.PRNG = crypto.prng(bp._ZERO) # bpi.gc_fnc = gc.collect bpi.gc_trace = self.log_trace # crypto.report_reset() # crypto.report_set(fncs) res = bpi.prove_batch_off_step(buffers) # crypto.report() state = bpi.dump_state() del bpi # del (bp, bpi) # gc.collect() self.log_trace("BP STATE") self.bpp((state, fncs)) # del (crypto) # gc.collect() self.log_trace("BP STATE2") # gc.collect() self.log_trace("BP STEP") self.check_mem("+++BP STEP") if isinstance(res, tuple) and res[0] == 1: from monero_glue.hwtoken import misc as tmisc B = res[1] B2 = BulletproofFull() B2.V = B.V B2.S = B.S B2.A = B.A B2.T1 = B.T1 B2.T2 = B.T2 B2.taux = B.taux B2.mu = B.mu B2.L = B.L B2.R = B.R B2.a = B.a B2.b = B.b B2.t = B.t res = await tmisc.dump_msg(B2) msg = None if res: msg = res if isinstance(res, (list, tuple)) else [res] return msg
def test_verify(self): bpi = bp.BulletProofBuilder() self.assertTrue(bpi.verify(self.bproof_1())) self.assertTrue(bpi.verify(self.bproof_2())) self.assertTrue(bpi.verify(self.bproof_4()))