Beispiel #1
0
    def prove_decrypt_batched(self, ciphertext_batch):
        """Batched version of `prove_decrypt()`

        Arguments:
            ciphertext_batch (list): the ciphertexts (PaillierCiphertext) to be
                decrypted in a verifiable manner

        Returns:
            tuple: `partial_decryption_batch`, `proof` where
            `partial_decryption_batch` is a list of the partial decryptions
            (int) of the ciphertexts, and `proof` is a proof (int) that they
            are indeed so
        """
        pk = self.public_key
        partial_decryption_batch = [
            self.decrypt(ciphertext) for ciphertext in ciphertext_batch
        ]

        # run protocol in the Fiat-Shamir heuristic

        # to aggregate ZKPs, the verifier provides λ_i *after* the plaintexts
        # have been provided; then combined_ciphertext = ∏ ciphertext^{λ_i}
        # and combined_plaintext = ∏ m^{λ_i} (not needed for prover)
        lambda_batch = [
            util.H([ciphertext.raw_value, partial_decryption])
            for ciphertext, partial_decryption in zip(
                ciphertext_batch, partial_decryption_batch)
        ]
        combined_plaintext = util.prod(
            util.powmod(plaintext, lambda_, pk.n) for plaintext, lambda_ in
            zip(partial_decryption_batch, lambda_batch))
        combined_ciphertext = util.prod(
            util.powmod(ciphertext.raw_value, lambda_, pk.n)
            for ciphertext, lambda_ in zip(ciphertext_batch, lambda_batch))

        try:
            # raises IndexError if not enough precomputations were forecast
            r, t1 = self.precomputed_values.pop()
        except AttributeError:
            # no pre-computations
            r = random.SystemRandom().randrange(pk.n <<
                                                (2 * pk.security_parameter))
            t1 = util.powmod(self.verification_base, r, pk.n)

        # prove knowledge of key_share such that:
        #   * v_i = v**key_share
        #   * combined_plaintext**2 = (combined_ciphertext**2)**(2*key_share)
        t2 = util.powmod(combined_ciphertext, _CP * _QR * r, pk.n)
        h = util.H([
            combined_ciphertext,
            combined_plaintext,
            t1,
            self.verification_base,
            self.verification,
            t2,
        ])
        w = r + h * self.key_share
        proof = t1, t2, w
        return partial_decryption_batch, proof
Beispiel #2
0
def f2(pa):  # called after getting (s, B)
    B, I, s, v, g, a, A = int(pa[0][1]), pa[1], int(
        pa[0][0]), pa[3], pa[4], pa[5], pa[6]
    u = util.H([A, B]) % util.N
    x = util.H(list(itertools.chain([ord(c) for c in util.p], [s])))
    Kclient = pow((B - util.k * v), a + u * x, util.N)
    pa.append(Kclient)
    m1 = util.H([A, B, Kclient])
    pa.append(m1)
    pa[0] = [m1]
    return pa
Beispiel #3
0
def check_challenge(m1, clientMap):
    # m1 - client's response, assuming just 1 client and called in right order
    for key in clientMap:
        m = clientMap[key]
        A = m[2]
        v = m[1]
        b = m[3]
        B = m[5]
        u = util.H([A, B]) % util.N
        Kserv = pow(A * (pow(v, u, util.N)), b, util.N)
        m[4] = Kserv
        m0 = util.H([A, B, Kserv])
        return int(m1[0]) == m0
    return None
Beispiel #4
0
    def verify_decrypt_batched(self, ciphertext_batch,
                               partial_decryption_batch, proof):
        """Batched version of `verify_decrypt()`

        Arguments:
            ciphertext_batch (list): the ciphertexts (PaillierCiphertext) to be
                decrypted in a verifiable manner
            partial_decryption_batch (list): the corresponding partial
                decryptions (int)
            proof: a proof that each element of `partial_decryption_batch` is
                indeed a partial decryption of the corresponding element in
                `ciphertext_batch` under the secret key corresponding to self
        """
        pk = self.public_key

        # run protocol in the Fiat-Shamir heuristic
        t1, t2, w = proof

        # generate random λ_i *after* decryption shares have been provided
        lambda_batch = [
            util.H([ciphertext.raw_value, partial_decryption])
            for ciphertext, partial_decryption in zip(
                ciphertext_batch, partial_decryption_batch)
        ]

        # compute combined plaintext and ciphertext for verification
        combined_plaintext = util.prod(
            util.powmod(plaintext, lambda_, pk.n) for plaintext, lambda_ in
            zip(partial_decryption_batch, lambda_batch))
        combined_ciphertext = util.prod(
            util.powmod(ciphertext.raw_value, lambda_, pk.n)
            for ciphertext, lambda_ in zip(ciphertext_batch, lambda_batch))
        h = util.H([
            combined_ciphertext,
            combined_plaintext,
            t1,
            self.verification_base,
            self.verification,
            t2,
        ])

        # verify proof
        # check that v^s = t_1 * v_i^c
        if util.powmod(self.verification_base, w, pk.n) != \
                t1 * util.powmod(self.verification, h, pk.n) % pk.n:
            raise InvalidProof
        # check that (x^2)^s = t_2 * (m^2)^c
        if util.powmod(combined_ciphertext, _CP*_QR*w, pk.n) != \
                t2 * util.powmod(combined_plaintext, _CP*h, pk.n) % pk.n:
            raise InvalidProof
