Beispiel #1
0
def check_ring_singature(prefix_hash, image, pubs, sig):
    """
    Checks ring signature generated with generate_ring_signature
    """
    image_unp = crypto.ge_frombytes_vartime(image)
    image_pre = crypto.ge_dsm_precomp(image_unp)

    buff_off = len(prefix_hash)
    buff = bytearray(buff_off + 2 * 32 * len(pubs))
    memcpy(buff, 0, prefix_hash, 0, buff_off)
    mvbuff = memoryview(buff)

    sum = crypto.sc_0()
    for i in range(len(pubs)):
        if crypto.sc_check(sig[i][0]) != 0 or crypto.sc_check(sig[i][1]) != 0:
            return False

        tmp3 = crypto.ge_frombytes_vartime(pubs[i])
        tmp2 = crypto.ge_double_scalarmult_base_vartime(
            sig[i][0], tmp3, sig[i][1])
        crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp2)
        buff_off += 32

        tmp3 = crypto.hash_to_point(crypto.encodepoint(pubs[i]))
        tmp2 = crypto.ge_double_scalarmult_precomp_vartime(
            sig[i][1], tmp3, sig[i][0], image_pre)
        crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp2)
        buff_off += 32

        sum = crypto.sc_add(sum, sig[i][0])

    h = crypto.hash_to_scalar(buff)
    h = crypto.sc_sub(h, sum)
    return crypto.sc_isnonzero(h) == 0
Beispiel #2
0
def hash_key_vector(v):
    """
    Hashes key vector
    :param v:
    :return:
    """
    return [crypto.hash_to_point(vi) for vi in v]
Beispiel #3
0
def generate_key_image(public_key, secret_key):
    """
    Key image: secret_key * H_p(pub_key)
    """
    point = crypto.hash_to_point(public_key)
    point2 = crypto.scalarmult(point, secret_key)
    return point2
Beispiel #4
0
def gen_mlsag_ext(message, pk, xx, kLRki, mscout, index, dsRows):
    """
    Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)

    :param message:
    :param pk: matrix of points, point form (not encoded)
    :param xx:
    :param kLRki:
    :param mscout:
    :param index:
    :param dsRows:
    :return:
    """
    rows, cols = gen_mlsag_assert(pk, xx, kLRki, mscout, index, dsRows)

    rv = xmrtypes.MgSig()
    c, L, R, Hi = 0, None, None, None

    c_old, Ip, alpha = gen_mlsag_rows(message, rv, pk, xx, kLRki, index,
                                      dsRows, rows, cols)

    i = (index + 1) % cols
    if i == 0:
        rv.cc = c_old

    while i != index:
        rv.ss[i] = scalar_gen_vector(rows)
        hasher = hasher_message(message)

        for j in range(dsRows):
            L = crypto.add_keys2(rv.ss[i][j], c_old, pk[i][j])
            Hi = crypto.hash_to_point(crypto.encodepoint(
                pk[i][j]))  # originally hashToPoint()
            R = crypto.add_keys3(rv.ss[i][j], Hi, c_old, Ip[j])
            hasher.update(crypto.encodepoint(pk[i][j]))
            hasher.update(crypto.encodepoint(L))
            hasher.update(crypto.encodepoint(R))

        for j in range(dsRows, rows):
            L = crypto.add_keys2(rv.ss[i][j], c_old, pk[i][j])
            hasher.update(crypto.encodepoint(pk[i][j]))
            hasher.update(crypto.encodepoint(L))

        c = crypto.decodeint(hasher.digest())
        c_old = c
        i = (i + 1) % cols

        if i == 0:
            rv.cc = c_old

    for j in range(rows):
        rv.ss[index][j] = crypto.sc_mulsub(
            c, xx[j],
            alpha[j])  # alpha[j] - c * xx[j]; sc_mulsub in original does c-ab

    if mscout:
        mscout(c)

    return rv, c
Beispiel #5
0
def key_image_vector(x):
    """
    Takes as input a keyvector, returns the keyimage-vector
    TODO: use crypto for generating key images
    :param x:
    :return:
    """
    return [
        crypto.scalarmult(crypto.hash_to_point(crypto.scalarmult_base(xx)), xx)
        for xx in x
    ]
Beispiel #6
0
 def test_hash_to_point(self):
     data = unhexlify(
         b"42f6835bf83114a1f5f6076fe79bdfa0bd67c74b88f127d54572d3910dd09201"
     )
     res = crypto.hash_to_point(data)
     res_p = crypto.encodepoint(res)
     self.assertEqual(
         res_p,
         unhexlify(
             b"54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5"
         ),
     )
Beispiel #7
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
Beispiel #8
0
def ver_mlsag_ext(message, pk, rv, dsRows):
    """
    Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
    c.f. http://eprint.iacr.org/2015/1098 section 2.
    keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i

    :param message:
    :param pk: matrix of EC points, point form.
    :param rv:
    :param dsRows:
    :return:
    """
    rows, cols = ver_mlsag_assert(pk, rv, dsRows)
    c_old = rv.cc

    Ip = key_vector(dsRows)
    for i in range(dsRows):
        Ip[i] = crypto.precomp(rv.II[i])

    i = 0
    while i < cols:
        c = 0
        hasher = hasher_message(message)
        for j in range(dsRows):
            L = crypto.add_keys2(rv.ss[i][j], c_old, pk[i][j])
            Hi = crypto.hash_to_point(crypto.encodepoint(
                pk[i][j]))  # originally hashToPoint()
            R = crypto.add_keys3(rv.ss[i][j], Hi, c_old, Ip[j])
            hasher.update(crypto.encodepoint(pk[i][j]))
            hasher.update(crypto.encodepoint(L))
            hasher.update(crypto.encodepoint(R))

        for j in range(dsRows, rows):
            L = crypto.add_keys2(rv.ss[i][j], c_old, pk[i][j])
            hasher.update(crypto.encodepoint(pk[i][j]))
            hasher.update(crypto.encodepoint(L))

        c = crypto.decodeint(hasher.digest())
        c_old = c
        i += 1

    c = crypto.sc_sub(c_old, rv.cc)
    return not crypto.sc_isnonzero(c)
