Exemple #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]
Exemple #2
0
 def test_batch_2_m_1_n_4(self):
     M = 1
     N = 4
     data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)]
     proof1 = pybullet.prove(data,N)
     data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)]
     proof2 = pybullet.prove(data,N)
     pybullet.verify([proof1,proof2],N)
Exemple #3
0
    def test_scalar_vector_mul_scalar(self):
        l = 3
        v = ScalarVector([random_scalar() for i in range(l)])
        s = random_scalar()
        w = v*s

        self.assertEqual(len(w),l)
        for i in range(l):
            self.assertEqual(w[i],v[i]*s)
Exemple #4
0
    def test_scalar_vector_sub(self):
        l = 3
        v = ScalarVector([random_scalar() for i in range(l)])
        w = ScalarVector([random_scalar() for i in range(l)])
        x = v-w

        self.assertEqual(len(x),l)
        for i in range(l):
            self.assertEqual(x[i],v[i]-w[i])
Exemple #5
0
    def test_scalar_vector_hadamard(self):
        l = 3
        v = ScalarVector([random_scalar() for i in range(l)])
        w = ScalarVector([random_scalar() for i in range(l)])
        x = v*w

        self.assertEqual(len(x),l)
        for i in range(l):
            self.assertEqual(x[i],v[i]*w[i])
Exemple #6
0
    def test_inner_product(self):
        l = 3
        v = ScalarVector([random_scalar() for i in range(l)])
        w = ScalarVector([random_scalar() for i in range(l)])
        x = v**w

        r = Scalar(0)
        for i in range(l):
            r += v[i]*w[i]
        self.assertEqual(r,x)
Exemple #7
0
 def test_invalid_batch_2_m_1_2_n_4(self):
     M = 1
     N = 4
     data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)]
     proof1 = pybullet.prove(data,N)
     M = 2
     data = [[Scalar(random.randint(2**N,2**(N+1)-1)),random_scalar()] for i in range(M)]
     proof2 = pybullet.prove(data,N)
     with self.assertRaises(ArithmeticError):
         pybullet.verify([proof1,proof2],N)
Exemple #8
0
def gen_account(public_key,a):
    r = dumb25519.random_scalar()
    co = G*a + H*r

    ek = dumb25519.random_scalar()
    s = dumb25519.hash_to_scalar(str(public_key.tpk)+str(public_key.spk)+str(public_key.X)+str(ek))
    pk = public_key.X + H*s

    _ek = ecies.encrypt(public_key.tpk,str(pk)+str(co),str(ek))
    _a = ecies.encrypt(public_key.spk,str(pk)+str(co),str(a))
    _r = ecies.encrypt(public_key.spk,str(pk)+str(co),str(r))

    return Account(pk,co,_ek,_a,_r),DepositKey(a,r)
Exemple #9
0
    def test_scalar_vector_slice(self):
        l = 3
        scalars = [random_scalar() for i in range(2*l)]
        v = ScalarVector(scalars)
        w = v[:l]

        self.assertEqual(len(w),l)
        self.assertEqual(w.scalars,scalars[:l])
Exemple #10
0
    def test_point_vector_mul_scalar(self):
        l = 3
        V = PointVector([random_point() for i in range(l)])
        s = random_scalar()
        W = V*s

        self.assertEqual(len(W),l)
        for i in range(l):
            self.assertEqual(W[i],V[i]*s)
Exemple #11
0
def encrypt(m,A):
    k = Scalar(0)
    while k == Scalar(0):
        k = random_scalar()

    output = Ciphertext()
    output.K = G*k
    output.M = m + hash_to_scalar(A*k)
    return output
Exemple #12
0
    def test_batch_inversion(self):
        l = 8
        v = ScalarVector([random_scalar() for i in range(l)])
        v.append(Scalar(1))
        v.append(Scalar(dumb25519.l - 1))
        w = v.invert()

        for i in range(len(v)):
            self.assertEqual(v[i] * w[i], Scalar(1))