Beispiel #5
0
    def verify_decrypt(self, ciphertext, partial_decryption, proof):
        """Check the proof of decryption of the corresponding secret key

        Arguments:
            ciphertext (PaillierCiphertext): the ciphertext to be decrypted in
                a verifiable manner
            partial_decryption (int): the corresponding partial decryption
            proof (int): a proof that `partial_decryption` is indeed a partial
                decryption of `ciphertext` under the corresponding secret key
        """

        pk = self.public_key

        # run Chaum-Pedersen protocol in the Fiat-Shamir heuristic
        t1, t2, w = proof
        h = util.H([
            ciphertext.raw_value,
            partial_decryption,
            t1,
            self.verification_base,
            self.verification,
            t2,
        ])

        # verify proof
        # check that v^s = t_1 * v_i^c
        if util.powmod(self.verification_base, w, pk.n) != \
                t1 * util.powmod(self.verification, h, pk.n) % pk.n:
            raise InvalidProof
        # check that (x^2)^s = t_2 * (m^2)^c
        if util.powmod(ciphertext.raw_value, _CP*_QR*w, pk.n) != \
                t2 * util.powmod(partial_decryption, _CP*h, pk.n) % pk.n:
            raise InvalidProof
Beispiel #6
0
def Verify(m, p, q, g, pubKey, r, s):
    # 驗證簽章
    assert r >= 0 and r < q and s >= 0 and s < q
    w = util.ModInv(s, q)
    u1 = (util.H(m) * w) % q
    u2 = (r * w) % q
    v = ((util.SQandMU(g, u1, p) * util.SQandMU(pubKey, u2, p)) % p) % q
    return v % q == r % q
Beispiel #7
0
def f0(
    pa
):  # NOTE: The first element in the returned array will be used for sending and receiving server messages.
    util.q, util.N, util.g, util.k, util.nL = int(pa[0][0]), int(
        pa[0][1]), int(pa[0][2]), int(pa[0][3]), int(pa[0][4])
    s = util.getSalt()
    x = util.H(list(itertools.chain([ord(c) for c in util.p], [s])))
    v = pow(util.g, x, util.N)
    del x
    return [(util.I, s, v), util.I, s, v, util.g]
Beispiel #8
0
def f3(pa):
    global fmt
    fmt = ""
    m2, A, Kclient, m1 = pa[0], pa[6], pa[-2], pa[-1]
    if util.H([A, m1, Kclient]) == int(m2[0]):
        print("Client: Success")
        pa[0] = [util.encryptFile(plaintext_filename, Kclient)]
        return pa[0]
    else:
        print("Client: Not Success")
        exit(1)
Beispiel #9
0
    def verify_private_multiply_batched(self, cx, cy_list, cz_list, proof):
        """Check the proof of multiplication of a ciphertext with a plaintext

        Arguments:
            cx (PaillierCiphertext): the encrypted left operand
            cy_list (list): the encrypted right operands (PaillierCiphertext)
            cz_list (list): the encrypted products (PaillierCiphertext) of x*y
                for each y in `cy_list`
            proof (int): a proof that z = x*y for each y, z in cy_list, cz_list
        """
        n2 = self.nsquare

        # generate random λ_i *after* ciphertexts have been provided
        cu, cyu, w, rs, rys = proof
        lambda_list = [
            util.H([cx, cy, cz]) for cy, cz in zip(cy_list, cz_list)
        ]

        # compute combined ciphertexts
        cy = util.prod(
            util.powmod(cy, lambda_, self.nsquare)
            for cy, lambda_ in zip(cy_list, lambda_list))
        cz = util.prod(
            util.powmod(cz, lambda_, self.nsquare)
            for cz, lambda_ in zip(cz_list, lambda_list))

        # run private multiply protocol in the Fiat-Shamir heuristic
        h = util.H([cx, cy, cz, cu, cyu])

        # verify proofs
        cs, _ = self.raw_multiply(self.g, w, rs)  # ⟦s⟧ = ⟦u + xe⟧
        cys, _ = self.raw_multiply(cy, w, rys)  # ⟦ys⟧ = ⟦y(u + xe)⟧
        # ⟦u⟧ * ⟦x⟧**e = ⟦u + xe⟧ = ⟦s⟧
        if cs != cu * util.powmod(cx, h, n2) % n2:
            raise InvalidProof
        # ⟦yu⟧ * ⟦z⟧**e = ⟦yu + yxe⟧ = ⟦ys⟧
        if cys != cyu * util.powmod(cz, h, n2) % n2:
            raise InvalidProof
