Ejemplo n.º 1
0
def commit(h, m, n, d):
    if len(h) != m * n + d + 1:
        raise ArithmeticError
    if m < 1 or n < 1 or d < 0 or d >= m:
        raise IndexError

    b = [dumb25519.random_scalar()
         for j in range(n)] + [dumb25519.Scalar(0)]  # blinding terms
    M = []  # blinded coefficient matrix; initially we define using columns

    # the first column is unique
    M.append([h[i] for i in range(d)] + [h[d] - b[0]] +
             [dumb25519.Scalar(0) for i in range(m - d)])

    # the rest of the columns (this is why there is an extra blinding term)
    for j in range(n):
        M.append([b[j]] +
                 [h[i] for i in range(j * m + d + 1, (j + 1) * m + d)] +
                 [h[(j + 1) * m + d] - b[j + 1]])

    # test that each matrix entry is a Scalar
    for i in range(n + 1):
        for j in range(m + 1):
            if not isinstance(M[i][j], dumb25519.Scalar):
                raise TypeError

    # commit to each row
    r = [dumb25519.random_scalar() for i in range(m + 1)]  # masks
    H = []  # commitments
    for i in range(m + 1):
        H.append(dumb25519.pedersen_commit([col[i] for col in M], r[i]))

    return H, [M, b, r]
Ejemplo n.º 2
0
def receive(private_key, account):
    ek = dumb25519.Scalar(
        int(
            ecies.decrypt(private_key.tsk,
                          str(account.pk) + str(account.co), account._ek)))
    a = dumb25519.Scalar(
        int(
            ecies.decrypt(private_key.ssk,
                          str(account.pk) + str(account.co), account._a)))
    r = dumb25519.Scalar(
        int(
            ecies.decrypt(private_key.ssk,
                          str(account.pk) + str(account.co), account._r)))

    public_key = stealth.gen_public_key(private_key)
    s = dumb25519.hash_to_scalar(
        str(public_key.tpk) + str(public_key.spk) + str(ek))

    if G * a + H * r != account.co:
        raise Exception('Bad account commitment!')
    if public_key.X + H * s != account.pk:
        raise Exception('Bad account public key!')

    xs = private_key.x + s
    return WithdrawalKey(xs, a, r, T * xs.invert())
Ejemplo n.º 3
0
def evaluate(state, x):
    if not isinstance(x, dumb25519.Scalar):
        raise TypeError

    M = state[0]
    r = state[2]

    hbar = []

    n = len(M) - 1
    m = len(M[0]) - 1
    for j in range(n + 1):
        temp = dumb25519.Scalar(0)
        for i in range(m + 1):
            temp += M[j][i] * (x**i)
        hbar.append(temp)

    rbar = dumb25519.Scalar(0)
    for i in range(m + 1):
        rbar += r[i] * (x**i)

    return [hbar, rbar]
Ejemplo n.º 4
0
def prepare_witness(withdrawal_keys, deposit_keys):
    a_in = [withdrawal_key.a for withdrawal_key in withdrawal_keys]
    a_out = [deposit_key.a for deposit_key in deposit_keys]
    r_in = [withdrawal_key.r for withdrawal_key in withdrawal_keys]
    r_out = [deposit_key.r for deposit_key in deposit_keys]

    if len(a_in) != len(r_in) or len(a_out) != len(r_out):
        raise IndexError

    max_i = len(a_in)
    max_j = len(nary(R, p1))
    max_k = p1

    d_ijk = []
    for i in range(max_i):
        d_ijk.append([])
        i_decomp = nary(i, p1, max_j)

        for j in range(max_j):
            d_ijk[i].append([])

            for k in range(max_k):
                if i_decomp[j] == k:
                    d_ijk[i][j].append(dumb25519.Scalar(1))
                else:
                    d_ijk[i][j].append(dumb25519.Scalar(0))

    max_i = len(a_out)
    max_j = len(nary(beta, p2))

    a_ij = []
    for i in range(max_i):
        a_ij.append(
            [dumb25519.Scalar(a) for a in nary(a_out[i].to_int(), p2, max_j)])

    return Witness(d_ijk,
                   [withdrawal_key.x for withdrawal_key in withdrawal_keys],
                   a_in, a_ij, r_in, r_out)
Ejemplo n.º 5
0
def verify(proof):
    xG = proof.xG
    xH = proof.xH
    C_G = proof.C_G
    C_H = proof.C_H
    e0_G = proof.e0_G
    e0_H = proof.e0_H
    a0 = proof.a0
    a1 = proof.a1
    b0 = proof.b0
    b1 = proof.b1

    # generators
    G = dumb25519.G
    G1 = dumb25519.hash_to_point('G1')
    H = dumb448.hash_to_point('H')
    H1 = dumb448.hash_to_point('H1')

    # reconstruct hashes using commitments
    xG_prime = dumb25519.Z
    xH_prime = dumb448.Z
    for i in range(len(C_G)):
        xG_prime += dumb25519.Scalar(2)**i * C_G[i]
        xH_prime += dumb448.Scalar(2)**i * C_H[i]
    if not xG_prime == xG or not xH_prime == xH:
        raise ArithmeticError('Commitments do not sum to hash value!')

    for i in range(len(C_G)):
        e1_G = dumb25519.hash_to_scalar(C_G[i], C_H[i],
                                        a1[i] * G - e0_G[i] * C_G[i],
                                        b1[i] * H - e0_H[i] * C_H[i])
        e1_H = dumb448.hash_to_scalar(C_G[i], C_H[i],
                                      a1[i] * G - e0_G[i] * C_G[i],
                                      b1[i] * H - e0_H[i] * C_H[i])
        e0_prime_G = dumb25519.hash_to_scalar(C_G[i], C_H[i],
                                              a0[i] * G - e1_G * (C_G[i] - G1),
                                              b0[i] * H - e1_H * (C_H[i] - H1))
        e0_prime_H = dumb448.hash_to_scalar(C_G[i], C_H[i],
                                            a0[i] * G - e1_G * (C_G[i] - G1),
                                            b0[i] * H - e1_H * (C_H[i] - H1))
        if not e0_G[i] == e0_prime_G or not e0_H[i] == e0_prime_H:
            raise ArithmeticError(
                'Bitwise ring signature verification failed!')