Exemple #13
0
 def test_invalid_value(self):
     M = 1
     N = 4
     data = [[
         Scalar(random.randint(2**N, 2**(N + 1) - 1)),
         random_scalar()
     ]]
     with self.assertRaises(ArithmeticError):
         pybullet.verify([pybullet.prove(data, N)], N)
Exemple #14
0
    def test_point_vector_mul_scalar_vector(self):
        l = 3
        V = PointVector([random_point() for i in range(l)])
        v = ScalarVector([random_scalar() for i in range(l)])
        W = V*v

        R = dumb25519.Z
        for i in range(l):
            R += V[i]*v[i]
        self.assertEqual(W,R)
Exemple #15
0
def spend(withdrawal_keys, deposit_keys, tx, mu):
    witness = prepare_witness(withdrawal_keys, deposit_keys)
    witness_list = [
        witness.d_ijk, witness.x_i, witness.a_in, witness.a_ij, witness.r_in,
        witness.r_out
    ]  # this is so we can flatten for commitment

    t = dumb25519.random_scalar()
    C = dumb25519.pedersen_commit(dumb25519.flatten(witness_list), t)

    s = dumb25519.hash_to_scalar(str(C) + str(tx) + str(mu))
Exemple #16
0
def encrypt(public_key, tag, message):
    if not isinstance(public_key, dumb25519.Point):
        raise TypeError

    r = dumb25519.random_scalar()
    R = G * r
    P = public_key * r

    hashes = hashlib.sha256(str(P) + str(tag)).hexdigest()
    sym_key = hashes[:len(hashes) / 2]
    mac_key = hashes[len(hashes) / 2:]

    e = binascii.hexlify(
        AES.new(sym_key, AES.MODE_CFB, '0' * 16).encrypt(str(message)))
    sigma = hashlib.sha256(mac_key +
                           hashlib.sha256(mac_key +
                                          e).hexdigest()).hexdigest()

    return Ciphertext(R, e, sigma)
Exemple #17
0
def prove(data,N):
    clear_cache()
    M = len(data)

    # curve points
    G = dumb25519.G
    H = hash_to_point('pybullet H')
    Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(M*N)])
    Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(M*N)])

    # set amount commitments
    V = PointVector([])
    aL = ScalarVector([])
    for v,gamma in data:
        V.append((H*v + G*gamma)*inv8)
        mash(V[-1])
        aL.extend(scalar_to_bits(v,N))

    # set bit arrays
    aR = ScalarVector([])
    for bit in aL.scalars:
        aR.append(bit-Scalar(1))

    alpha = random_scalar()
    A = (Gi*aL + Hi*aR + G*alpha)*inv8

    sL = ScalarVector([random_scalar()]*(M*N))
    sR = ScalarVector([random_scalar()]*(M*N))
    rho = random_scalar()
    S = (Gi*sL + Hi*sR + G*rho)*inv8

    # get challenges
    mash(A)
    mash(S)
    y = cache
    y_inv = y.invert()
    mash('')
    z = cache

    # polynomial coefficients
    l0 = aL - ScalarVector([z]*(M*N))
    l1 = sL

    # ugly sum
    zeros_twos = []
    for i in range (M*N):
        zeros_twos.append(Scalar(0))
        for j in range(1,M+1):
            temp = Scalar(0)
            if i >= (j-1)*N and i < j*N:
                temp = Scalar(2)**(i-(j-1)*N)
            zeros_twos[-1] += temp*(z**(1+j))
    
    # more polynomial coefficients
    r0 = aR + ScalarVector([z]*(M*N))
    r0 = r0*exp_scalar(y,M*N)
    r0 += ScalarVector(zeros_twos)
    r1 = exp_scalar(y,M*N)*sR

    # build the polynomials
    t0 = l0**r0
    t1 = l0**r1 + l1**r0
    t2 = l1**r1

    tau1 = random_scalar()
    tau2 = random_scalar()
    T1 = (H*t1 + G*tau1)*inv8
    T2 = (H*t2 + G*tau2)*inv8

    mash(T1)
    mash(T2)
    x = cache # challenge

    taux = tau1*x + tau2*(x**2)
    for j in range(1,M+1):
        gamma = data[j-1][1]
        taux += z**(1+j)*gamma
    mu = x*rho+alpha
    
    l = l0 + l1*x
    r = r0 + r1*x
    t = l**r

    mash(taux)
    mash(mu)
    mash(t)

    x_ip = cache # challenge
    L = PointVector([])
    R = PointVector([])
   
    # initial inner product inputs
    data_ip = [Gi,PointVector([Hi[i]*(y_inv**i) for i in range(len(Hi))]),H*x_ip,l,r,None,None]
    while True:
        data_ip = inner_product(data_ip)

        # we have reached the end of the recursion
        if len(data_ip) == 2:
            return [V,A,S,T1,T2,taux,mu,L,R,data_ip[0],data_ip[1],t]

        # we are not done yet
        L.append(data_ip[-2])
        R.append(data_ip[-1])
