ZKP Pedersen Commitment Scheme module
Project description
TNO PET Lab - Zero-Knowledge Proofs (ZKP) - Commitment Schemes - Pedersen
Implementation of the Pedersen commitment scheme.
PET Lab
The TNO PET Lab consists of generic software components, procedures, and functionalities developed and maintained on a regular basis to facilitate and aid in the development of PET solutions. The lab is a cross-project initiative allowing us to integrate and reuse previously developed PET functionalities to boost the development of new protocols and solutions.
The package tno.zkp.commitment_schemes.pedersen is part of the TNO Python Toolbox.
Limitations in (end-)use: the content of this software package may solely be used for applications that comply with international export control laws.
This implementation of cryptographic software has not been audited. Use at your own risk.
Documentation
Documentation of the tno.zkp.commitment_schemes.pedersen package can be found
here.
Install
Easily install the tno.zkp.commitment_schemes.pedersen package using pip:
$ python -m pip install tno.zkp.commitment_schemes.pedersen
Note: If you are cloning the repository and wish to edit the source code, be sure to install the package in editable mode:
$ python -m pip install -e 'tno.zkp.commitment_schemes.pedersen'
If you wish to run the tests you can use:
$ python -m pip install 'tno.zkp.commitment_schemes.pedersen[tests]'
Note: A significant performance improvement can be achieved by installing the GMPY2 library.
$ python -m pip install 'tno.zkp.commitment_schemes.pedersen[gmpy]'
Using the Pedersen Zero Knowledge Proof library
NOTE: This library is meant to be used in combination with the zero-knowledge proof (ZKP) template library found here. Preliminaries on the content can also be found here. The Pedersen library is an instance of a ZKP, which uses the functionality from the template. In that sense, it is interchangable with the modulus linear form described in the template. They are both homomorphisms to be used in sigma protocols, though they have different structure. If anything below is unclear, it is highly recommended to read the preliminaries.
The ZKP library is based on Thomas Attema's dissertation Compressed $\Sigma$-protocol Theory, which can be found here. Many concepts are taken from it, and there will be references throughout the code to the dissertation. In this README the crucial concepts from the dissertation needed to use this library will be explained in short. If anything is unclear, feel free to raise an issue at the code repository.
Commitment schemes
A commitment scheme is a cryptograpic protocol that is used when a party has a value they want to commit to now, but only share later. A commitment scheme consists of two phases: in the commit phase, the prover commits to a chosen value and sends a commitment to the verifier. During the reveal phase, the prover sends the original value and the verifier checks that the earlier commitment was indeed correct. One can view the functionality similar to the prover putting the value in a box, locking it and giving it to the verifier, and only later giving the key to the verifier to check. Commitment schemes can for instance be used to fairly flip a coin over text-only communication, where it can make sure neither party cheats by changing their prediction. It can also be used in more complex applications, such as signature schemes, secret sharing or zero-knowledge proofs.
The Pedersen commitment scheme
The Pedersen commitment scheme is defined as follows. The prover has a secret value $\mathbf{x} \in \mathbb{G}^n$ and reveal information $u \in \mathbb{G}$. They calculate the commitment $P := \psi_n(u, \mathbf{x})$, where the homomorphism $\psi_n$ is defined as
$$ \psi_n(u, \mathbf{x}) := h^u \cdot g_1^{x_1} g_2^{x_2} \cdots g_n^{x_n} $$
where $h, g_1, g_2, \dots, g_n \in \mathbb{G}$. Then the prover sends $P$ to the verifier who stores it. Only later, when the prover wants to show that they indeed chose $\mathbf{x}$, they send $\mathbf{x}$ to the verifier, who then checks that $\psi(u, \mathbf{x}) = P$.
Compressing the homomorphism
Splitting the homomorphism $\psi_n$ and the input $(u, \mathbf{x})$ works similarly to the linear form found in the templates package, but the reveal information needs to be handled correctly as well. We split the input vector $\mathbf{x}$ as follows
\mathbf{x} = (x_1, x_2, \dots, x_n) \\
\mathbf{x_L} = (x_1, x_2, \dots, x_{n/2}) \\
\mathbf{x_R} = (x_{n/2+1}, x_{n/2+2}, \dots, x_n)
and similarly the generators $g_1, g_2, \dots, g_n$ of $\psi(\cdot)$. We also need to 'split' the reveal information $u$ and the generator $h$, but these are numbers rather than vectors. It turns out that if we simply copy these values to both halves, the verification fails. So instead, we give the halves new reveal information $u_L$ and $u_R$ respectively, leading to the following
\psi_n(u, \mathbf{x}) := h^u \cdot g_1^{x_1} g_2^{x_2} \cdots g_n^{x_n} \\
\psi_{n/2}^L(u_L, \mathbf{x}_L) := h^{u_L} \cdot g_1^{x_1} g_2^{x_2} \cdots g_{n/2}^{x_{n/2}}
\\
\psi_{n/n}^R(u_R, \mathbf{x}_R) := h^{u_R} \cdot g_{n/2+1}^{x_{n/2+1}} g_{n/2+2}^{x_{n/2+2}} \cdots g_n^{x_n}
If we plug general $u_L, u_R$ into the scheme and follow the protocol, at the verification step we get the equation
h^{u_L+cu+c^2u_R} = \left(h^{c+1}\right)^{(u_L+cu_R)} \\
\implies u_L+cu+c^2u_R = u_L+c(u_L+u_R)+c^2u_R \\
\implies u = u_L+u_R
Therefore when splitting, we define $u_L:=0, \ u_R:=u$ to ensure correct behavior. This design is followed in the code.
Creating a Sigma Protocol
To support the creation of a sigma protocol the template classes have been created. The template classes can be split into two categories.
The first category are the classes needed to create a basic sigma protocol. The basic sigma protocol creates a proof of knowledge in a non-interactive way. The StandardSigmaProtocol object contains all the information needed for the verification and none of the private information. The object can therefore be shared with the verifier for verification.
The PedersenVectorCommitmentScheme is a Homomorphism object that can be used with the sigma protocol library.
The easiest way to create a PedersenVectorCommitmentScheme is using the from_security_param, supplying a key length of 256 bits and generating a vector of length 16 in this case. You can also define the coefficients manually, but you need to supply a large enough safe prime as well.
Generating the proof of knowledge is relatively straight forward. You call the method generate_proof with the homomorphism, the secret input and the hash function. The class will handle the process as described in the steps above.
To verify the proof of knowledge you only need to call the verify function.
from tno.zkp.commitment_schemes.pedersen import PedersenVectorCommitmentScheme
from tno.zkp.templates.sigma_protocol import StandardSigmaProtocol
homomorphism = PedersenVectorCommitmentScheme.from_security_param(key_length=256, vector_length=16)
secret_input_x = homomorphism.random_input()
proof_of_knowledge = StandardSigmaProtocol.generate_proof(
homomorphism, secret_input_x, "sha256"
)
# proof of knowledge can now be transferred to the verifier
assert proof_of_knowledge.verify()
Compressing a Sigma Protocol
To compress a proof of knowledge there are some requirements on the homomorphism and the input. The requirements are
enforced using the CompressibleHomomorphism and the CompressibleHomomorphismInput abstract classes.
Compressing a proof of knowledge makes the verification of the protocol cheaper. The cost savings occur due to a compression mechanism. The compression mechanism is described in detail in the dissertation.
The PedersenVectorCommitmentScheme class satisfies the requirements. Therefore, we can use the
previous proof of knowledge for compression.
To apply the compression we need to use a compression mechanism. The compression mechanism from the dissertation has been implemented in the template. To apply it you need to do the following:
from tno.zkp.templates.compression_mechanism import full_compression
# compress the proof of knowledge as much as possible
compressed_protocol = full_compression(proof_of_knowledge)
assert compressed_protocol.verify()
The function full_compression reduces the ZKP from length $n$ until it can not be compressed anymore, which is a length of 1. The function used for the compression is called compression and is available to the user as well. The compression function halves the length of the ZKP.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tno_zkp_commitment_schemes_pedersen-0.2.0.tar.gz.
File metadata
- Download URL: tno_zkp_commitment_schemes_pedersen-0.2.0.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e606eb77ad8903826394f0928237928e1a9629549da10075e2fd02deb99b7da1
|
|
| MD5 |
ce2eda6f4517e0c023763b0b9582be0f
|
|
| BLAKE2b-256 |
ec7d75a05323f81d5686683f174fb3a6ef94af624d0f27ca8b0e38cd08a29059
|
File details
Details for the file tno.zkp.commitment_schemes.pedersen-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tno.zkp.commitment_schemes.pedersen-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a3d6a3ccf150cfb620b4b5570048df1518ad3b70a4ebd666ea3c74cd802e0e2
|
|
| MD5 |
80cb51ce10e573f631c8afad71c9ac68
|
|
| BLAKE2b-256 |
d9fb8441ada99de53569f8d37d75dabb303ec0356d8527ce608cfacf2c5c2305
|