Exemple #1
0
def verify_prf(*args, **kwargs) -> 'bool':
    """
    Verification of ZKP for square relation between preimages
    Positional args : tuple(A1, A2), tuple(B1, B2) - ElGamal encryptions
    Keyword args - as below
    """

    try:
        (A1, A2) = args[0]
        (B1, B2) = args[1]
        pid = kwargs['pid']
        pk = kwargs['pubkey']
        (C_a1, C_a2) = kwargs['C_a']
        (C_b1, C_b2) = kwargs['C_b']
        v = kwargs['v']
        z_a = kwargs['z_a']
        z_b = kwargs['z_b']
    except:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)
        sys.exit(1)

    logger.info(
        "Verifying ZKP for square relation for participant id {}".format(pid))

    # generate crs using SHA256
    crs = ''.join(
        [str(_) for _ in [pid, A1, A2, B1, B2, C_a1, C_a2, C_b1, C_b2]])
    c = int(SHA256.new(crs.encode('utf-8')).hexdigest(), 16) % order

    # Canny, step4
    (e1, e2) = elgamal_encrypt(pk, z_a, v * G)
    (f1, f2) = elgamal_encrypt(pk, z_b, 0 * G)

    # check statements
    if e1 != c * A1 + C_a1:
        return False

    if e2 != c * A2 + C_a2:
        return False

    if f1 + v * A1 != c * B1 + C_b1:
        return False

    if f2 + v * A2 != c * B2 + C_b2:
        return False

    # ZKP successful verification
    return True
Exemple #2
0
def gen_prf(*args, **kwargs) -> 'dict':
    """
    Generate proof of square relation between preimages of two ElGamal
    encrytions
    Positional args : tuple(A1, A2), tuple(B1, B2) - ElGamal encryptions
    Keyword args - as below
    """

    try:
        (A1, A2) = args[0]
        (B1, B2) = args[1]
        pid = kwargs['pid']
        s_a = kwargs['secret1']
        s_b = kwargs['secret2']
        a = kwargs['message']
        pk = kwargs['pubkey']
    except:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)
        sys.exit(1)

    logger.info(
        "Generating proof of square relation for participant id {}".format(
            pid))

    # Canny, step1
    x, r_a, r_b = random.randint(0, order), random.randint(
        0, order), random.randint(0, order)
    (C_a1, C_a2) = elgamal_encrypt(pk, r_a, x * G)
    (C_b1, C_b2) = elgamal_encrypt(pk, r_b, 0 * G)
    (C_b1, C_b2) = (C_b1 + x * A1, C_b2 + x * A2)

    # generate crs using SHA256
    crs = ''.join(
        [str(_) for _ in [pid, A1, A2, B1, B2, C_a1, C_a2, C_b1, C_b2]])
    c = int(SHA256.new(crs.encode('utf-8')).hexdigest(), 16) % order

    # Canny, step3
    v = (c * a + x) % order
    z_a = (c * s_a + r_a) % order
    z_b = (c * (s_b - a * s_a) + r_b) % order

    return {
        'C_a': (C_a1, C_a2),
        'C_b': (C_b1, C_b2),
        'v': v,
        'z_a': z_a,
        'z_b': z_b
    }