Exemple #18
0
def verify(proofs,N):
    # determine the length of the longest proof
    max_MN = 2**max([len(proof[7]) for proof in proofs])

    # curve points
    Z = dumb25519.Z
    G = dumb25519.G
    H = hash_to_point('pybullet H')
    Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)])
    Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)])

    # set up weighted aggregates
    y0 = Scalar(0)
    y1 = Scalar(0)
    z1 = Scalar(0)
    z3 = Scalar(0)
    z4 = [Scalar(0)]*max_MN
    z5 = [Scalar(0)]*max_MN
    scalars = ScalarVector([]) # for final check
    points = PointVector([]) # for final check

    # run through each proof
    for proof in proofs:
        clear_cache()

        V,A,S,T1,T2,taux,mu,L,R,a,b,t = proof

        # get size information
        M = 2**len(L)/N

        # weighting factors for batching
        weight_y = random_scalar()
        weight_z = random_scalar()
        if weight_y == Scalar(0) or weight_z == Scalar(0):
            raise ArithmeticError

        # reconstruct all challenges
        for v in V:
            mash(v)
        mash(A)
        mash(S)
        if cache == Scalar(0):
            raise ArithmeticError
        y = cache
        y_inv = y.invert()
        mash('')
        if cache == Scalar(0):
            raise ArithmeticError
        z = cache
        mash(T1)
        mash(T2)
        if cache == Scalar(0):
            raise ArithmeticError
        x = cache
        mash(taux)
        mash(mu)
        mash(t)
        if cache == Scalar(0):
            raise ArithmeticError
        x_ip = cache

        y0 += taux*weight_y
        
        k = (z-z**2)*sum_scalar(y,M*N)
        for j in range(1,M+1):
            k -= (z**(j+2))*sum_scalar(Scalar(2),N)

        y1 += (t-k)*weight_y

        for j in range(M):
            scalars.append(z**(j+2)*weight_y)
            points.append(V[j]*Scalar(8))
        scalars.append(x*weight_y)
        points.append(T1*Scalar(8))
        scalars.append(x**2*weight_y)
        points.append(T2*Scalar(8))

        scalars.append(weight_z)
        points.append(A*Scalar(8))
        scalars.append(x*weight_z)
        points.append(S*Scalar(8))

        # inner product
        W = ScalarVector([])
        for i in range(len(L)):
            mash(L[i])
            mash(R[i])
            if cache == Scalar(0):
                raise ArithmeticError
            W.append(cache)
        W_inv = W.invert()

        for i in range(M*N):
            index = i
            g = a
            h = b*((y_inv)**i)
            for j in range(len(L)-1,-1,-1):
                J = len(W)-j-1
                base_power = 2**j
                if index/base_power == 0:
                    g *= W_inv[J]
                    h *= W[J]
                else:
                    g *= W[J]
                    h *= W_inv[J]
                    index -= base_power

            g += z
            h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y_inv)**i)

            z4[i] += g*weight_z
            z5[i] += h*weight_z

        z1 += mu*weight_z

        for i in range(len(L)):
            scalars.append(W[i]**2*weight_z)
            points.append(L[i]*Scalar(8))
            scalars.append(W_inv[i]**2*weight_z)
            points.append(R[i]*Scalar(8))
        z3 += (t-a*b)*x_ip*weight_z
    
    # now check all proofs together
    scalars.append(-y0-z1)
    points.append(G)
    scalars.append(-y1+z3)
    points.append(H)
    for i in range(max_MN):
        scalars.append(-z4[i])
        points.append(Gi[i])
        scalars.append(-z5[i])
        points.append(Hi[i])

    if not dumb25519.multiexp(scalars,points) == Z:
        raise ArithmeticError('Bad z check!')

    return True