Beispiel #10
0
def Sign(m, p, q, g, priKey):
    # 簽章
    r, s = 0, 0
    while 1:
        k = random.randrange(1, q)
        r = util.SQandMU(g, k, p) % q
        if (r == 0):
            continue
            # 發生R=0的情況,試另一組k
        dk = util.ModInv(k, q)
        s = (dk * (util.H(m) + priKey * r)) % q
        if (s != 0):
            break
    return r, s
Beispiel #11
0
    def verify_knowledge(self, proof):
        """Check the proof of knowledge of the corresponding secret key

        Arguments:
            proof (int): a proof of knowledge of the secret key
        """
        pk = self.public_key

        # run Schnorr protocol in the Fiat-Shamir heuristic
        t, w = proof
        h = util.H([self.verification_base, self.verification, t])

        # verify proof
        if util.powmod(self.verification_base, w, pk.n) != \
                t * util.powmod(self.verification, h, pk.n) % pk.n:
            raise InvalidProof
Beispiel #12
0
    def prove_private_multiply(self, x, cy):
        """Multiply a ciphertext with a plaintext in a verifiable manner

        Arguments:
            x (int): the clear operand
            cy (PaillierCiphertext): the encrypted operand

        Returns:
            tuple: `cx`, `cz`, `proof` where `cx` is an encryption
            (PaillierCiphertext) of x, `cz` is an encryption
            (PaillierCiphertext) of x*y and `proof` is a proof (int)
            that z = x * y
        """
        n2 = self.nsquare

        # precomputable values
        try:
            # raises IndexError if not enough precomputations were forecast
            x_, (cx, rx), u, (cu, ru) = self.precomputed_values.pop()
        except AttributeError:
            # no pre-computations
            u = random.SystemRandom().randrange(self.n)
            cx, rx = self.raw_multiply(self.g, x)  # ⟦x⟧
            cu, ru = self.raw_multiply(self.g, u)  # ⟦u⟧
        else:
            # ensure consistency with arguments
            if x is None:
                x = x_
            elif x != x_:
                raise ValueError

        # other encrypted values
        cz, rz = self.raw_multiply(cy, x)  # ⟦z⟧ = ⟦xy⟧
        cyu, ryu = self.raw_multiply(cy, u)  # ⟦yu⟧

        # run protocol in the Fiat-Shamir heuristic
        h = util.H([cx, cy, cz, cu, cyu])
        rs = ru * util.powmod(rx, h, self.n) % self.n
        rys = ryu * util.powmod(rz, h, self.n) % self.n
        w = u + x * h
        proof = cu, cyu, w, rs, rys

        return cx, cz, proof
Beispiel #13
0
    def prove_decrypt(self, ciphertext):
        """(Partially) decrypt a ciphertext in a verifiable manner

        Arguments:
            ciphertext (PaillierCiphertext): the ciphertext to be decrypted

        Returns:
            tuple: `partial_decryption`, `proof` where `partial_decryption` is
            the partial decryption (int) of the ciphertext, and `proof` is a
            proof (int) that it is indeed so
        """
        pk = self.public_key
        partial_decryption = self.decrypt(ciphertext)

        try:
            # raises IndexError if not enough precomputations were forecast
            r, t1 = self.precomputed_values.pop()
        except AttributeError:
            # no pre-computations
            r = random.SystemRandom().randrange(pk.n <<
                                                (2 * pk.security_parameter))
            t1 = util.powmod(self.verification_base, r, pk.n)

        # prove knowledge of key_share such that:
        #   * v_i = v**key_share
        #   * (partial_decryption**2) = (ciphertext**2)**(2*key_share)
        t2 = util.powmod(ciphertext.raw_value, _CP * _QR * r, pk.n)

        # run Chaum-Pedersen protocol in the Fiat-Shamir heuristic
        h = util.H([
            ciphertext.raw_value,
            partial_decryption,
            t1,
            self.verification_base,
            self.verification,
            t2,
        ])
        w = r + h * self.key_share
        proof = t1, t2, w
        return partial_decryption, proof
