Ejemplo n.º 1
0
    def back_encrypt(self, authenticated=True):
        for i in range(5):
            priv_key = crypto.random_scalar()
            data = crypto.cn_fast_hash(crypto.encodeint(
                crypto.random_scalar())) * (i + 1)

            blob = chacha.encrypt_xmr(priv_key,
                                      data,
                                      authenticated=authenticated)
            plaintext = chacha.decrypt_xmr(priv_key,
                                           blob,
                                           authenticated=authenticated)
            self.assertEqual(data, plaintext)

            try:
                plaintext2 = chacha.decrypt_xmr(
                    crypto.sc_add(priv_key, crypto.sc_init(1)),
                    blob,
                    authenticated=authenticated,
                )
                if authenticated:
                    self.fail("Signature error expected")
                else:
                    self.assertNotEqual(data, plaintext2)

            except:
                if not authenticated:
                    raise
Ejemplo n.º 2
0
 def gen_creds(self):
     if self.creds:
         return
     for i in range(3):
         self.creds.append(
             AccountCreds.new_wallet(crypto.random_scalar(),
                                     crypto.random_scalar(), self.nettype))
     return self.creds
Ejemplo n.º 3
0
    def test_ge25519_double_scalarmult_vartime(self):
        for i in range(10):
            ap = crypto.random_scalar()
            A = crypto.scalarmult_base(ap)
            a = crypto.random_scalar()
            b = crypto.random_scalar()

            R = crypto.ge_double_scalarmult_base_vartime(a, A, b)
            R_exp = crypto.point_add(crypto.scalarmult(A, a), crypto.scalarmult_base(b))
            self.assertTrue(crypto.point_eq(R, R_exp))
Ejemplo n.º 4
0
    def gen_clsag_sig(self, ring_size=11, index=None):
        msg = bytearray(random.getrandbits(8) for _ in range(32))
        amnt = crypto.sc_init(random.randint(0, 0xFFFFFF) + 12)
        priv = crypto.random_scalar()
        msk = crypto.random_scalar()
        alpha = crypto.random_scalar()
        P = crypto.scalarmult_base(priv)
        C = crypto.add_keys2(msk, amnt, crypto.xmr_H())
        Cp = crypto.add_keys2(alpha, amnt, crypto.xmr_H())

        ring = []
        for i in range(ring_size - 1):
            tk = TmpKey(
                crypto.encodepoint(
                    crypto.scalarmult_base(crypto.random_scalar())),
                crypto.encodepoint(
                    crypto.scalarmult_base(crypto.random_scalar())),
            )
            ring.append(tk)

        index = index if index is not None else random.randint(0, len(ring))
        ring.insert(index, TmpKey(crypto.encodepoint(P),
                                  crypto.encodepoint(C)))
        ring2 = list(ring)
        mg_buffer = []

        self.assertTrue(
            crypto.point_eq(crypto.scalarmult_base(priv),
                            crypto.decodepoint(ring[index].dest)))
        self.assertTrue(
            crypto.point_eq(
                crypto.scalarmult_base(crypto.sc_sub(msk, alpha)),
                crypto.point_sub(crypto.decodepoint(ring[index].commitment),
                                 Cp),
            ))

        mlsag2.generate_clsag_simple(
            msg,
            ring,
            CtKey(dest=priv, mask=msk),
            alpha,
            Cp,
            index,
            mg_buffer,
        )

        sD = crypto.decodepoint(mg_buffer[-1])
        sc1 = crypto.decodeint(mg_buffer[-2])
        scalars = [crypto.decodeint(x) for x in mg_buffer[1:-2]]
        H = crypto.new_point()
        sI = crypto.new_point()

        crypto.hash_to_point_into(H, crypto.encodepoint(P))
        crypto.scalarmult_into(sI, H, priv)  # I = p*H
        return msg, scalars, sc1, sI, sD, ring2, Cp
