示例#1
0
文件: bbsplus.py 项目: zpleefly/zksk
    def commit(self, messages, zkp=True):
        """
        Construct the product of messages and optionaly a Pedersen commitment and its proof.

        Args:
            messages: Messages (attributes) to commit to
            zkp (bool): Whether to construct a Pedersen commitment and proof the knowledge of the
                messages for this commitment.

        Returns:
            :py:class:`UserCommitmentMessage`: user's packed commitment.
        """
        lhs = self.pk.generators[0].group.wsum(
            messages, self.pk.generators[2 : len(messages) + 2]
        )
        com_nizk_proof = None
        if zkp:
            self.s1 = self.pk.generators[0].group.order().random()
            lhs = self.s1 * self.pk.generators[1] + lhs

            # TODO: Extract into a separate ExtendedProofStmt.
            secret_vars = [Secret() for _ in range(len(messages) + 1)]
            secrets = [self.s1] + messages
            rhs = wsum_secrets(secret_vars, self.pk.generators[1 : len(messages) + 2])
            com_stmt = DLRep(lhs, rhs)
            com_nizk_proof = com_stmt.prove(
                {s: v for s, v in zip(secret_vars, secrets)}
            )

        return UserCommitmentMessage(com_message=lhs, com_nizk_proof=com_nizk_proof)
示例#2
0
 def construct_stmt(self, precommitment):
     infty = self.generators[0].group.infinite()
     p1 = DLRep(infty,
                self.alpha * self.generators[0] + self.beta * self.lhs[0])
     p2 = DLRep(precommitment,
                self.alpha * self.generators[1] + self.beta * self.lhs[1])
     return p1 & p2
示例#3
0
文件: bbsplus.py 项目: zpleefly/zksk
    def construct_stmt(self, precommitment):
        r"""
        Proof of knowledge of a signature.

        This is an implementation of a proof :math:`\Pi_5` detailed on page 7 of the `Constant-Size
        Dynamick-TAA` paper.
        """

        self.A1, self.A2 = precommitment["A1"], precommitment["A2"]
        g0, g1, g2 = self.bases[0], self.bases[1], self.bases[2]

        dl1 = DLRep(self.A1, self.r1 * g1 + self.r2 * g2)
        dl2 = DLRep(
            g0.group.infinite(),
            self.delta1 * g1 + self.delta2 * g2 + self.secret_vars[0] * (-1 * self.A1),
        )

        self.pair_lhs = self.A2.pair(self.pk.w) + (-1 * self.pk.gen_pairs[0])
        bases = [
            -1 * (self.A2.pair(self.pk.h0)),
            self.bases[2].pair(self.pk.w),
            self.pk.gen_pairs[2],
        ]
        bases.extend(self.pk.gen_pairs[1 : len(self.bases)])

        # Build secret names [e, r1, delta1, s, m_i]
        new_secret_vars = (
            self.secret_vars[:1] + [self.r1, self.delta1] + self.secret_vars[1:]
        )
        pairings_stmt = DLRep(self.pair_lhs, wsum_secrets(new_secret_vars, bases))

        constructed_stmt = AndProofStmt(dl1, dl2, pairings_stmt)
        constructed_stmt.lhs = [p.lhs for p in constructed_stmt.subproofs]
        return constructed_stmt
示例#4
0
def test_dlrep_non_interactive_1(group):
    g, h = make_generators(2, group)
    expr = Secret(value=3) * g + Secret(value=4) * h
    p = DLRep(expr.eval(), expr)
    tr = p.prove()
    prover = p.get_prover()
    assert p.verify(tr)
示例#5
0
def test_dlrep_simulation(group):
    g, h = make_generators(2, group=group)
    x, y = Secret(value=3), Secret(value=4)
    expr = x * g + y * h
    p = DLRep(expr.eval(), expr)

    tr = p.simulate()
    assert (not p.verify(tr)) and p.verify_simulation_consistency(tr)
示例#6
0
def test_dlrep_non_interactive_with_message(group):
    g, h = make_generators(2, group)

    expr = Secret(value=3) * g + Secret(value=4) * h
    p = DLRep(expr.eval(), expr)
    tr = p.prove(message="mymessage")

    assert DLRep(expr.eval(), expr).verify(tr, message="mymessage")
示例#7
0
def test_dlrep_interactive_2(group):
    g, h = make_generators(2, group)
    x, y = Secret(), Secret()

    p = DLRep(10 * g + 15 * h, x * g + y * h)
    prover = p.get_prover({x: 10, y: 15})
    verifier = p.get_verifier()
    protocol = SigmaProtocol(verifier, prover)
    assert protocol.verify()
示例#8
0
def test_same_random_values_in_commitments(group):
    (g, ) = make_generators(1, group)
    generators = [g, g, g]

    pub = group.wsum([Bn(100), Bn(100), Bn(100)], generators)
    x = Secret()
    p = DLRep(pub, wsum_secrets([x, x, x], generators))
    prover = p.get_prover({x: 100})
    commitments = prover.commit()