Exemple #3
0
def gen_prf(*args, **kwargs) -> 'dict':
    """
    Generate proof
    """

    try:
        (x,y) = args[0]
        pid = kwargs['pid']
        v = kwargs['message']
        secret = kwargs['secret']
        pk = kwargs['pubkey']
        b = kwargs['bound']
    except:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)
        sys.exit(1)
    
    logger.info("Generating range ZKP for participant id {}".format(pid))

    # represent the original value in binary form 
    vb_str = "{0:b}".format(v)
    vb = []
    for c in vb_str:
        vb.append(int(c))
    v_new = 0
    L = len(vb)
    for l in range(L):
        v_new += vb[l] * 2**(L - 1 - l)
    assert v_new == v, "{}, {}".format(str(v_new), str(v))

    LB = math.ceil(math.log2(b))
    if L > LB:
    	print('Range Proof: input value {} exceeds bound {}'.format(v, b))
    	sys.exit(1)

    vb_enc = []
    vb_prf = []
    rsum = 0 # the randomness for the weighted sum
    # generate 1 out of 2 proofs
    for l in range(L):
    	bit = vb[l]
    	r = random.randint(0, order)
    	rsum += 2**(L-1-l)*r
    	cbit = elgamal_encrypt(pk, r, bit * G)
    	(c1, c2) = cbit
    	prf = zkp_oneOutOfTwo.gen_prf(c1, c2, pid = pid, message = bit, secret = r, pubkey = pk)
    	vb_enc.append(cbit)
    	vb_prf.append(prf)

    # generate dhtuple proof
    c1sum = I
    c2sum = I
    for l in range(L):
    	c1sum += 2**(L - 1 - l)*vb_enc[l][0]
    	c2sum += 2**(L - 1 - l)*vb_enc[l][1]
    dhtuple = (G, pk, x - c1sum, y - c2sum)
    dhtuple_prf = zkp_dhTuple.gen_prf(dhtuple, pid=pid, secret=secret - rsum)

    return {'zkp01':vb_prf, 'zkp_dhtuple':dhtuple_prf, 'encrypted_bits':vb_enc} 
Exemple #4
0
def simpleElGamal():
    # generate secret-key
    sk = random.randint(0, order)
    pk = sk * G

    # generate secret randomness
    r = random.randint(0, order)

    # message to encrypt
    m = int(42)
    # point on the curve corresponding to the message
    m_point = m * G

    (c1, c2) = elgamal_encrypt(pk, r, m_point)
    logger.info("ElGamal ciphertext: {}, {}".format(c1, c2))

    m_point_decrypt = elgamal_decrypt(sk, c1, c2)
    logger.info("ElGamal decrypted: {}".format(m_point_decrypt))

    # data recovered from ElGamal is a point on the curve. We need to solve
    # the discrete log problem to get the message - exhaustive search or
    # Baby/Giant
    assert m_point_decrypt == m_point

    plaintext = baby_giant(m_point_decrypt)
    print("Plaintext: {}".format(plaintext))
Exemple #5
0
def run():
    # generate secret-key
    sk = random.randint(0, order) 
    pk = sk*G 

    m = int(42)
    m_point = m * G
    r_m = random.randint(0, order) # secret for m

    m_sq = m**2 
    m_sq_point = m_sq * G
    r_m_sq = random.randint(0, order) # secret for m_sq 

    # ElGamal encryptions
    E_m = elgamal_encrypt(pk, r_m, m_point)
    E_m_sq = elgamal_encrypt(pk, r_m_sq, m_sq_point) 

    prf = zkp_square.gen_prf(E_m, E_m_sq, pid=0, secret1=r_m,
            secret2=r_m_sq, message=m, pubkey=pk)

    success = zkp_square.verify_prf(E_m, E_m_sq, pid=0, pubkey=pk, **prf)

    print("ZKP verification %s."%('Passed' if success is True else 'Failed'))
Exemple #6
0
def run():
    # generate secret-key
    sk = random.randint(0, order)
    pk = sk * G

    # message to encrypt
    m = int(1)
    m2 = int(3)
    mmax = 2
    # point on the curve corresponding to the message
    m_point = m * G
    m2_point = m2 * G

    # generate secret randomness
    L = math.ceil(math.log2(mmax))

    c1 = elgamal_encrypt(pk, sk, m_point)
    c2 = elgamal_encrypt(pk, sk, m2_point)
    prf = zkp_range.gen_prf(c1,
                            pid=0,
                            message=m,
                            secret=sk,
                            pubkey=pk,
                            bound=mmax)
    prf2 = zkp_range.gen_prf(c2,
                             pid=1,
                             message=m,
                             secret=sk,
                             pubkey=pk,
                             bound=mmax)
    success = zkp_range.verify_prf(c1, pid=0, pubkey=pk, bound=mmax, **prf)
    success2 = zkp_range.verify_prf(c2, pid=1, pubkey=pk, bound=mmax, **prf2)

    print("ZKP verification 0 %s." %
          ('Passed' if success is True else 'Failed'))
    print("ZKP verification 1 %s." %
          ('Passed' if success2 is True else 'Failed'))