Ejemplo n.º 5
0
def gen_mlsag_rows(message, rv, pk, xx, kLRki, index, dsRows, rows, cols):
    """
    MLSAG computation - the part with secret keys
    :param message:
    :param rv:
    :param pk:
    :param xx:
    :param kLRki:
    :param index:
    :param dsRows:
    :param rows:
    :param cols:
    :return:
    """
    Ip = key_vector(dsRows)
    rv.II = key_vector(dsRows)
    alpha = key_vector(rows)
    rv.ss = key_matrix(rows, cols)

    hasher = hasher_message(message)

    for i in range(dsRows):
        hasher.update(crypto.encodepoint(pk[index][i]))
        if kLRki:
            alpha[i] = kLRki.k
            rv.II[i] = kLRki.ki
            hasher.update(crypto.encodepoint(kLRki.L))
            hasher.update(crypto.encodepoint(kLRki.R))

        else:
            Hi = crypto.hash_to_point(crypto.encodepoint(
                pk[index][i]))  # originally hashToPoint()
            alpha[i] = crypto.random_scalar()
            aGi = crypto.scalarmult_base(alpha[i])
            aHPi = crypto.scalarmult(Hi, alpha[i])
            rv.II[i] = crypto.scalarmult(Hi, xx[i])
            hasher.update(crypto.encodepoint(aGi))
            hasher.update(crypto.encodepoint(aHPi))

        Ip[i] = crypto.precomp(rv.II[i])

    for i in range(dsRows, rows):
        alpha[i] = crypto.random_scalar()
        aGi = crypto.scalarmult_base(alpha[i])
        hasher.update(crypto.encodepoint(pk[index][i]))
        hasher.update(crypto.encodepoint(aGi))

    c_old = hasher.digest()
    c_old = crypto.decodeint(c_old)
    return c_old, Ip, alpha
Ejemplo n.º 6
0
    def test_encrypt_base(self):
        for i in range(10):
            key = crypto.cn_fast_hash(crypto.encodeint(crypto.random_scalar()))
            data = crypto.cn_fast_hash(crypto.encodeint(
                crypto.random_scalar())) * (i + 1)

            ciphertext = chacha.encrypt(key, data)
            plaintext = chacha.decrypt(key, ciphertext)
            self.assertEqual(plaintext, data)

            plaintext2 = chacha.decrypt(
                key,
                bytes(int(ciphertext[0]) ^ 0xff) + ciphertext[1:])
            self.assertNotEqual(plaintext2, data)
Ejemplo n.º 7
0
def compute_tx_key(spend_key_private,
                   tx_prefix_hash,
                   salt=None,
                   rand_mult=None):
    """

    :param spend_key_private:
    :param tx_prefix_hash:
    :param salt:
    :param rand_mult:
    :return:
    """
    if not salt:
        salt = crypto.random_bytes(32)

    if not rand_mult:
        rand_mult_num = crypto.random_scalar()
        rand_mult = crypto.encodeint(rand_mult_num)
    else:
        rand_mult_num = crypto.decodeint(rand_mult)

    rand_inp = crypto.sc_add(spend_key_private, rand_mult_num)
    passwd = crypto.keccak_2hash(crypto.encodeint(rand_inp) + tx_prefix_hash)
    tx_key = crypto.compute_hmac(salt, passwd)
    # tx_key = crypto.pbkdf2(passwd, salt, count=100)
    return tx_key, salt, rand_mult
Ejemplo n.º 8
0
 def gen_r(self):
     """
     Generates a new transaction key pair.
     :return:
     """
     self.r = crypto.random_scalar()
     self.r_pub = crypto.scalarmult_base(self.r)