示例#9
0
def test_dlrep_interactive_1(group):
    sk, g = group.order().random(), group.generator()
    pk = sk * g

    x = Secret()
    p = DLRep(pk, x * g)
    prover = p.get_prover({x: sk})
    verifier = p.get_verifier()
    protocol = SigmaProtocol(verifier, prover)
    assert protocol.verify()
示例#10
0
def test_dlrep_wrong_response_non_interactive(group):
    g, h = make_generators(2, group=group)
    x, y = Secret(value=3), Secret(value=4)
    expr = x * g + y * h

    p = DLRep(expr.eval(), expr)
    tr = p.prove(message="mymessage")

    # Turn one of the responses random
    tr.responses[1] = group.order().random()

    assert not p.verify(tr, message="mymessage")
示例#11
0
def test_dlrep_wrong_public_elements(group):
    g, h = make_generators(2, group=group)
    x, y = Secret(value=3), Secret(value=4)
    expr = x * g + y * h

    public_wrong = get_random_point()
    p = DLRep(public_wrong, expr)

    prover = p.get_prover()
    verifier = p.get_verifier()
    protocol = SigmaProtocol(verifier, prover)
    assert not protocol.verify()
示例#12
0
def test_get_many_different_provers(group, num):
    generators = make_generators(num, group)

    secrets = [Secret(name="secret_%i" % i) for i in range(num)]
    secrets_vals = [Bn(i) for i in range(num)]
    secret_dict = {secret: val for secret, val in zip(secrets, secrets_vals)}

    p = DLRep(group.wsum(secrets_vals, generators),
              wsum_secrets(secrets, generators))
    prover = p.get_prover(secret_dict)
    _, commitment = prover.commit()
    assert isinstance(commitment, EcPt)
示例#13
0
def test_dlrep_wrong_secrets(group):
    g = group.generator()
    g1 = 2 * g
    g2 = 5 * g
    x1 = Secret()
    x2 = Secret()
    p = DLRep(g, x1 * g1 + x2 * g2)
    prover = p.get_prover({x1: 10, x2: 15})
    verifier = p.get_verifier()

    protocol = SigmaProtocol(verifier, prover)
    assert not protocol.verify()
示例#14
0
文件: bbsplus.py 项目: zpleefly/zksk
    def verify_blinding(self, pk):
        """
        Verify the NIZK proof for Pedersen commitment.
        """
        if self.com_nizk_proof is None:
            raise ValueError("No proof to verify")

        # TODO: Extract into a separate ExtendedProofStmt.
        lhs = self.com_message
        generators = pk.generators[1 : len(self.com_nizk_proof.responses) + 1]
        secret_vars = [Secret() for _ in self.com_nizk_proof.responses]
        proof = DLRep(lhs, wsum_secrets(secret_vars, generators))

        return proof.verify(self.com_nizk_proof)
示例#15
0
    def construct_stmt(self, precommitment):
        """
        Construct the internal proof statement.
        """
        if self.is_prover:
            # Indicators that tell us which or-clause is true
            actual_value = ensure_bn(self.x.value)
            value_as_bits = decompose_into_n_bits(actual_value, self.num_bits)
            zero_simulated = [b == 1 for b in value_as_bits]
            one_simulated = [b == 0 for b in value_as_bits]

        bit_proofs = []
        for i in range(self.num_bits):
            p0 = DLRep(precommitment["Cs"][i], self.randomizers[i] * self.h)
            p1 = DLRep(precommitment["Cs"][i] - self.g,
                       self.randomizers[i] * self.h)

            # When we are a prover, mark which disjunct is true
            if self.is_prover:
                p0.set_simulated(zero_simulated[i])
                p1.set_simulated(one_simulated[i])

            bit_proofs.append(p0 | p1)

        return AndProofStmt(*bit_proofs)
示例#16
0
def test_generators_sharing_a_secret(group, num):
    generators = make_generators(num, group)
    unique_secret = 4

    x = Secret()
    secret_vals = [Bn(unique_secret) for _ in range(num)]
    lhs = group.wsum(secret_vals, generators)
    rhs = wsum_secrets([x] * num, generators)

    p = DLRep(lhs, rhs)
    prover = p.get_prover({x: unique_secret})
    assert isinstance(prover, DLRepProver)

    _, commitment = prover.commit()
    assert isinstance(commitment, EcPt)
示例#17
0
def test_dlrep_bad_hash(group):
    g, h = make_generators(2, group=group)
    x, y = Secret(), Secret()
    secret_dict = {x: 2, y: 3}
    p1 = DLRep(2 * g + 3 * h, x * g + y * h)
    p2 = DLRep(2 * g + 3 * h, y * h + x * g)
    tr = p1.prove(secret_dict)
    assert p1.verify(tr)

    with pytest.raises(StatementMismatch):
        p2.verify(tr)