Ejemplo n.º 6
0
def prove(x):
    if not x < max_x:
        raise ValueError('Discrete log is too large!')
    if not x >= 0:
        raise ValueError('Discrete log must not be negative!')
    b = nary(x, 2)

    # generate blinders that sum to zero
    r = dumb25519.ScalarVector([])
    r_sum = dumb25519.Scalar(0)
    s = dumb448.ScalarVector([])
    s_sum = dumb448.Scalar(0)
    for i in range(len(b) - 1):
        r.append(dumb25519.random_scalar())
        r_sum += dumb25519.Scalar(2)**i * r[-1]
        s.append(dumb448.random_scalar())
        s_sum += dumb448.Scalar(2)**i * s[-1]
    temp_2inv_25519 = (dumb25519.Scalar(2)**(len(b) - 1)).invert()
    temp_2inv_448 = (dumb448.Scalar(2)**(len(b) - 1)).invert()
    r.append(-temp_2inv_25519 * r_sum)
    s.append(-temp_2inv_448 * s_sum)

    # sanity check on blinder sums
    temp_r = dumb25519.Scalar(0)
    temp_s = dumb448.Scalar(0)
    for i in range(len(b)):
        temp_r += dumb25519.Scalar(2)**i * r[i]
        temp_s += dumb448.Scalar(2)**i * s[i]
    if not temp_r == dumb25519.Scalar(0) or not temp_s == dumb448.Scalar(0):
        raise ArithmeticError('Blinder sum check failed!')

    # generators
    G = dumb25519.G
    G1 = dumb25519.hash_to_point('G1')
    H = dumb448.hash_to_point('H')
    H1 = dumb448.hash_to_point('H1')

    # commitments to bits of x
    C_G = dumb25519.PointVector([])
    C_H = dumb448.PointVector([])
    for i in range(len(b)):
        C_G.append(dumb25519.Scalar(b[i]) * G1 + r[i] * G)
        C_H.append(dumb448.Scalar(b[i]) * H1 + s[i] * H)

    # sanity check on commitment sums
    temp_C_G = dumb25519.Z
    temp_C_H = dumb448.Z
    for i in range(len(b)):
        temp_C_G += dumb25519.Scalar(2)**i * C_G[i]
        temp_C_H += dumb448.Scalar(2)**i * C_H[i]
    if not temp_C_G == dumb25519.Scalar(
            x) * G1 or not temp_C_H == dumb448.Scalar(x) * H1:
        raise ArithmeticError('Bit construction check failed!')

    # proof elements
    e0_G = dumb25519.ScalarVector([])
    e0_H = dumb448.ScalarVector([])
    a0 = dumb25519.ScalarVector([])
    a1 = dumb25519.ScalarVector([])
    b0 = dumb448.ScalarVector([])
    b1 = dumb448.ScalarVector([])

    # construct the proof
    for i in range(len(b)):
        # the current bit is 0
        if b[i] == 0:
            j = dumb25519.random_scalar()
            k = dumb448.random_scalar()
            e1_G = dumb25519.hash_to_scalar(C_G[i], C_H[i], j * G, k * H)
            e1_H = dumb448.hash_to_scalar(C_G[i], C_H[i], j * G, k * H)

            a0.append(dumb25519.random_scalar())
            b0.append(dumb448.random_scalar())
            e0_G.append(
                dumb25519.hash_to_scalar(C_G[i], C_H[i],
                                         a0[i] * G - e1_G * (C_G[i] - G1),
                                         b0[i] * H - e1_H * (C_H[i] - H1)))
            e0_H.append(
                dumb448.hash_to_scalar(C_G[i], C_H[i],
                                       a0[i] * G - e1_G * (C_G[i] - G1),
                                       b0[i] * H - e1_H * (C_H[i] - H1)))

            a1.append(j + e0_G[i] * r[i])
            b1.append(k + e0_H[i] * s[i])
        # the current bit is 1
        elif b[i] == 1:
            j = dumb25519.random_scalar()
            k = dumb448.random_scalar()
            e0_G.append(dumb25519.hash_to_scalar(C_G[i], C_H[i], j * G, k * H))
            e0_H.append(dumb448.hash_to_scalar(C_G[i], C_H[i], j * G, k * H))

            a1.append(dumb25519.random_scalar())
            b1.append(dumb448.random_scalar())
            e1_G = dumb25519.hash_to_scalar(C_G[i], C_H[i],
                                            a1[i] * G - e0_G[i] * C_G[i],
                                            b1[i] * H - e0_H[i] * C_H[i])
            e1_H = dumb448.hash_to_scalar(C_G[i], C_H[i],
                                          a1[i] * G - e0_G[i] * C_G[i],
                                          b1[i] * H - e0_H[i] * C_H[i])

            a0.append(j + e1_G * r[i])
            b0.append(k + e1_H * s[i])
        # somehow the bit is something else
        else:
            raise ArithmeticError('Bit decomposition must be 0 or 1!')

    return Proof(
        dumb25519.Scalar(x) * G1,
        dumb448.Scalar(x) * H1, C_G, C_H, e0_G, e0_H, a0, a1, b0, b1)