Ejemplo n.º 9
0
    async def init_transaction(self, tsx_data, tsx_ctr):
        """
        Initializes a new transaction.
        :param tsx_data:
        :param tsx_ctr:
        :return:
        """
        self.tsx_data = tsx_data
        self.gen_r()

        # Additional keys
        class_res = classify_subaddresses(
            tsx_data.outputs, tsx_data.change_dts.addr if tsx_data.change_dts else None
        )
        num_stdaddresses, num_subaddresses, single_dest_subaddress = class_res

        # if this is a single-destination transfer to a subaddress, we set the tx pubkey to R=s*D
        if num_stdaddresses == 0 and num_subaddresses == 1:
            self.r_pub = crypto.ge_scalarmult(
                self.r, crypto.decodepoint(single_dest_subaddress.m_spend_public_key)
            )

        self.need_additional_txkeys = num_subaddresses > 0 and (
            num_stdaddresses > 0 or num_subaddresses > 1
        )
        if self.need_additional_txkeys:
            for _ in range(len(tsx_data.outputs)):
                self.additional_tx_keys.append(crypto.random_scalar())

        # Extra processing, payment id
        self.tx.version = 2
        self.tx.unlock_time = tsx_data.unlock_time
        await self.process_payment_id()
        await self.compute_hmac_keys(tsx_ctr)
Ejemplo n.º 10
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.º 11
0
    async def mlsag_prepare(self):
        Hi = None
        xin = None
        options = 0

        if len(self.c_msg) > 1:
            options = 1
            Hi = crypto.decodepoint(self._fetch())
            if self.options & 0x40:
                xin = crypto.decodeint(self._fetch())
            else:
                xin = crypto.decodeint(self._fetch_decrypt())

        alpha = crypto.random_scalar()
        self._insert_encrypt(crypto.encodeint(alpha))

        # ai.G
        self._insert(crypto.encodepoint(crypto.scalarmult_base(alpha)))

        if options:
            # ai * Hi
            self._insert(crypto.encodepoint(crypto.scalarmult(Hi, alpha)))
            # xin * Hi
            self._insert(crypto.encodepoint(crypto.scalarmult(Hi, xin)))
        return SW_OK
Ejemplo n.º 12
0
def scalar_gen_vector(n):
    """
    Generates vector of scalars
    :param n:
    :return:
    """
    return [crypto.random_scalar() for _ in range(0, n)]
Ejemplo n.º 13
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.º 14
0
 def gen_r(self, use_r=None):
     """
     Generates a new transaction key pair.
     :param use_r:
     :return:
     """
     self.r = crypto.random_scalar() if use_r is None else use_r
     self.r_pub = crypto.scalarmult_base(self.r)
Ejemplo n.º 15
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.º 16
0
def main():
    """
    Entry point
    :return:
    """
    parser = argparse.ArgumentParser(
        description="Generate non-deterministic wallet credentials")

    parser.add_argument(
        "--testnet",
        dest="testnet",
        default=False,
        action="store_const",
        const=True,
        help="Testnet",
    )

    parser.add_argument(
        "--stagenet",
        dest="stagenet",
        default=False,
        action="store_const",
        const=True,
        help="Testnet",
    )

    args = parser.parse_args()

    network_type = monero.NetworkTypes.MAINNET
    if args.testnet:
        network_type = monero.NetworkTypes.TESTNET
    elif args.stagenet:
        network_type = monero.NetworkTypes.STAGENET

    priv_view = crypto.random_scalar()
    priv_spend = crypto.random_scalar()
    w = monero.AccountCreds.new_wallet(priv_view,
                                       priv_spend,
                                       network_type=network_type)

    print("Address: %s" % w.address.decode("utf8"))
    print("Private view key:  %s" %
          binascii.hexlify(crypto.encodeint(priv_view)).decode("utf8"))
    print("Private spend key: %s" %
          binascii.hexlify(crypto.encodeint(priv_spend)).decode("utf8"))
Ejemplo n.º 17
0
    async def open_tx(self):
        self.ctx_amount = sha256()
        self.account = self._fetch_u32()

        self.r = crypto.random_scalar()
        self.R = crypto.scalarmult_base(self.r)

        self._insert(crypto.encodepoint(self.R))
        self._insert_encrypt(crypto.encodeint(self.r))
        return SW_OK
