예제 #1
0
    def simulate_proof(self, challenge=None, *args, **kwargs):
        # Simulate the n-1 first subproofs, computes the complementary challenge and
        # simulates the last proof using this challenge.
        if challenge is None:
            challenge = get_random_num(bits=CHALLENGE_LENGTH)
        com = []
        resp = []
        or_chals = []
        precom = []

        # Generate one simulation at a time and update a list of each attribute.
        for index, subproof in enumerate(self.subproofs[:-1]):
            transcript = subproof.simulate_proof()
            com.append(transcript.commitment)
            resp.append(transcript.responses)
            or_chals.append(transcript.challenge)
            precom.append(transcript.precommitment)

        # Generate the last simulation.
        final_chal = _find_residual_challenge(or_chals, challenge,
                                              CHALLENGE_LENGTH)
        or_chals.append(final_chal)
        final_transcript = self.subproofs[index + 1].simulate_proof(
            challenge=final_chal)
        com.append(final_transcript.commitment)
        resp.append(final_transcript.responses)
        precom.append(final_transcript.precommitment)

        # Pack everything into a SimulationTranscript, pack the or-challenges in the response field.
        return SimulationTranscript(
            commitment=com,
            challenge=challenge,
            responses=(or_chals, resp),
            precommitment=precom,
        )
예제 #2
0
def ZK_equality(G,H):

##Generate two El-Gamal ciphertexts (C1,C2) and (D1,D2)
    # Setup: generate secret randomizers.    
    # m is the secret bit.
    m = Secret(utils.get_random_num(bits=2))
    r1 = Secret(utils.get_random_num(bits=128))
    r2 = Secret(utils.get_random_num(bits=128))

    C1 = r1.value*G
    #print("this is C1:", C1)
    C2 = r1.value * H + m.value * G
    D1 = r2.value * G
    D2 = r2.value * H + m.value * G
    
##Generate a NIZK proving equality of the plaintexts 

    stmt = DLRep(C1,r1*G) & DLRep(C2,r1*H+m*G) & DLRep(D1,r2*G) & DLRep(D2,r2*H+m*G)
    zk_proof = stmt.prove()
    
    #Return two ciphertexts and the proof
    return (C1,C2), (D1,D2), zk_proof
예제 #3
0
def test_statement_zk_proof() -> None:
    vm = sy.VirtualMachine()
    client = vm.get_root_client()

    sy.load("zksk")

    # third party
    from zksk import DLRep
    from zksk import Secret
    from zksk import utils

    num = 2
    seed = 42
    num_sy = sy.lib.python.Int(num)
    seed_sy = sy.lib.python.Int(seed)

    # Setup: Peggy and Victor agree on two group generators.
    G, H = utils.make_generators(num=num, seed=seed)
    # Setup: generate a secret randomizer.
    r = Secret(utils.get_random_num(bits=128))

    # This is Peggy's secret bit.
    top_secret_bit = 1

    # A Pedersen commitment to the secret bit.
    C = top_secret_bit * G + r.value * H

    # Peggy's definition of the proof statement, and proof generation.
    # (The first or-clause corresponds to the secret value 0, and the second to the value 1. Because
    # the real value of the bit is 1, the clause that corresponds to zero is marked as simulated.)
    stmt = DLRep(C, r * H, simulated=True) | DLRep(C - G, r * H)
    zk_proof = stmt.prove()

    # send over the network and get back
    num_ptr = num_sy.send(client)
    seed_prt = seed_sy.send(client)
    c_ptr = C.send(client)
    zk_proof_ptr = zk_proof.send(client)

    num2 = num_ptr.get().upcast()
    seed2 = seed_prt.get().upcast()
    C2 = c_ptr.get()
    zk_proof2 = zk_proof_ptr.get()

    # Setup: get the agreed group generators.
    G, H = utils.make_generators(num=num2, seed=seed2)
    # Setup: define a randomizer with an unknown value.
    r = Secret()

    stmt = DLRep(C2, r * H) | DLRep(C2 - G, r * H)
    assert stmt.verify(zk_proof2)