Exemple #19
0
def verify(proofs,N):
    # determine the length of the longest proof
    max_MN = 2**max([len(proof.L) for proof in proofs])

    # curve points
    Z = dumb25519.Z
    Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)])
    Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)])

    # set up weighted aggregates
    y0 = Scalar(0)
    y1 = Scalar(0)
    z1 = Scalar(0)
    z3 = Scalar(0)
    z4 = [Scalar(0)]*max_MN
    z5 = [Scalar(0)]*max_MN
    scalars = ScalarVector([]) # for final check
    points = PointVector([]) # for final check

    # run through each proof
    for proof in proofs:
        tr = transcript.Transcript('Bulletproof')

        V = proof.V
        A = proof.A
        S = proof.S
        T1 = proof.T1
        T2 = proof.T2
        taux = proof.taux
        mu = proof.mu
        L = proof.L
        R = proof.R
        a = proof.a
        b = proof.b
        t = proof.t

        # get size information
        M = 2**len(L)/N

        # weighting factors for batching
        weight_y = random_scalar()
        weight_z = random_scalar()
        if weight_y == Scalar(0) or weight_z == Scalar(0):
            raise ArithmeticError

        # reconstruct challenges
        for v in V:
            tr.update(v)
        tr.update(A)
        tr.update(S)
        y = tr.challenge()
        if y == Scalar(0):
            raise ArithmeticError
        y_inv = y.invert()
        z = tr.challenge()
        if z == Scalar(0):
            raise ArithmeticError
        tr.update(T1)
        tr.update(T2)
        x = tr.challenge()
        if x == Scalar(0):
            raise ArithmeticError
        tr.update(taux)
        tr.update(mu)
        tr.update(t)
        x_ip = tr.challenge()
        if x_ip == Scalar(0):
            raise ArithmeticError

        y0 += taux*weight_y
        
        k = (z-z**2)*sum_scalar(y,M*N)
        for j in range(1,M+1):
            k -= (z**(j+2))*sum_scalar(Scalar(2),N)

        y1 += (t-k)*weight_y

        for j in range(M):
            scalars.append(z**(j+2)*weight_y)
            points.append(V[j]*Scalar(8))
        scalars.append(x*weight_y)
        points.append(T1*Scalar(8))
        scalars.append(x**2*weight_y)
        points.append(T2*Scalar(8))

        scalars.append(weight_z)
        points.append(A*Scalar(8))
        scalars.append(x*weight_z)
        points.append(S*Scalar(8))

        # inner product
        W = ScalarVector([])
        for i in range(len(L)):
            tr.update(L[i])
            tr.update(R[i])
            W.append(tr.challenge())
            if W[i] == Scalar(0):
                raise ArithmeticError
        W_inv = W.invert()

        for i in range(M*N):
            index = i
            g = a
            h = b*((y_inv)**i)
            for j in range(len(L)-1,-1,-1):
                J = len(W)-j-1
                base_power = 2**j
                if index/base_power == 0:
                    g *= W_inv[J]
                    h *= W[J]
                else:
                    g *= W[J]
                    h *= W_inv[J]
                    index -= base_power

            g += z
            h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y_inv)**i)

            z4[i] += g*weight_z
            z5[i] += h*weight_z

        z1 += mu*weight_z

        for i in range(len(L)):
            scalars.append(W[i]**2*weight_z)
            points.append(L[i]*Scalar(8))
            scalars.append(W_inv[i]**2*weight_z)
            points.append(R[i]*Scalar(8))
        z3 += (t-a*b)*x_ip*weight_z
    
    # now check all proofs together
    scalars.append(-y0-z1)
    points.append(Gc)
    scalars.append(-y1+z3)
    points.append(Hc)
    for i in range(max_MN):
        scalars.append(-z4[i])
        points.append(Gi[i])
        scalars.append(-z5[i])
        points.append(Hi[i])

    if not dumb25519.multiexp(scalars,points) == Z:
        raise ArithmeticError('Bad verification!')

    return True
