Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
 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])
Ejemplo n.º 4
0
    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))
Ejemplo n.º 5
0
    def test_masks(self):
        bpi = bp.BulletProofBuilder()
        self.mask_consistency_check(bpi)

        # Randomized masks
        bpi.use_det_masks = False
        self.mask_consistency_check(bpi)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
 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()
Ejemplo n.º 10
0
 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()])
Ejemplo n.º 11
0
    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))
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
    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))
Ejemplo n.º 15
0
    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))
Ejemplo n.º 16
0
    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))
Ejemplo n.º 17
0
 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])
Ejemplo n.º 18
0
 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])
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
 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()))