예제 #1
0
 def reenc_return_r(self):
     """
     Reencryption with fresh randomness, which is returned.
     """
     r = random.mpz_lt(self.pk.q)
     new_c = self.reenc_with_r(r)
     return [new_c, r]
예제 #2
0
    def encrypt_return_r(self, plaintext):
        """
        Encrypt a plaintext and return the randomness just generated and used.
        """
        r = random.mpz_lt(self.q)
        ciphertext = self.encrypt_with_r(plaintext, r)

        return [ciphertext, r]
예제 #3
0
    def generate(self, p, q, g):
        """
        Generate an ElGamal keypair
        """
        self.pk.g = g
        self.pk.p = p
        self.pk.q = q

        self.sk.x = random.mpz_lt(q)
        self.pk.y = pow(g, self.sk.x, p)

        self.sk.public_key = self.pk
예제 #4
0
    def prove_sk(self, challenge_generator):
        """
        Generate a PoK of the secret key
        Prover generates w, a random integer modulo q, and computes commitment = g^w mod p.
        Verifier provides challenge modulo q.
        Prover computes response = w + x*challenge mod q, where x is the secret key.
        """
        w = random.mpz_lt(self.pk.q)
        commitment = pow(self.pk.g, w, self.pk.p)
        challenge = challenge_generator(commitment) % self.pk.q
        response = (w + (self.x * challenge)) % self.pk.q

        return DLogProof(commitment, challenge, response)
예제 #5
0
    def simulate_encryption_proof(self, plaintext, challenge=None):
        # generate a random challenge if not provided
        if not challenge:
            challenge = random.mpz_lt(self.pk.q)

        proof = ZKProof()
        proof.challenge = challenge

        # compute beta/plaintext, the completion of the DH tuple
        beta_over_plaintext = (self.beta *
                               inverse(plaintext.m, self.pk.p)) % self.pk.p

        # random response, does not even need to depend on the challenge
        proof.response = random.mpz_lt(self.pk.q)

        # now we compute A and B
        proof.commitment["A"] = (
            inverse(pow(self.alpha, proof.challenge, self.pk.p), self.pk.p) *
            pow(self.pk.g, proof.response, self.pk.p)) % self.pk.p
        proof.commitment["B"] = (inverse(
            pow(beta_over_plaintext, proof.challenge, self.pk.p),
            self.pk.p) * pow(self.pk.y, proof.response, self.pk.p)) % self.pk.p

        return proof
예제 #6
0
    def generate_encryption_proof(self, plaintext, randomness,
                                  challenge_generator):
        """
        Generate the disjunctive encryption proof of encryption
        """
        # random W
        w = random.mpz_lt(self.pk.q)

        # build the proof
        proof = ZKProof()

        # compute A=g^w, B=y^w
        proof.commitment["A"] = pow(self.pk.g, w, self.pk.p)
        proof.commitment["B"] = pow(self.pk.y, w, self.pk.p)

        # generate challenge
        proof.challenge = challenge_generator(proof.commitment)

        # Compute response = w + randomness * challenge
        proof.response = (w + (randomness * proof.challenge)) % self.pk.q

        return proof
예제 #7
0
    def prove_decryption(self, ciphertext):
        """
        given g, y, alpha, beta/(encoded m), prove equality of discrete log
        with Chaum Pedersen, and that discrete log is x, the secret key.

        Prover sends a=g^w, b=alpha^w for random w
        Challenge c = sha1(a,b) with and b in decimal form
        Prover sends t = w + xc

        Verifier will check that g^t = a * y^c
        and alpha^t = b * beta/m ^ c
        """

        m = (inverse(pow(ciphertext.alpha, self.x, self.pk.p), self.pk.p) *
             ciphertext.beta) % self.pk.p
        beta_over_m = (ciphertext.beta * inverse(m, self.pk.p)) % self.pk.p

        # pick a random w
        w = random.mpz_lt(self.pk.q)
        a = pow(self.pk.g, w, self.pk.p)
        b = pow(ciphertext.alpha, w, self.pk.p)

        c = int(
            SHA1.new(bytes(str(a) + "," + str(b), "utf-8")).hexdigest(), 16)

        t = (w + self.x * c) % self.pk.q

        return (
            m,
            {
                "commitment": {
                    "A": str(a),
                    "B": str(b)
                },
                "challenge": str(c),
                "response": str(t),
            },
        )
예제 #8
0
    def generate(cls, little_g, little_h, x, p, q, challenge_generator):
        """
        generate a DDH tuple proof, where challenge generator is
        almost certainly EG_fiatshamir_challenge_generator
        """

        # generate random w
        w = random.mpz_lt(q)

        # create proof instance
        proof = cls()

        # compute A = little_g^w, B=little_h^w
        proof.commitment["A"] = pow(little_g, w, p)
        proof.commitment["B"] = pow(little_h, w, p)

        # get challenge
        proof.challenge = challenge_generator(proof.commitment)

        # compute response
        proof.response = (w + (x * proof.challenge)) % q

        # return proof
        return proof