示例#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 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)
        }
示例#3
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]
示例#4
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
示例#5
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)
示例#6
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
示例#7
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
示例#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