Primitives API¶
zksk.primitives.dlrep
– Discrete Logarithm Representations¶
ZK proof for linear representations of discrete logarithms, our basic building block.
An example of such proof is \(PK\{ (x_0, x_1): y = x_0 G_0 + x_1 G_1 \}\), where \(x_0\) and \(x_1\) are secret integers from a finite field, \(G_0\) and \(G_1\) are points on a same elliptic curve, and \(y\) is the actual value of the expression \(x_0 G_0 + x_1 G_1\).
See “Proof Systems for General Statements about Discrete Logarithms” by Camenisch and Stadler, 1997 for the details.

class
zksk.primitives.dlrep.
DLRep
(lhs, expr, simulated=False)¶ Proof statement for a discretelogarithm representation proof.
Supports statements of the following form:
\[PK\{ (x_0, x_1, ..., x_n): Y = x_0 G_0 + x_1 G_1 + ... + x_n G_n \}\]Example usage for \(PK\{x: Y = x G \}\):
>>> from petlib.ec import EcGroup >>> x = Secret(name="x") >>> g = EcGroup().generator() >>> y = 42 * g >>> stmt = DLRep(y, x * g) >>> nizk = stmt.prove({x: 42}) >>> stmt.verify(nizk) True
 Parameters
expr (
zksk.base.Expression
) – Proof statement. For example:Secret("x") * g
represents \(PK\{ x: Y = x G \}\).lhs – “Lefthand side.” Value of \(Y\).

get_proof_id
(secret_id_map=None)¶ Identifier for the proof statement
 Returns
Objects that can be used for hashing.
 Return type
list

get_prover
(secrets_dict=None)¶ Get a prover for the current proof statement.
 Parameters
secrets_dict – Optional mapping from secrets or secret names to their values.
 Returns
Prover object if all secret values are known.
 Return type
DLRepProver
or None

get_randomizers
()¶ Initialize randomizers for each secret.
Each randomizer is drawn at random from the associated group.
By using a dictionary, we enforce that if secret are repeated in \(x_0 G_0 + x_1 G_1 + ... + x_n G_n\), that is, if \(x_i\) and \(x_j\) have the same name, they will get the same random value. Identical secret values and identical randomizers will yield identical responses, and this identity will be checked by the verifier.
 Returns
 Mapping from secrets to the random values that are needed to compute the responses
of the proof.
 Return type
dict

recompute_commitment
(challenge, responses)¶ Compute a pseudocommitment.
A pseudocommitment is the commitment a verifier should have received if the proof was correct. It should be compared to the actual commitment.
Reoccuring secrets yield identical responses.
 Parameters
challenge – the challenge used in the proof
response – a list of responses, ordered as the list of secret names, i.e., with as many elements as there are secrets in the proof claim.