Exemple #20
0
def prove(data,N):
    tr = transcript.Transcript('Bulletproof')
    M = len(data)

    # curve points
    Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(M*N)])
    Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(M*N)])

    # set amount commitments
    V = PointVector([])
    aL = ScalarVector([])
    for v,gamma in data:
        V.append(com(v,gamma)*inv8)
        tr.update(V[-1])
        aL.extend(scalar_to_bits(v,N))

    # set bit arrays
    aR = ScalarVector([])
    for bit in aL.scalars:
        aR.append(bit-Scalar(1))

    alpha = random_scalar()
    A = (Gi**aL + Hi**aR + Gc*alpha)*inv8

    sL = ScalarVector([random_scalar()]*(M*N))
    sR = ScalarVector([random_scalar()]*(M*N))
    rho = random_scalar()
    S = (Gi**sL + Hi**sR + Gc*rho)*inv8

    # get challenges
    tr.update(A)
    tr.update(S)
    y = tr.challenge()
    z = tr.challenge()
    y_inv = y.invert()

    # polynomial coefficients
    l0 = aL - ScalarVector([z]*(M*N))
    l1 = sL

    # for polynomial coefficients
    zeros_twos = []
    z_cache = z**2
    for j in range(M):
        for i in range(N):
            zeros_twos.append(z_cache*2**i)
        z_cache *= z
    
    # more polynomial coefficients
    r0 = aR + ScalarVector([z]*(M*N))
    r0 = r0*exp_scalar(y,M*N)
    r0 += ScalarVector(zeros_twos)
    r1 = exp_scalar(y,M*N)*sR

    # build the polynomials
    t0 = l0**r0
    t1 = l0**r1 + l1**r0
    t2 = l1**r1

    tau1 = random_scalar()
    tau2 = random_scalar()
    T1 = com(t1,tau1)*inv8
    T2 = com(t2,tau2)*inv8

    tr.update(T1)
    tr.update(T2)
    x = tr.challenge()

    taux = tau1*x + tau2*(x**2)
    for j in range(1,M+1):
        gamma = data[j-1][1]
        taux += z**(1+j)*gamma
    mu = x*rho+alpha
    
    l = l0 + l1*x
    r = r0 + r1*x
    t = l**r

    tr.update(taux)
    tr.update(mu)
    tr.update(t)
    x_ip = tr.challenge()

    # initial inner product inputs
    data = InnerProductRound(Gi,PointVector([Hi[i]*(y_inv**i) for i in range(len(Hi))]),Hc*x_ip,l,r,tr)
    while True:
        inner_product(data)

        # we have reached the end of the recursion
        if data.done:
            return Bulletproof(V,A,S,T1,T2,taux,mu,data.L,data.R,data.a,data.b,t)
Exemple #21
0
def gen_private_key():
    return dumb25519.random_scalar()