Beispiel #14
0
    def prove_knowledge(self):
        """Proves knowldege of the secret key share

        Returns:
            int: the proof
        """
        pk = self.public_key

        try:
            # raises IndexError if not enough precomputations were forecast
            r, t = self.precomputed_values.pop()
        except AttributeError:
            # no pre-computations
            r = random.SystemRandom().randrange(pk.n <<
                                                (2 * pk.security_parameter))
            t = util.powmod(self.verification_base, r, pk.n)

        # run Schnorr protocol in the Fiat-Shamir heuristic
        h = util.H([self.verification_base, self.verification, t])
        w = r + h * self.key_share
        proof = t, w
        return proof
Beispiel #15
0
    def verify_private_multiply(self, cx, cy, cz, proof):
        """Check the proof of multiplication of a ciphertext with a plaintext

        Arguments:
            cx (int): the encrypted left operand
            cy (int): the encrypted right operand
            cz (int): the encrypted result
            proof (int): a proof that z = x*y
        """
        n2 = self.nsquare

        # run protocol in the Fiat-Shamir heuristic
        cu, cyu, w, rs, rys = proof
        h = util.H([cx, cy, cz, cu, cyu])

        # verify proofs
        cs, _ = self.raw_multiply(self.g, w, rs)  # ⟦s⟧ = ⟦u + xe⟧
        cys, _ = self.raw_multiply(cy, w, rys)  # ⟦ys⟧ = ⟦y(u + xe)⟧
        # ⟦u⟧ * ⟦x⟧**e = ⟦u + xe⟧ = ⟦s⟧
        if cs != cu * util.powmod(cx, h, n2) % n2:
            raise InvalidProof
        # ⟦yu⟧ * ⟦z⟧**e = ⟦yu + yxe⟧ = ⟦ys⟧
        if cys != cyu * util.powmod(cz, h, n2) % n2:
            raise InvalidProof
Beispiel #16
0
def auth_successful(m1, clientMap):
    for key in clientMap:
        m = clientMap[key]
        return util.numbersToByteArr([util.H([m[2], int(m1[0]), m[4]])])
    return None
Beispiel #17
0
    def prove_private_multiply_batched(self, x, cy_list):
        """Multiply a secret with several ciphertexts in a verifiable manner

        Arguments:
            x (int): the secret operand (plaintext)
            cy_list (list): the list of encrypted operands (PaillierCiphertext)

        Returns:
            tuple: `cx`, `cz_list`, `proof` where `cx` is an encryption
            (PaillierCiphertext) of x, `cz_list` is a list of encryptions
            (PaillierCiphertext) of x*y for each y in `cy_list`, and `proof`
            (int) is a proof that z = x*y for each y, z in cy_list, cz_list
        """
        n2 = self.nsquare

        # precomputable values
        try:
            # raises IndexError if not enough precomputations were forecast
            x_, (cx, rx), u, (cu, ru) = self.precomputed_values.pop()
        except AttributeError:
            # no pre-computations
            u = random.SystemRandom().randrange(self.n)
            cx, rx = self.raw_multiply(self.g, x)  # ⟦x⟧
            cu, ru = self.raw_multiply(self.g, u)  # ⟦u⟧
        else:
            # ensure consistency with arguments
            if x is None:
                x = x_
            elif x != x_:
                raise ValueError

        # encrypted result
        cz_rz_list = [self.raw_multiply(cy, x) for cy in cy_list]  # ⟦z⟧ = ⟦xy⟧
        cz_list = [cz for cz, rz in cz_rz_list]
        rz_list = [rz for cz, rz in cz_rz_list]

        lambda_list = [
            util.H([cx, cy, cz]) for cy, cz in zip(cy_list, cz_list)
        ]

        # compute combined ciphertexts
        cy = util.prod(
            util.powmod(cy, lambda_, self.nsquare)
            for cy, lambda_ in zip(cy_list, lambda_list))
        cz = util.prod(
            util.powmod(cz, lambda_, self.nsquare)
            for cz, lambda_ in zip(cz_list, lambda_list))
        rz = util.prod(
            util.powmod(rz, lambda_, self.n)
            for rz, lambda_ in zip(rz_list, lambda_list))

        # other encrypted values
        cyu, ryu = self.raw_multiply(cy, u)  # ⟦yu⟧

        # run private multiply protocol in the Fiat-Shamir heuristic
        h = util.H([cx, cy, cz, cu, cyu])
        rs = ru * util.powmod(rx, h, self.n) % self.n
        rys = ryu * util.powmod(rz, h, self.n) % self.n
        w = u + x * h
        proof = cu, cyu, w, rs, rys

        return cx, cz_list, proof
Beispiel #18
0
def register():
    s = random.randrange(1000,
                         9999)  # needs to be cryptographically suitable random
    x = util.H(list(itertools.chain([ord(c) for c in util.p], [s])))
    v = pow(util.g, x, util.N)