def sc_muladd(dst, a, b, c):
    dst = _ensure_dst_key(dst)
    crypto.decodeint_into_noreduce(tmp_sc_1, a)
    crypto.decodeint_into_noreduce(tmp_sc_2, b)
    crypto.decodeint_into_noreduce(tmp_sc_3, c)
    crypto.sc_muladd_into(tmp_sc_4, tmp_sc_1, tmp_sc_2, tmp_sc_3)
    crypto.encodeint_into(dst, tmp_sc_4)
    return dst
def inner_product(a, b, dst=None):
    if len(a) != len(b):
        raise ValueError("Incompatible sizes of a and b")
    dst = _ensure_dst_key(dst)
    crypto.sc_init_into(tmp_sc_1, 0)

    for i in range(len(a)):
        crypto.decodeint_into_noreduce(tmp_sc_2, a.to(i))
        crypto.decodeint_into_noreduce(tmp_sc_3, b.to(i))
        crypto.sc_muladd_into(tmp_sc_1, tmp_sc_2, tmp_sc_3, tmp_sc_1)
        gc_iter(i)

    crypto.encodeint_into(dst, tmp_sc_1)
    return dst
def cross_inner_product(l0, r0, l1, r1):
    """
    t1_1 = l0 . r1,     t1_2 = l1 . r0
    t1   = t1_1 + t1_2, t2   = l1 . r1
    """
    sc_t1_1, sc_t1_2, sc_t2 = alloc_scalars(3)
    cl0, cr0, cl1, cr1 = alloc_scalars(4)

    for i in range(len(l0)):
        crypto.decodeint_into_noreduce(cl0, l0.to(i))
        crypto.decodeint_into_noreduce(cr0, r0.to(i))
        crypto.decodeint_into_noreduce(cl1, l1.to(i))
        crypto.decodeint_into_noreduce(cr1, r1.to(i))

        crypto.sc_muladd_into(sc_t1_1, cl0, cr1, sc_t1_1)
        crypto.sc_muladd_into(sc_t1_2, cl1, cr0, sc_t1_2)
        crypto.sc_muladd_into(sc_t2, cl1, cr1, sc_t2)
        gc_iter(i)

    crypto.sc_add_into(sc_t1_1, sc_t1_1, sc_t1_2)
    return crypto.encodeint(sc_t1_1), crypto.encodeint(sc_t2)
Exemple #4
0
def _generate_clsag(
    message: bytes,
    P: List[bytes],
    p: Sc25519,
    C_nonzero: List[bytes],
    z: Sc25519,
    Cout: Ge25519,
    index: int,
    mg_buff: List[bytes],
) -> List[bytes]:
    sI = crypto.new_point()  # sig.I
    sD = crypto.new_point()  # sig.D
    sc1 = crypto.new_scalar()  # sig.c1
    a = crypto.random_scalar()
    H = crypto.new_point()
    D = crypto.new_point()
    Cout_bf = crypto.encodepoint(Cout)

    tmp_sc = crypto.new_scalar()
    tmp = crypto.new_point()
    tmp_bf = bytearray(32)

    crypto.hash_to_point_into(H, P[index])
    crypto.scalarmult_into(sI, H, p)  # I = p*H
    crypto.scalarmult_into(D, H, z)  # D = z*H
    crypto.sc_mul_into(tmp_sc, z, crypto.sc_inv_eight())  # 1/8*z
    crypto.scalarmult_into(sD, H, tmp_sc)  # sig.D = 1/8*z*H
    sD = crypto.encodepoint(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):
        nonlocal hsh_P, hsh_C
        hsh_P.update(x)
        hsh_C.update(x)

    for x in P:
        hsh_PC(x)

    for x in C_nonzero:
        hsh_PC(x)

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

    del (hsh_PC, hsh_P, hsh_C)
    c_to_hash = crypto.get_keccak()  # domain, P, C, C_offset, message, aG, aH
    c_to_hash.update(_HASH_KEY_CLSAG_ROUND)
    for i in range(len(P)):
        c_to_hash.update(P[i])
    for i in range(len(P)):
        c_to_hash.update(C_nonzero[i])
    c_to_hash.update(Cout_bf)
    c_to_hash.update(message)

    chasher = c_to_hash.copy()
    crypto.scalarmult_base_into(tmp, a)
    chasher.update(crypto.encodepoint_into(tmp_bf, tmp))  # aG
    crypto.scalarmult_into(tmp, H, a)
    chasher.update(crypto.encodepoint_into(tmp_bf, tmp))  # aH
    c = crypto.decodeint(chasher.digest())
    del (chasher, H)

    L = crypto.new_point()
    R = crypto.new_point()
    c_p = crypto.new_scalar()
    c_c = crypto.new_scalar()
    i = (index + 1) % len(P)
    if i == 0:
        crypto.sc_copy(sc1, c)

    mg_buff.append(int_serialize.dump_uvarint_b(len(P)))
    for _ in range(len(P)):
        mg_buff.append(bytearray(32))

    while i != index:
        crypto.random_scalar(tmp_sc)
        crypto.encodeint_into(mg_buff[i + 1], tmp_sc)

        crypto.sc_mul_into(c_p, mu_P, c)
        crypto.sc_mul_into(c_c, mu_C, c)

        # L = tmp_sc * G + c_P * P[i] + c_c * C[i]
        crypto.add_keys2_into(L, tmp_sc, c_p,
                              crypto.decodepoint_into(tmp, P[i]))
        crypto.decodepoint_into(tmp, C_nonzero[i])  # C = C_nonzero - Cout
        crypto.point_sub_into(tmp, tmp, Cout)
        crypto.scalarmult_into(tmp, tmp, c_c)
        crypto.point_add_into(L, L, tmp)

        # R = tmp_sc * HP + c_p * I + c_c * D
        crypto.hash_to_point_into(tmp, P[i])
        crypto.add_keys3_into(R, tmp_sc, tmp, c_p, sI)
        crypto.point_add_into(R, R, crypto.scalarmult_into(tmp, D, 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())

        P[i] = None
        C_nonzero[i] = None

        i = (i + 1) % len(P)
        if i == 0:
            crypto.sc_copy(sc1, c)

        if i & 3 == 0:
            gc.collect()

    # Final scalar = a - c * (mu_P * p + mu_c * Z)
    crypto.sc_mul_into(tmp_sc, mu_P, p)
    crypto.sc_muladd_into(tmp_sc, mu_C, z, tmp_sc)
    crypto.sc_mulsub_into(tmp_sc, c, tmp_sc, a)
    crypto.encodeint_into(mg_buff[index + 1], tmp_sc)

    mg_buff.append(crypto.encodeint(sc1))
    mg_buff.append(sD)
    return mg_buff
 def aR1_fnc(i, d):
     crypto.sc_add_into(aR1_sc1, aR.to(i), zc)
     crypto.sc_muladd_into(aR1_sc1, d_vct[i], ypow_back[MN - i],
                           aR1_sc1)
     return crypto.encodeint_into(d, aR1_sc1)