Exemple #22
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)
Exemple #23
0
def verify(proofs,N):
    # determine the length of the longest proof
    max_MN = 2**max([len(proof[7]) for proof in proofs])

    # curve points
    Z = dumb25519.Z
    G = dumb25519.G
    H = dumb25519.H
    Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)])
    Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)])

    # verify that all points are in the correct subgroup
    for item in dumb25519.flatten(proofs):
        if not isinstance(item,Point):
            continue
        if not item*Scalar(dumb25519.l) == Z:
            raise ArithmeticError

    # set up weighted aggregates
    y0 = Scalar(0)
    y1 = Scalar(0)
    Y2 = Z
    Y3 = Z
    Y4 = Z
    Z0 = Z
    z1 = Scalar(0)
    Z2 = Z
    z3 = Scalar(0)
    z4 = [Scalar(0)]*max_MN
    z5 = [Scalar(0)]*max_MN

    # run through each proof
    for proof in proofs:
        clear_cache()

        V,A,S,T1,T2,taux,mu,L,R,a,b,t = proof

        # get size information
        M = 2**len(L)/N

        # weighting factor for batching
        w = random_scalar()

        # reconstruct all challenges
        for v in V:
            mash(v)
        mash(A)
        mash(S)
        y = cache
        mash('')
        z = cache
        mash(T1)
        mash(T2)
        x = cache
        mash(taux)
        mash(mu)
        mash(t)
        x_ip = cache

        y0 += taux*w
        
        k = (z-z**2)*sum_scalar(y,M*N)
        for j in range(1,M+1):
            k -= (z**(j+2))*sum_scalar(Scalar(2),N)

        y1 += (t-k)*w

        Temp = Z
        for j in range(M):
            Temp += V[j]*(z**(j+2)*Scalar(8))
        Y2 += Temp*w
        Y3 += T1*(x*w*Scalar(8))
        Y4 += T2*((x**2)*w*Scalar(8))

        Z0 += (A*Scalar(8)+S*(x*Scalar(8)))*w

        # inner product
        W = []
        for i in range(len(L)):
            mash(L[i])
            mash(R[i])
            W.append(cache)

        for i in range(M*N):
            index = i
            g = a
            h = b*((y.invert())**i)
            for j in range(len(L)-1,-1,-1):
                J = len(W)-j-1
                base_power = 2**j
                if index/base_power == 0:
                    g *= W[J].invert()
                    h *= W[J]
                else:
                    g *= W[J]
                    h *= W[J].invert()
                    index -= base_power

            g += z
            h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y.invert())**i)

            z4[i] += g*w
            z5[i] += h*w

        z1 += mu*w

        Multiexp = []
        for i in range(len(L)):
            Multiexp.append([L[i],Scalar(8)*(W[i]**2)])
            Multiexp.append([R[i],Scalar(8)*(W[i].invert()**2)])
        Z2 += dumb25519.multiexp(Multiexp)*w
        z3 += (t-a*b)*x_ip*w
    
    # now check all proofs together
    if not G*y0 + H*y1 - Y2 - Y3 - Y4 == Z:
        raise ArithmeticError('Bad y check!')

    Multiexp = [[Z0,Scalar(1)],[G,-z1],[Z2,Scalar(1)],[H,z3]]
    for i in range(max_MN):
        Multiexp.append([Gi[i],-z4[i]])
        Multiexp.append([Hi[i],-z5[i]])
    if not dumb25519.multiexp(Multiexp) == Z:
        raise ArithmeticError('Bad z check!')

    return True
Exemple #24
0
 def test_random(self):
     random_scalar()
     random_point()
Exemple #25
0
def gen_private_key():
    return PrivateKey(ecies.gen_private_key(),ecies.gen_private_key(),dumb25519.random_scalar())
Exemple #26
0
 def test_8_random(self):
     data = [[random_point(),random_scalar()] for i in range(8)]
     result = Z
     for datum in data:
         result += datum[0]*datum[1]
     self.assertEqual(dumb25519.multiexp(data),result)
Exemple #27
0
 def test_prove_verify_m_2_n_4(self):
     M = 2
     N = 4
     data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)]
     pybullet.verify([pybullet.prove(data,N)],N)