예제 #4
0
파일: base.py 프로젝트: spring-epfl/zksk
    def send_challenge(self, commitment):
        """
        Store the received commitment and generate a challenge.

        The challenge is chosen at random between 0 and ``CHALLENGE_LENGTH`` (excluded).

        Args:
            commitment: A tuple containing a hash of the stmt statement, to be
                compared against the local statement, and the commmitment as a
                (potentially multi-level list of) base(s) of the group.
        """
        statement, self.commitment = commitment
        self.stmt.check_statement(statement)
        self.challenge = get_random_num(bits=CHALLENGE_LENGTH)
        return self.challenge
예제 #5
0
    def simulate_proof(self, responses_dict=None, challenge=None):
        """
        Returns a transcript of a proof simulation. Responses and challenge can be enforced.  The
        function will misbehave if passed a non-empty but incomplete responses_dict.

        Args:
            responses_dict: Optinal mapping from secrets or secret names to responses.
            challenge: Optional challenge to use in the simulation
        """
        # Fill the missing positions of the responses dictionary
        responses_dict = self.update_randomizers(responses_dict)
        if challenge is None:
            challenge = get_random_num(CHALLENGE_LENGTH)

        responses = [responses_dict[m] for m in self.secret_vars]
        # Random responses, the same for shared secrets
        commitment = self.recompute_commitment(challenge, responses)

        return SimulationTranscript(commitment=commitment,
                                    challenge=challenge,
                                    responses=responses)
예제 #6
0
    def send_challenge(self, commitment, ignore_statement_hash_checks=False):
        """
        Store the received commitment and generate a challenge.

        Additionally checks the received hashed statement matches the one of the current proof. Only
        called at the highest level or in extended proofs.

        Args:
            commitment: A tuple (statement, actual_commitment) with
                actual_commitment a list of commitments, one for each subproof.
            ignore_statement_hash_checks: Optional parameter to deactivate the
                statement check. In this case, the commitment parameter is
                simply the actual commitment. Useful in 2-level proofs for which
                we don't check the inner statements.
        """
        if ignore_statement_hash_checks:
            self.commitment = commitment
        else:
            statement, self.commitment = commitment
            self.stmt.check_statement(statement)
        self.challenge = get_random_num(CHALLENGE_LENGTH)
        return self.challenge
예제 #7
0
def test_nizk_serde() -> None:
    vm = sy.VirtualMachine()
    client = vm.get_root_client()

    # third party
    from zksk import DLRep
    from zksk import Secret
    from zksk import utils

    sy.load("zksk")

    num = 2
    seed = 42
    G, H = utils.make_generators(num=num, seed=seed)
    # Setup: generate a secret randomizer.
    r = Secret(utils.get_random_num(bits=128))

    # This is Peggy's secret bit.
    top_secret_bit = 1

    # A Pedersen commitment to the secret bit.
    C = top_secret_bit * G + r.value * H

    # Peggy's definition of the proof statement, and proof generation.
    # (The first or-clause corresponds to the secret value 0, and the second to the value 1. Because
    # the real value of the bit is 1, the clause that corresponds to zero is marked as simulated.)
    stmt = DLRep(C, r * H, simulated=True) | DLRep(C - G, r * H)

    # zksk.base.NIZK
    zk_proof = stmt.prove()

    # test serde
    zk_proof_ptr = zk_proof.send(client)
    zk_proof2 = zk_proof_ptr.get()

    assert zk_proof == zk_proof2
예제 #8
0
    def simulate_proof(self, responses_dict=None, challenge=None):
        """
        Simulate the And proof

        To do so, draw a global challenge, a global dictionary of responses (for consistency) and
        simulate each subproof.

        Gathers the commitments, and pack everything into a :py:class:`base.SimulationTranscript`.

        Args:
            responses_dict: A dictionary of responses to override (could come from an upper And
                Proof, for example). Draw randomly if None.
            challenge: The challenge to use in the proof. Draw one if None.
        """
        # Fill the missing positions of the responses dictionary
        responses_dict = self.update_randomizers(responses_dict)

        if challenge is None:
            challenge = get_random_num(CHALLENGE_LENGTH)
        com = []
        resp = []
        precom = []

        # Simulate all subproofs and gather their attributes, repack them in a unique
        # SimulationTranscript.
        for sub in self.subproofs:
            simulation = sub.simulate_proof(challenge=challenge,
                                            responses_dict=responses_dict)
            com.append(simulation.commitment)
            resp.append(simulation.responses)
            precom.append(simulation.precommitment)

        return SimulationTranscript(commitment=com,
                                    challenge=challenge,
                                    responses=resp,
                                    precommitment=precom)