Ejemplo n.º 18
0
def pttest2(N=10000):
    a = crypto.random_scalar()
    a8 = crypto.sc_mul(a, crypto.sc_init(8))
    for i in range(1, N):
        ca = crypto.sc_mul(a8, crypto.sc_init(i))
        A8 = crypto.scalarmult_base(ca)
        A8bin = crypto.encodepoint(A8)
        red = crypto.encodeint(crypto.decodeint(A8bin))
        if red == A8bin:
            return i, red
    return None
Ejemplo n.º 19
0
def gen_schnorr_non_linkable(x, P1, P2, index):
    """
    Generates simple Schnorr
    :param x:
    :param P1:
    :param P2:
    :param index:
    :return:
    """
    a = crypto.random_scalar()
    L1 = crypto.scalarmult_base(a)
    s2 = crypto.random_scalar()
    c2 = crypto.cn_fast_hash(crypto.encodepoint(L1))
    L2 = crypto.point_add(
        crypto.scalarmult_base(s2),
        crypto.scalarmult(P2 if index == 0 else P1, crypto.decodeint(c2)),
    )
    c1 = crypto.cn_fast_hash(crypto.encodepoint(L2))
    s1 = crypto.sc_mulsub(x, crypto.decodeint(c1), a)

    return (L1, s1, s2) if index == 0 else (L2, s2, s1)
Ejemplo n.º 20
0
    def test_signature(self):
        for i in range(10):
            priv = crypto.random_scalar()
            data = crypto.cn_fast_hash(bytes(bytearray([i])))

            c, r, pub = crypto.generate_signature(data, priv)
            res = crypto.check_signature(data, c, r, pub)
            self.assertEqual(res, 1)

            res2 = crypto.check_signature(data,
                                          crypto.sc_add(c, crypto.sc_init(1)),
                                          r, pub)
            self.assertEqual(res2, 0)
Ejemplo n.º 21
0
async def prove_range_bp(amount, last_mask=None):
    mask = last_mask if last_mask is not None else crypto.random_scalar()
    bp_proof = await prove_range_bp_batch([amount], [mask])

    C = crypto.decodepoint(bp_proof.V[0])
    C = crypto.point_mul8(C)

    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 C, mask, bp_proof
Ejemplo n.º 22
0
def gen_borromean(x, P1, P2, indices):
    """
    Generates Borromean signature for range proofs.
    :return:
    """
    n = len(P1)
    alpha = key_zero_vector(n)
    s1 = key_zero_vector(n)
    kck = crypto.get_keccak()  # ee computation

    for ii in range(n):
        alpha[ii] = crypto.random_scalar()
        L = crypto.scalarmult_base(alpha[ii])

        if indices[ii] == 0:
            s1[ii] = crypto.random_scalar()
            c = crypto.hash_to_scalar(crypto.encodepoint(L))
            L = crypto.add_keys2(s1[ii], c, P2[ii])
            kck.update(crypto.encodepoint(L))

        else:
            kck.update(crypto.encodepoint(L))

    ee = crypto.decodeint(kck.digest())
    del kck

    s0 = key_zero_vector(n)

    for jj in range(n):
        if not indices[jj]:
            s0[jj] = crypto.sc_mulsub(x[jj], ee, alpha[jj])
        else:
            s0[jj] = crypto.random_scalar()
            LL = crypto.add_keys2(s0[jj], ee, P1[jj])
            cc = crypto.hash_to_scalar(crypto.encodepoint(LL))
            s1[jj] = crypto.sc_mulsub(x[jj], cc, alpha[jj])

    return s0, s1, ee
Ejemplo n.º 23
0
    def test_pointadd(self):
        a = crypto.random_scalar()
        A = crypto.scalarmult_base(a)
        A2 = crypto.point_add(A, A)
        A3 = crypto.point_add(A2, A)
        A4 = crypto.point_add(A3, A)
        A8 = crypto.scalarmult(A4, crypto.sc_init(2))

        A8p = crypto.point_mul8(A)
        self.assertTrue(crypto.point_eq(A8p, A8))
        self.assertTrue(
            crypto.point_eq(A4, crypto.scalarmult(A, crypto.sc_init(4))))
        self.assertTrue(
            crypto.point_eq(A3, crypto.scalarmult(A, crypto.sc_init(3))))