Exemple #7
0
def run():
    # generate secret-key
    sk = random.randint(0, order) 
    pk = sk*G 

    # generate secret randomness
    r = random.randint(0, order)

    # message to encrypt
    m = int(1)
    # point on the curve corresponding to the message
    m_point = m * G

    (c1, c2) = elgamal_encrypt(pk, r, m_point)
    prf = zkp_oneOutOfTwo.gen_prf(c1, c2, pid=0, message=m, secret=r, pubkey=pk)
    success = zkp_oneOutOfTwo.verify_prf(c1, c2, pid=0, pubkey=pk, **prf)

    print("ZKP verification %s."%('Passed' if success is True else 'Failed'))
Exemple #8
0
    def prove(self):
        if (self.ledger.cur_phase != 'p'):
            print("Not in proof phase!")
            return

        # verify zkp for discrete log
        if (not self.check_zkp_discretelog(self.ledger.pk_list,
                                           self.ledger.zkp_discretelog_dict)):
            print("ZKP discrete log validation failed!")
            return

        # compute the encryption of g (equation 2), which cancels after addition; generate range proof for each value of g
        encrypted_g1 = []
        h_list = []
        zkp_range_g1 = []
        for x in range(self.len):
            h = I
            for u in self.ledger.pk_list:
                if (u < self.uid):
                    h += self.ledger.pk_list[u][x]
                elif (u > self.uid):
                    h -= self.ledger.pk_list[u][x]
            h_list.append(h)
            c = elgamal_encrypt(h, self.secrets[x], self.g[x] * G)
            encrypted_g1.append(c)
            prf = zkp_range.gen_prf(c,
                                    pid=str(self.uid) + ":" + str(x),
                                    message=self.g[x],
                                    secret=self.secrets[x],
                                    pubkey=h_list[x],
                                    bound=self.gmax)
            zkp_range_g1.append(prf)
        if (self.ledger.commit_zkp_range(zkp_range_g1, self.uid) == 0):
            print("Failed to upload ZKP of range proof for {}!".format(
                self.uid))
            return

        # compute another encryption of g, which uses the same public key for all values; generate zkp for dhtuple (equation 3)
        encrypted_g2 = []
        zkp_dhtuple_list = []
        for x in range(self.len):
            encrypted_g2.append(
                elgamal_encrypt(self.h, self.secrets[x], self.g[x] * G))
            dhtuple = (G, h_list[x] - self.h, self.secrets[x] * G,
                       encrypted_g1[x][1] - encrypted_g2[x][1])
            prf = zkp_dhTuple.gen_prf(dhtuple,
                                      pid=str(self.uid) + ":" + str(x),
                                      secret=self.secrets[x])
            zkp_dhtuple_list.append(prf)

        if (self.ledger.commit_zkp_dhtuple(self.h, h_list, encrypted_g1,
                                           encrypted_g2, zkp_dhtuple_list,
                                           self.uid) == 0):
            print("Failed to upload ZKP of dhtuple for {}!".format(self.uid))
            return

        # generate range proof for sum
        g_sum = 0
        g_encsum1 = I
        g_encsum2 = I
        g_secsum = 0
        for x in range(self.len):
            g_sum += self.g[x]
            g_encsum1 += encrypted_g2[x][0]
            g_encsum2 += encrypted_g2[x][1]
            g_secsum += self.secrets[x]
        g_encsum = (g_encsum1, g_encsum2)
        zkp_sumRange = zkp_range.gen_prf(g_encsum,
                                         pid=str(self.uid),
                                         message=g_sum,
                                         secret=g_secsum,
                                         pubkey=self.h,
                                         bound=self.bound)
        if (self.ledger.commit_zkp_sumRange(zkp_sumRange, self.uid) == 0):
            print("Failed to upload ZKP of sum range for {}!".format(self.uid))
            return