simulate_proof
(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 nonempty but incomplete responses_dict.
 Parameters
responses_dict – Optinal mapping from secrets or secret names to responses.
challenge – Optional challenge to use in the simulation

verifier_cls
¶ alias of
DLRepVerifier

class
zksk.primitives.dlrep.
DLRepProver
(stmt, secret_values)¶ The prover in a discrete logarithm proof.

compute_response
(challenge)¶ Constructs an (ordered) list of response for each secret.
For each secret \(x\) and a random value \(k\) (associated to \(x\)), the response is equal to \(k + c x\), where \(c\) is the challenge value.
 Parameters
challenge – Challenge value
 Returns
A list of responses

internal_commit
(randomizers_dict=None)¶ Compute the commitment using the randomizers.
 Parameters
randomizers_dict – Optional mapping from secrets or secret names to random values. Every random value not given here will be generated at random.
 Returns
A single commitment—sum of bases, weighted by the corresponding randomizers


class
zksk.primitives.dlrep.
DLRepVerifier
(stmt)¶ 
check_responses_consistency
(responses, responses_dict=None)¶ Check if reoccuring secrets yield the same responses.
To do so, go through the names of the secrets in the current DLRep, and construct a mapping between secrets and responses.
 Parameters
response – List of responses
responses_dict – Mapping from secrets to responses
 Returns
True if responses are consistent, False otherwise.
 Return type
bool

zksk.primitives.dl_notequal
– Inequality of Discrete Logarithms¶
ZK proof of inequality of two discrete logarithms.
See Protocol 1 in “Thinking Inside the BLAC Box: Smarter Protocols for Faster Anonymous Blacklisting” by Henry and Goldberg, 2013:

class
zksk.primitives.dl_notequal.
DLNotEqual
(valid_pair, invalid_pair, x, bind=False, simulated=False)¶ ZK proof statement of inequality of two discrete logarithms.
\[PK\{ (x): H_0 = x h_0 \land H_1 \neq x h_1 \}\]The statement is constructed from two pairs: \((H_0, h_0)\), \((H_1, h_1)\), and a
expr.Secret
object representing a secret \(x\).The proof can be made binding: bind the \(x\) to another proof. If the proof is not binding, it is not possible to assert that the same \(x\) was used in any other proof (even in, say, an AND conjunction).
 Parameters
valid_pair (tuple) – Pair of two Elliptic curve points \((H_0, h_0)\) such that \(H_0 = x h_0\)
invalid_pair (tuple) – Pair of two Elliptic curve points \((H_1, h_1)\) such that \(H_1 \neq x h_1\)
x (
expr.Secret
) – Secret.bind (bool) – Whether the proof is binding.
simulated (bool) – If this proof is a part of an orproof: whether it should be simulated.

construct_stmt
(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.

precommit
()¶ Build the lefthand side of the internal proof statement.

simulate_precommit
()¶ Draw a base at random (not unity) from the bases’ group.

validate
(precommitment)¶ Verify the the proof statement is indeed proving the inequality of discret logs.
zksk.primitives.bbsplus
– Knowledge of BBS+ Signature¶
ZK proof of knowledge of a BBS+ signature.
This proof can be used to build blacklistable anonymous credential schemes.
See “ConstantSize Dynamic kTAA” by Au et al., 2008 for the details.

class
zksk.primitives.bbsplus.
BBSPlusKeypair
(generators, h0, sk, pk)¶ A publicprivate key pair, along with a list of canonical bases to use in proofs.

static
generate
(bilinear_pair, num_generators)¶ Generate a keypair.
 Parameters
bilinear_pair (
pairings.BilinearGroupPair
) – Bilinear group pair.num_generators – Upper bound on the number of generators needed to compute the proof. Should be at least 2 + the number of messages.
 Returns
Keypair.
 Return type

static

class
zksk.primitives.bbsplus.
BBSPlusPublicKey
(w, h0, generators)¶ BBS+ public key.
Automatically precomputes the generator pairings \(e(g_i, h_0)\).

__attrs_post_init__
()¶ Precompute the group pairings.


class
zksk.primitives.bbsplus.
BBSPlusSecretKey
(h0, gamma, generators)¶ BBS+ private key.

sign
(lhs)¶ Sign a committed message (typically a product, blinded or not),
A signature is \((A, e, s_2)\) such that \(A = (g_0 + s_2 g_1 + C_m) \cdot \frac{1}{e+\gamma}\).
If the product was blinded by the user’s \(s_1\) secret value, user has to update the signature.


class
zksk.primitives.bbsplus.
BBSPlusSignature
(A, e, s)¶ BBS+ signature.

verify_signature
(pk, messages)¶ Verify the validity of the signature w.r.t the given public key and set of messages.


class
zksk.primitives.bbsplus.
BBSPlusSignatureCreator
(pk)¶ Presigned product along with a NIZK proof of correct construction.
 Parameters
pk (PublicKey) – Public key.

commit
(messages, zkp=True)¶ Construct the product of messages and optionaly a Pedersen commitment and its proof.
 Parameters
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
user’s packed commitment.
 Return type

obtain_signature
(presignature)¶ Make a complete signature from the received presignature.
 Parameters
presignature (
BBSPlusSignature
) – presignature Returns
Signature.
 Return type

class
zksk.primitives.bbsplus.
BBSPlusSignatureStmt
(secret_vars, pk, signature=None, binding=True, simulated=False)¶ Proof of knowledge of a BBS+ signature over a set of (hidden) messages.
The proof can be made binding: bind the secrets to another proof. If the proof is not binding, it is not possible to assert that the same secrets were used in any other proof.
 Parameters
secret_vars – Secret variables. If binding, the two first elements of secret_vars as the Secret variables for the
e
ands
attributes of the signature.pk (
BBSPlusPublicKey
) – Public key.signature (
BBSPlusSignature
) – Signature. Required if used for proving.binding (bool) – Whether the signature is binding.
simulated (bool) – If this proof is a part of an orproof: whether it should be simulated.

construct_stmt
(precommitment)¶ Proof of knowledge of a signature.
This is an implementation of a proof \(\Pi_5\) detailed on page 7 of the ConstantSize DynamickTAA paper.

precommit
()¶ Generate the lacking information to construct a complete proof.
The precommitment comprises the
A1
andA2
commitments that depend on the secret signature and the Prover’s randomness.

simulate_precommit
()¶ Draw \(A_1\), \(A_2\) at random.
zksk.primitives.rangeproof
– Range proofs¶
Range proof: ZK proof that a committed value lies within a range.
This module implements a Schoenmakers’ range proof, a conjuction of orproofs for each bit of the value.

class
zksk.primitives.rangeproof.
GenericRangeOnlyStmtMaker
¶ Auxiliary builder class for generic range proofs.
\[PK \{ (x): a \leq x < b \}\]See “Efficient Protocols for Set Membership and Range Proofs” by Camenisch et al., 2008.
In practice, use the
zksk.primitives.rangeproof.RangeStmt
object directly:>>> x = Secret(value=3) >>> lo = 0 >>> hi = 5 >>> stmt = RangeOnlyStmt(lo, hi, x) >>> nizk = stmt.prove() >>> stmt.verify(nizk) True
See
GenericRangeStmtMaker.__call__()
for the construction signature.
__call__
(a, b, x=None)¶ Get a conjunction of two rangepoweroftwo proofs. :param a: Lower limit \(a\) :param b: Upper limit \(b\) :param x: Value for which we construct a range proof


class
zksk.primitives.rangeproof.
GenericRangeStmtMaker
¶ Auxiliary builder class for generic range proofs.
\[PK \{ (r, x): x G + r H \land a \leq x < b \}\]See “Efficient Protocols for Set Membership and Range Proofs” by Camenisch et al., 2008.
In practice, use the
zksk.primitives.rangeproof.RangeStmt
object directly:>>> group = EcGroup() >>> x = Secret(value=3) >>> randomizer = Secret(value=group.order().random()) >>> g = group.hash_to_point(b"1") >>> h = group.hash_to_point(b"2") >>> lo = 0 >>> hi = 5 >>> com = x * g + randomizer * h >>> stmt = RangeStmt(com.eval(), g, h, lo, hi, x, randomizer) >>> nizk = stmt.prove() >>> stmt.verify(nizk) True
See
GenericRangeStmtMaker.__call__()
for the construction signature.
__call__
(com, g, h, a, b, x, r)¶ Get a conjunction of two rangepoweroftwo proofs.
 Parameters
com – Value of the Pedersen commitment, \(C = x G + r H\)
g – First commitment base point \(G\)
h – Second commitment base point \(H\)
a – Lower limit \(a\)
b – Upper limit \(b\)
x – Value for which we construct a range proof
r – Randomizer of the commitment \(r\)


class
zksk.primitives.rangeproof.
PowerTwoRangeStmt
(com, g, h, num_bits, x=None, randomizer=None)¶ A powertwo range proof statement.
\[PK \{ (r, x): C = x G + r H \land 0 \leq x < 2^n \}\] Parameters
com – Value of the Pedersen commitment, \(C = x G + r H\)
g – First commitment base point \(G\)
h – Second commitment base point \(H\)
num_bits – The number of bits of the committed value \(n\)
x – Value for which we construct a range proof (prover only)
randomizer – Randomizer of the commitment \(r\) (prover only)

construct_stmt
(precommitment)¶ Construct the internal proof statement.

precommit
()¶ Commit to the bitdecomposition of the value.

simulate_precommit
()¶ Simulate a precommitment. Override if needed.
Override this method to enable using this proof in orproofs.
It should compute the same output as generated by precommit, but without relying on any secrets.

validate
(precommitment)¶ Check the commitment to the bitdecomposition is correct.

zksk.primitives.rangeproof.
decompose_into_n_bits
(value, n)¶ Array of bits, least significant bit first