Ejemplo n.º 24
0
def prove_range_orig(amount, last_mask=None, use_asnl=False):
    """
    Gives C, and mask such that \sumCi = C
    c.f. http:#eprint.iacr.org/2015/1098 section 5.1

    Ci is a commitment to either 0 or 2^i, i=0,...,63
    thus this proves that "amount" is in [0, 2^ATOMS]
    mask is a such that C = aG + bH, and b = amount
    :param amount:
    :param last_mask: ai[ATOMS-1] will be computed as \sum_{i=0}^{ATOMS-2} a_i - last_mask
    :param use_asnl: use ASNL, used before Borromean, insecure
    :return: sumCi, mask, RangeSig.
        sumCi is Pedersen commitment on the amount value. sumCi = aG + amount*H
        mask is "a" from the Pedersent commitment above.
    """
    bb = d2b(amount,
             ATOMS)  # gives binary form of bb in "digits" binary digits
    logger.info("amount, amount in binary %s %s" % (amount, bb))
    ai = [None] * len(bb)
    Ci = [None] * len(bb)
    CiH = [None] * len(bb)  # this is like Ci - 2^i H
    H2 = crypto.gen_Hpow(ATOMS)
    a = crypto.sc_0()
    for i in range(0, ATOMS):
        ai[i] = crypto.random_scalar()
        if last_mask is not None and i == ATOMS - 1:
            ai[i] = crypto.sc_sub(last_mask, a)

        a = crypto.sc_add(
            a, ai[i]
        )  # creating the total mask since you have to pass this to receiver...
        if bb[i] == 0:
            Ci[i] = crypto.scalarmult_base(ai[i])
        if bb[i] == 1:
            Ci[i] = crypto.point_add(crypto.scalarmult_base(ai[i]), H2[i])
        CiH[i] = crypto.point_sub(Ci[i], H2[i])

    A = xmrtypes.BoroSig()

    if use_asnl:
        A.s0, A.s1, A.ee = asnl.gen_asnl(ai, Ci, CiH, bb)
    else:
        A.s0, A.s1, A.ee = mlsag2.gen_borromean(ai, Ci, CiH, bb)

    R = xmrtypes.RangeSig()
    R.asig = A
    R.Ci = Ci

    C = sum_Ci(Ci)
    return C, a, R
Ejemplo n.º 25
0
    async def commitment(self, in_amount):
        """
        Computes Pedersen commitment - pseudo outs
        Here is slight deviation from the original protocol.
        We want that \\sum Alpha = \\sum A_{i,j} where A_{i,j} is a mask from range proof for output i, bit j.

        Previously this was computed in such a way that Alpha_{last} = \\sum A{i,j} - \\sum_{i=0}^{last-1} Alpha
        But we would prefer to compute commitment before range proofs so alphas are generated completely randomly
        and the last A mask is computed in this special way.
        Returns pseudo_out
        :return:
        """
        alpha = crypto.random_scalar()
        self.sumpouts_alphas = crypto.sc_add(self.sumpouts_alphas, alpha)
        return alpha, crypto.gen_c(alpha, in_amount)
Ejemplo n.º 26
0
def ecdh_encode(unmasked, receiver_pk=None, derivation=None, v2=False, dest=None):
    """
    Elliptic Curve Diffie-Helman: encodes and decodes the amount b and mask a
    where C= aG + bH
    :param unmasked:
    :param receiver_pk:
    :param derivation:
    :return:
    """
    rv = xmrtypes.EcdhTuple() if dest is None else dest
    if derivation is None:
        esk = crypto.random_scalar()
        rv.senderPk = crypto.scalarmult_base(esk)
        derivation = crypto.encodepoint(crypto.scalarmult(receiver_pk, esk))

    return ecdh_encdec(unmasked, None, derivation, v2=v2, enc=True, dest=rv)