Exemple #9
0
    def prove(self):
        if (self.ledger.cur_phase != 'p'):
            print("Not in proof phase!")
            return

        # verify zkp for discrete log
        all_pk_list = self.ledger.pk_list
        if (not self.check_zkp_discretelog(all_pk_list,
                                           self.ledger.zkp1_dict)):
            print("ZKP discrete log validation failed!")
            return

        # compute the encryption of g (equation 2)
        encrypted_g1 = []
        h_list = []
        for x in range(self.len):
            h = I
            for u in all_pk_list:
                if (u < self.uid):
                    h += all_pk_list[u][x]
                elif (u > self.uid):
                    h -= all_pk_list[u][x]
            h_list.append(h)
            encrypted_g1.append(
                elgamal_encrypt(h, self.sk_list[x], self.g[x] * G))

        # compute another encryption of g, generate zkp for dhtuple (equation 3)
        encrypted_g2 = []
        zkp_dhtuple_list = []
        for x in range(self.len):
            encrypted_g2.append(
                elgamal_encrypt(self.h, self.sk_list[x], self.g[x] * G))
            dhtuple = (G, h_list[x] - self.h, self.pk_list[x],
                       encrypted_g1[x][1] - encrypted_g2[x][1])
            prf = zkp_dhTuple.gen_prf(dhtuple,
                                      pid=str(self.uid) + ":" + str(x),
                                      secret=self.sk_list[x])
            zkp_dhtuple_list.append(prf)

        if (self.ledger.zkp2(self.h, h_list, encrypted_g1, encrypted_g2,
                             zkp_dhtuple_list, self.uid) == 0):
            print("Failed to upload ZKP of dhtuple for {}!".format(self.uid))
            return

        # generate square vector and its binary representation
        w = []
        s = 0
        for x in range(self.len):
            w.append(self.g[x]**2)
            s += w[x]
        sb_str = "{0:b}".format(s)
        sb = []
        for c in sb_str:
            sb.append(int(c))
        s_new = 0
        L = len(sb)
        for x in range(L):
            s_new += sb[x] * 2**(L - 1 - x)
        assert s_new == s, "{}, {}".format(str(s_new), str(s))

        # encrypt the binary representation (equation 6), and generate zkp01 for each binary value
        encrypted_sb = []
        r_list_sb = []
        zkp01 = []
        for x in range(L):
            r_sb = random.randint(0, order)
            e_sb = elgamal_encrypt(self.h, r_sb, sb[x] * G)
            (c1, c2) = e_sb
            prf = zkp_oneOutOfTwo.gen_prf(c1,
                                          c2,
                                          pid=str(self.uid) + ":" + str(x),
                                          message=sb[x],
                                          secret=r_sb,
                                          pubkey=self.h)
            r_list_sb.append(r_sb)
            encrypted_sb.append(e_sb)
            zkp01.append(prf)
        if (self.ledger.zkp3(encrypted_sb, zkp01, self.uid) == 0):
            print("Failed to upload ZKP01 for {}!".format(self.uid))
            return

        # generate randomness for w and encrypt w (equation 7, equation 8)
        r_list_w = []
        encrypted_w = []
        zkp_square_list = []
        for x in range(self.len):
            r_w = random.randint(0, order)
            r_list_w.append(r_w)
        sum_rw = 0
        sum_rw_new = 0
        for x in range(self.len):
            r_w = 0
            for y in range(self.len):
                if (y < x):
                    r_w += r_list_w[y]
                elif (y > x):
                    r_w -= r_list_w[y]
            r_w *= r_list_w[x]
            if (x < L):
                r_w_new = r_w + r_list_sb[x] * 2**(L - 1 - x)
            else:
                r_w_new = r_w
            sum_rw += r_w
            sum_rw_new += r_w_new
            e_w = elgamal_encrypt(self.h, r_w_new, w[x] * G)
            prf = zkp_square.gen_prf(encrypted_g2[x],
                                     e_w,
                                     pid=str(self.uid) + ":" + str(x),
                                     secret1=self.sk_list[x],
                                     secret2=r_w_new,
                                     message=self.g[x],
                                     pubkey=self.h)
            encrypted_w.append(e_w)
            zkp_square_list.append(prf)
        if (self.ledger.zkp4(encrypted_w, zkp_square_list, self.uid) == 0):
            print("Failed to upload ZKP square for {}".format(self.uid))

        assert sum_rw == 0, "sum_rw = {}".format(sum_rw)
        sum_e_w = I
        sum_e_sb = I
        for x in range(self.len):
            sum_e_w += encrypted_w[x][1]
        for x in range(L):
            sum_e_sb += encrypted_sb[x][1] * 2**(L - 1 - x)
        assert (sum_e_w == sum_e_sb), "check sum failed"