Beispiel #9
0
def generate_ring_signature(prefix_hash,
                            image,
                            pubs,
                            sec,
                            sec_idx,
                            test=False):
    """
    Generates ring signature with key image.
    void crypto_ops::generate_ring_signature()
    """
    if test:
        t = crypto.scalarmult_base(sec)
        if not crypto.point_eq(t, pubs[sec_idx]):
            raise ValueError("Invalid sec key")

        k_i = monero.generate_key_image(crypto.encodepoint(pubs[sec_idx]), sec)
        if not crypto.point_eq(k_i, image):
            raise ValueError("Key image invalid")
        for k in pubs:
            crypto.ge_frombytes_vartime_check(k)

    image_unp = crypto.ge_frombytes_vartime(image)
    image_pre = crypto.ge_dsm_precomp(image_unp)

    buff_off = len(prefix_hash)
    buff = bytearray(buff_off + 2 * 32 * len(pubs))
    memcpy(buff, 0, prefix_hash, 0, buff_off)
    mvbuff = memoryview(buff)

    sum = crypto.sc_0()
    k = crypto.sc_0()
    sig = []
    for i in range(len(pubs)):
        sig.append([crypto.sc_0(), crypto.sc_0()])  # c, r

    for i in range(len(pubs)):
        if i == sec_idx:
            k = crypto.random_scalar()
            tmp3 = crypto.scalarmult_base(k)
            crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp3)
            buff_off += 32

            tmp3 = crypto.hash_to_point(crypto.encodepoint(pubs[i]))
            tmp2 = crypto.scalarmult(tmp3, k)
            crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp2)
            buff_off += 32

        else:
            sig[i] = [crypto.random_scalar(), crypto.random_scalar()]
            tmp3 = crypto.ge_frombytes_vartime(pubs[i])
            tmp2 = crypto.ge_double_scalarmult_base_vartime(
                sig[i][0], tmp3, sig[i][1])
            crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp2)
            buff_off += 32

            tmp3 = crypto.hash_to_point(crypto.encodepoint(tmp3))
            tmp2 = crypto.ge_double_scalarmult_precomp_vartime(
                sig[i][1], tmp3, sig[i][0], image_pre)
            crypto.encodepoint_into(mvbuff[buff_off:buff_off + 32], tmp2)
            buff_off += 32

            sum = crypto.sc_add(sum, sig[i][0])

    h = crypto.hash_to_scalar(buff)
    sig[sec_idx][0] = crypto.sc_sub(h, sum)
    sig[sec_idx][1] = crypto.sc_mulsub(sig[sec_idx][0], sec, k)
    return sig
Beispiel #10
0
def verify_clsag(msg, ss, sc1, sI, sD, pubs, C_offset):
    n = len(pubs)
    c = crypto.new_scalar()
    D_8 = crypto.new_point()
    tmp_bf = bytearray(32)
    C_offset_bf = crypto.encodepoint(C_offset)

    crypto.sc_copy(c, sc1)
    crypto.point_mul8_into(D_8, 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):
        hsh_P.update(x)
        hsh_C.update(x)

    for x in pubs:
        hsh_PC(x.dest)

    for x in pubs:
        hsh_PC(x.commitment)

    hsh_PC(crypto.encodepoint_into(tmp_bf, sI))
    hsh_PC(crypto.encodepoint_into(tmp_bf, sD))
    hsh_PC(C_offset_bf)
    mu_P = crypto.decodeint(hsh_P.digest())
    mu_C = crypto.decodeint(hsh_C.digest())

    c_to_hash = crypto.get_keccak()  # domain, P, C, C_offset, message, L, R
    c_to_hash.update(_HASH_KEY_CLSAG_ROUND)
    for i in range(len(pubs)):
        c_to_hash.update(pubs[i].dest)
    for i in range(len(pubs)):
        c_to_hash.update(pubs[i].commitment)
    c_to_hash.update(C_offset_bf)
    c_to_hash.update(msg)

    c_p = crypto.new_scalar()
    c_c = crypto.new_scalar()
    L = crypto.new_point()
    R = crypto.new_point()
    tmp_pt = crypto.new_point()
    i = 0
    while i < n:
        crypto.sc_mul_into(c_p, mu_P, c)
        crypto.sc_mul_into(c_c, mu_C, c)

        C_P = crypto.point_sub(
            crypto.decodepoint_into(tmp_pt, pubs[i].commitment), C_offset)
        crypto.add_keys2_into(L, ss[i], c_p,
                              crypto.decodepoint_into(tmp_pt, pubs[i].dest))
        crypto.point_add_into(L, L, crypto.scalarmult_into(tmp_pt, C_P, c_c))

        HP = crypto.hash_to_point(pubs[i].dest)
        crypto.add_keys3_into(R, ss[i], HP, c_p, sI)
        crypto.point_add_into(R, R, crypto.scalarmult_into(tmp_pt, D_8, 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())
        i += 1
    res = crypto.sc_sub(c, sc1)
    if not crypto.sc_eq(res, crypto.sc_0()):
        raise ValueError("Signature error")