This project serves as a practical demonstration of the Chaum-Pedersen Zero-Knowledge Proof protocol. It showcases an interactive model where the prover (represented by the client) and the verifier (embodied by the server) engage in a sequence of communications to validate claims without revealing underlying secrets. The exchange between the prover and verifier is facilitated through gRPC
, enabling efficient and structured data transmission for the verification process.
- Introduction
- Approach
- Overview of Solution
- Using the Project
- Set up your Environment
- Run it Locally
- Run it on Docker (
docker-compose
) - Test it
- Development
pre-commit
protobuf
- Deployment to
AWS
: Strategy and Steps- Simple AWS-Native Approach
- Complex, Flexible Approach
- Future Considerations
- Diving Deeper
- Nuances
The Chaum-Pederson protocol is a zero-knowledge proof (ZKP) mechanism that enables one party to prove the possession of a certain discrete logarithm without revealing its actual value. This cryptographic protocol is particularly revered for its completeness and soundness properties: completeness ensures that an honest prover can always convince a verifier of the truth of a valid statement, while soundness guarantees that a dishonest prover cannot convince the verifier of a false statement, except with some negligible probability. It is grounded in the realm of integer-based modular exponentiations, which form the backbone of the commitment step where the prover sends a value to the verifier without disclosing the secret. This is followed by the challenge step, where the verifier sends a randomly chosen challenge to the prover, and then the response step, where the prover sends a response that allows the verifier to check the validity of the initial commitment. The Chaum-Pederson protocol exemplifies an interactive ZKP, demanding an active dialogue between the prover and verifier, yet it maintains the zero-knowledge property whereby no additional information is leaked beyond the validity of the statement being proven.
Now that what needs to be done is understood an overview of the solution will be highlighted.
-
Directory Structure:
src/
: Contains the core Python files for the service, including:client.py
: Manages the CLI for user interaction (registration, login).lib.py
: Handles the mathematical operations for generating ( g, h, p, q ) values.server.py
: Implements gRPC for server-client communication.settings.py
: Reads and validates the YAML configuration.
proto/
: Includes.proto
definition files and autogenerated Python gRPC files for protocol buffers.tests/
: Stores unittests for testing various components of the project.configs/
: Contains YAML configuration for initial service variables.scripts/
: Houses scripts for service startup usingdocker-compose
.
-
Key Components:
- Configuration and Validation:
- The YAML configuration file sets initial variables and is validated by
settings.py
to adhere to the required number of bits.
- The YAML configuration file sets initial variables and is validated by
- Mathematical Library (
lib.py
):- Approach 1 is used to generate cryptographic values ( g, h, p, q ), based on the bits specified in the YAML config.
- Approach 2 was my curiosity going down a rabbit hole...
- This script operates independently and outputs values that can be manually entered into the YAML config.
- Client-Server Interaction:
- The
server.py
andclient.py
manage the gRPC-based communication. - Chaum-Pedersen protocol mathematics are distributed across these files corresponding to the protocol steps.
- Includes basic exception handling for robust process flow.
- The
- Command-Line Interface (CLI):
- Provided by
client.py
to allow user interaction with the system for functions like registration and login.
- Provided by
- Configuration and Validation:
-
Protobuf and gRPC:
proto/zkp_auth.proto
: Protocol buffers definition file.- Autogenerated files (
zkp_auth_pb2.py
,zkp_auth_pb2_grpc.py
,zkp_auth_pb2.pyi
) are detailed under the Development section in the documentation, explaining their generation.
-
Containerization and Deployment:
- Scripts in the
scripts/
directory facilitate starting the service in a containerized environment using Docker.
- Scripts in the
-
Code Quality and Standards:
- Utilization of a pre-commit hook alongside linting and formatting tools (
flake8
,black
,isort
,mypy
, etc.) ensures high code quality and consistency.
- Utilization of a pre-commit hook alongside linting and formatting tools (
This summary captures the project's directory layout, main and secondary directories, the nature of key components, gRPC and Protobuf usage, containerization strategy, and code quality measures.
Below is the order in which I approached this particular project.
- Comprehensive review of all relevant documentation.
- Conceptualization of the core principles and objectives.
- Detailed examination of the mathematical foundations.
- Assessment of system requirements and specifications.
- Drafting of a preliminary system architecture plan.
- Creation of a foundational script to grasp and apply the protocol:
- 6.1. Exploration of the Chaum-Pedersen protocol mechanics.
- 6.2. Generation of publicly agreed-upon variables ( g, h, p, q ).
- Incremental development process:
- 7.1. Establishment of foundational functions and classes derived from
zkp_auth.proto
. - 7.2. Facilitation of communication between the client and server using
gRPC
. - 7.3. Integration and testing of the cryptographic mathematics.
- 7.4. Automation of user authentication to streamline the verification process.
- 7.1. Establishment of foundational functions and classes derived from
- Conducting preliminary tests and refinements.
- Construction and execution of a comprehensive suite of unit tests.
- Progressive enhancements:
- 10.1. Development of a Command Line Interface (CLI) for user interaction.
- 10.2. Configuration management using a YAML file accessible to all services.
- 10.3. Containerization of the project for deployment ease and reproducibility.
Things to know to get up and running.
In order to be able to run this project the user will require:
- Poetry (local) - Installation
- Docker (containerised) - Installation
Set up the environment.
poetry shell
poetry install
Next we will start our client
and server
in seperate terminals - be sure to start the server
first.
Open Terminal 1
python -m src.server
Open Terminal 2
python -m src.client local
See python -m src.client -h
for a list of choices.
You are encouraged to have a look at the contents of the below script as well as the docker-entrypoint.sh
inside the server and client ci
directories respectively.
bash scripts/start_docker_compose_services.sh
python -m unittest discover -s tests
If you're going to be fiddling with this please consult.
Should you want to work on this project it is necessary to make use of the pre-commit
.
Please note that all below commands that beging with
pre-commit
need to be run from within the virtual environment.
- Ensure that it is installed on your device - documentation
- Install this project's specific pre-commit.
pre-commit install
- Run all of the pre-commit hooks.
pre-commit run --all-files
-
Run specific hook.
See the hook id inside the
.pre-commit-config.yaml
file. Examples:mypy
,isort
,flake8
, etc.
pre-commit run <hook_name> --all-files
This project communicates on port 50051
by making use of grpc protobuf - see ./proto/zkp_auth.proto
for the protobuf
definition.
Additionally, should you want to update or generate the other files in the ./proto
directory perform the following:
- To generate
zkp_auth_pb2.py
andzkp_auth_pb2_grpc.py
python -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. ./proto/zkp_auth.proto`
- To generate
zkp_auth_pb2.pyi
`protoc --mypy_out=. proto/zkp_auth.proto`
Note that this requires protoc, Protocol Buffer Compiler, to be installed on your device - installation.
Deploying to AWS involves a thoughtful consideration of the technologies in use and their alignment with our project goals and infrastructure. The following is an overview of the technological stack and deployment strategies:
- Continuous Integration / Continuous Deployment:
- Options include GitLab CI/CD, GitHub Actions, or AWS CodeBuild/CodePipeline.
- Infrastructure:
- Infrastructure as Code (IaC) with Terraform for provisioning.
- AWS services, weighing options like EC2 versus ECS and ECR versus Docker Hub.
Given these considerations, two deployment approaches are proposed - a simpler AWS-native strategy and a more complex, flexible approach.
The simple approach leverages AWS services exclusively to streamline the process:
- Prepare a
buildspec.yml
for AWS CodeBuild to define the build process. - Set up an Amazon Elastic Container Registry (ECR) for Docker image storage.
- Configure AWS CodeBuild for continuous integration.
- Establish AWS CodePipeline to automate code retrieval and deployment processes.
- Use Amazon Elastic Container Service (ECS) for container orchestration and deployment.
- Enable automated deployments through CodePipeline, connecting the build artifacts to ECS services.
The more intricate strategy demands a solid DevOps background but offers a robust and finely-tuned deployment process:
- Set up a
gitlab-ci.yml
for the GitLab CI/CD pipeline. - Use Terraform to define and create the AWS infrastructure, including:
- 2.1. Amazon ECR for Docker image registry.
- 2.2. Amazon EC2 instances for scalable compute capacity.
- 2.3. GitLab runners configured on AWS to execute the CI/CD pipeline.
- Implement Ansible playbooks for consistent setup and configuration of the deployment environment.
- Establish monitoring and observability with tools such as DataDog or Prometheus for system health insights.
- Push code changes to trigger the pipeline and deploy automatically onto the configured AWS infrastructure.
In both strategies, consider the security implications of each step, ensure IAM roles and policies are tightly scoped, and validate that networking configurations (like VPCs and security groups) align with best practices for a secure, scalable cloud environment.
Moving forward, the following could be improved:
-
Integrate a Persistent Storage Solution:
- Implementing a database such as SQLite would address the challenge of synchronizing public variable updates across client and server containers. This shared, persistent store would facilitate dynamic updates.
- Transitioning from a transient in-memory dictionary to a persistent storage mechanism would prevent data loss on service restarts and maintain the state of registered users.
-
Session Management Enhancements:
- Introducing a session timeout would greatly enhance security for a production-ready system.
- Generating unique and non-repeatable session IDs for each login instance would mitigate replay attacks and session hijacking risks.
-
Secure Public Variables Selection:
- Ensuring the uniqueness of the prover's first-step value
k
is crucial to prevent predictability and enhance security. Implementing a more sophisticated hashing strategy could enforce this uniqueness.
- Ensuring the uniqueness of the prover's first-step value
-
Address Protobuf Limitations:
- The current use of
int64
in protobuf restricts the system to 63-bit integers. Considering alternative representations, like strings, could enable the use of larger numbers without altering the protobuf definition. - For the proof-of-concept phase, the current setup is adequate, but for advanced security, this limitation must be revisited.
- The current use of
-
Optimizations for Handling Large Numbers:
- For larger numbers, such as 512-bit values, performing algorithmic complexity analysis (Big O notation) would identify performance bottlenecks.
- Exploring parallel processing techniques like threading or multiprocessing could significantly reduce computation times for these large numbers.
-
Security and Performance Improvements:
- Adopting elliptic curve cryptography (ECC) could dramatically improve both the security and efficiency of the protocol, making it suitable for higher security demands and modern computational standards.
To further understand the Chaum-Pedersen Interactive Zero-Knowledge Protocol, please consult:
- Cryptography: An Introduction (3rd Edition) by Nigel Smart - book
- Sigma Protocols, Chaum–Pedersen Protocol - Chapter 25. Zero-Knowledge Proof, Section 3.2, page 377
- Discrete Logarithms - Chapter 13. page 203
- Prime Numbers, Miller–Rabin Test - Chapter 12. Primality Testing and Factoring, Section 1.3, page 188
- Basic Algorithms, Greatest Common Divisors - Chapter 1. Modular Arithmetic, Groups, Finite Fields and Probability, Section 3.1, page 10
- Commitments and Oblivious Transfer - Chapter 24, page 363
- Chaum pedersen zero knowledge protocol - video
Error: "ModuleNotFoundError: No module named '<module_name>'"
Answer: Ensure that your poetry
environment is active and that you have run export PYTHONPATH='src':$PYTHONPATH
.