示例#18
0
    def construct_stmt(self, precommitment):
        """
        Build the internal proof statement.

        See the formula in Protocol 1 of the `Thinking Inside the BLAC Box: Smarter Protocols for
        Faster Anonymous Blacklisting` paper.
        """
        infty = self.g.group.infinite()
        p1 = DLRep(infty, self.alpha * self.g + self.beta * self.lhs[0])
        p2 = DLRep(precommitment,
                   self.alpha * self.h + self.beta * self.lhs[1])
        statements = [p1, p2]

        if self.bind:
            # If the binding parameter is set, we add a DLRep member repeating
            # the first member without randomizing the secret.
            statements.append(DLRep(self.lhs[0], self.x * self.g))

        return AndProofStmt(*statements)
示例#19
0
    def __call__(self, com, g, h, a, b, x, r):
        """
        Get a conjunction of two range-power-of-two proofs.

        Args:
            com: Value of the Pedersen commitment, :math:`C = x G + r H`
            g: First commitment base point :math:`G`
            h: Second commitment base point :math:`H`
            a: Lower limit :math:`a`
            b: Upper limit :math:`b`
            x: Value for which we construct a range proof
            r: Randomizer of the commitment :math:`r`
        """
        a = ensure_bn(a)
        b = ensure_bn(b)
        num_bits = (b - a - 1).num_bits()
        offset = Bn(2)**num_bits - (b - a)

        com_shifted1 = com - a * g
        com_shifted2 = com_shifted1 + offset * g
        x1 = Secret()
        x2 = Secret()
        if x.value is not None:
            x1.value = x.value - a
            x2.value = x.value - a + offset

            # Ensure secret is in range
            if x.value < a or x.value >= b:
                warnings.warn("Secret outside of given range [{}, {})".format(
                    a, b))

        com_stmt = DLRep(com, x * g + r * h)

        p1 = PowerTwoRangeStmt(
            com=com_shifted1,
            g=g,
            h=h,
            num_bits=num_bits,
            x=x1,
            randomizer=r,
        )

        p2 = PowerTwoRangeStmt(
            com=com_shifted2,
            g=g,
            h=h,
            num_bits=num_bits,
            x=x2,
            randomizer=r,
        )

        return com_stmt & p1 & p2
示例#20
0
def test_diff_groups_dlrep(group):
    g, h = make_generators(2, group)
    x, y = Secret(), Secret()

    # Precondition for the test.
    other_group = EcGroup(706)
    assert other_group != group, "Test assumption is broken."
    h = other_group.generator()

    expr = x * g + y * h
    z = get_random_point(group)
    with pytest.raises(InvalidExpression):
        p = DLRep(z, expr)
示例#21
0
    def __call__(self, a, b, x=None):
        """
        Get a conjunction of two range-power-of-two proofs.
        Args:
            a: Lower limit :math:`a`
            b: Upper limit :math:`b`
            x: Value for which we construct a range proof
        """
        group = EcGroup()
        g = group.hash_to_point(b"g")
        h = group.hash_to_point(b"h")

        r = Secret(value=group.order().random())
        com = (x * g + r * h).eval()

        a = ensure_bn(a)
        b = ensure_bn(b)
        num_bits = (b - a - 1).num_bits()
        offset = Bn(2)**num_bits - (b - a)
        com_shifted1 = com - a * g
        com_shifted2 = com_shifted1 + offset * g

        x1 = Secret()
        x2 = Secret()
        if x is not None:
            x1.value = x.value - a
            x2.value = x.value - a + offset

        com_stmt = DLRep(com, x * g + r * h)
        p1 = PowerTwoRangeStmt(
            com=com_shifted1,
            g=g,
            h=h,
            num_bits=num_bits,
            x=x1,
            randomizer=r,
        )
        p2 = PowerTwoRangeStmt(
            com=com_shifted2,
            g=g,
            h=h,
            num_bits=num_bits,
            x=x2,
            randomizer=r,
        )

        return com_stmt & p1 & p2
示例#22
0
def test_dlrep_interactive_3(group):
    """Emulate actual workflow with independent provers and verifiers."""
    sk, g = group.order().random(), group.generator()
    pk = sk * g

    x = Secret()
    p1 = DLRep(pk, x * g)
    prover = p1.get_prover({x: sk})

    x = Secret()
    p2 = DLRep(pk, x * g)
    verifier = p2.get_verifier()

    protocol = SigmaProtocol(verifier, prover)
    assert protocol.verify()
示例#23
0
def test_dlrep_non_interactive_2(group):
    (g, ) = make_generators(1, group)
    x = Secret()
    p = DLRep(4 * g, x * g)
    tr = p.prove({x: 4})
    assert p.verify(tr)