Ejemplo n.º 27
0
    async def compute_sec_keys(self, tsx_data, tsx_ctr):
        """
        Generate master key H(TsxData || r || c_tsx)
        :return:
        """
        from monero_glue.xmr.sub.keccak_hasher import get_keccak_writer
        from monero_serialize import xmrserialize

        writer = get_keccak_writer()
        ar1 = xmrserialize.Archive(writer, True)
        await ar1.message(tsx_data)
        await writer.awrite(crypto.encodeint(self.r))
        await xmrserialize.dump_uvarint(writer, tsx_ctr)
        self.key_master = crypto.keccak_2hash(
            writer.get_digest() + crypto.encodeint(crypto.random_scalar())
        )
        self.key_hmac = crypto.keccak_2hash(b"hmac" + self.key_master)
        self.key_enc = crypto.keccak_2hash(b"enc" + self.key_master)
Ejemplo n.º 28
0
def ecdh_encode(unmasked, receiver_pk=None, derivation=None):
    """
    Elliptic Curve Diffie-Helman: encodes and decodes the amount b and mask a
    where C= aG + bH
    :param unmasked:
    :param receiver_pk:
    :param derivation:
    :return:
    """
    rv = xmrtypes.EcdhTuple()
    if derivation is None:
        esk = crypto.random_scalar()
        rv.senderPk = crypto.scalarmult_base(esk)
        derivation = crypto.encodepoint(crypto.scalarmult(receiver_pk, esk))

    sec1 = crypto.hash_to_scalar(derivation)
    sec2 = crypto.hash_to_scalar(crypto.encodeint(sec1))

    rv.mask = crypto.sc_add(unmasked.mask, sec1)
    rv.amount = crypto.sc_add(unmasked.amount, sec2)
    return rv
Ejemplo n.º 29
0
    async def _set_out1_additional_keys(self, dst_entr):
        additional_txkey = None
        additional_txkey_priv = None
        if self.need_additional_txkeys:
            use_provided = self.num_dests() == len(self.additional_tx_private_keys)
            additional_txkey_priv = (
                self.additional_tx_private_keys[self.out_idx]
                if use_provided
                else crypto.random_scalar()
            )

            if dst_entr.is_subaddress:
                additional_txkey = crypto.ge_scalarmult(
                    additional_txkey_priv,
                    crypto.decodepoint(dst_entr.addr.m_spend_public_key),
                )
            else:
                additional_txkey = crypto.ge_scalarmult_base(additional_txkey_priv)

            self.additional_tx_public_keys.append(crypto.encodepoint(additional_txkey))
            if not use_provided:
                self.additional_tx_private_keys.append(additional_txkey_priv)
        return additional_txkey_priv
Ejemplo n.º 30
0
    async def test_live_refresh(self):
        if self.should_test_only_tx() or not int(
                os.getenv("TREZOR_TEST_LIVE_REFRESH", '1')):
            self.skipTest("Live refresh skipped")

        creds = self.get_trezor_creds(0)
        await self.agent.live_refresh_start()
        for att in range(22):
            r = crypto.random_scalar()
            R = crypto.scalarmult_base(r)
            D = crypto.scalarmult(R, creds.view_key_private)
            subaddr = 0, att

            scalar_step1 = crypto.derive_secret_key(D, att,
                                                    creds.spend_key_private)

            # step 2: add Hs(SubAddr || a || index_major || index_minor)
            if subaddr == (0, 0):
                scalar_step2 = scalar_step1
            else:
                subaddr_sk = monero.get_subaddress_secret_key(
                    creds.view_key_private, major=0, minor=att)
                scalar_step2 = crypto.sc_add(scalar_step1, subaddr_sk)

            pub_ver = crypto.scalarmult_base(scalar_step2)
            ki = monero.generate_key_image(crypto.encodepoint(pub_ver),
                                           scalar_step2)

            ki2 = await self.agent.live_refresh(creds.view_key_private,
                                                crypto.encodepoint(pub_ver),
                                                crypto.encodepoint(D), att, 0,
                                                att)

            if not crypto.point_eq(ki, ki2):
                raise ValueError("Key image inconsistent")
            time.sleep(0.1)
        await self.agent.live_refresh_final()