Work in Progress: This project is under active development and is not yet production-ready. APIs, circuit design, and implementation details may change without notice. Use at your own risk and do not rely on this for securing real assets until a stable release is announced.
PQChain is an open-source implementation of a post-quantum secure zero-knowledge proof system for EdDSA key ownership. It enables users to prove ownership of Ed25519 keys through their deterministic seed, facilitating seamless post-quantum migration for modern blockchains without changing addresses.
Research Paper: This implementation is based on our research paper "Post-Quantum Readiness in EdDSA Chains" accepted to Financial Crypto Conference 2026.
- Introduction
- Why PQChain?
- Technical Approach
- Repository Structure
- Prerequisites and Setup
- Building the Project
- Running the Prover and Verifier
- Circuit Arguments
- Performance Benchmarks
- Troubleshooting
- Acknowledgements
- License
- About Soundness Labs
Quantum computers pose an existential threat to elliptic curve cryptography. Shor's algorithm can recover private keys from public keys in polynomial time, putting billions of dollars in blockchain assets at risk. EdDSA-based chains (Sui, Solana, Near, and others) have a structural advantage: keys are deterministically derived from a seed via RFC 8032, enabling zero-knowledge proofs of ownership without exposing the private scalar.
PQChain leverages this property to create a backward-compatible post-quantum migration path. Users can prove they control an EdDSA keypair by demonstrating knowledge of the underlying seed—all without revealing the seed itself or changing their on-chain address.
For a detailed treatment of the cryptographic foundations and security analysis, see our research paper.
This implementation builds upon the Ligetron zkVM (v1.1.0), extending it with:
- Complete Ed25519 curve arithmetic via non-native field emulation
- SHA-512 implementation for RFC 8032-compliant key derivation
- A ZK circuit proving seed-to-public-key consistency
Base Commit:
commit fd06e438cf84de6d9c30243e0feec858c9b16bf8
Author: release-bot <releases@ligero-inc.com>
Date: Sun Oct 5 04:00:15 2025 +0000
Release v1.1.0
- Shor's Algorithm: Can break ECDSA/EdDSA in polynomial time once large-scale quantum computers exist
- Regulatory Pressure: NIST mandates post-quantum migration for critical systems by 2030; many enterprises need solutions now
We selected the Ligetron zkVM as our proving backend for several reasons:
| Feature | Benefit |
|---|---|
| Post-Quantum Security | Based on hash-based commitments resistant to quantum attacks |
| Space Efficiency | Streaming memory architecture enables proving on resource-constrained devices |
| Client-Side Proving | Compiles to WebAssembly for browser-based proof generation via WebGPU |
| No Trusted Setup | Transparent setup eliminates trusted third parties |
Note: We are actively exploring additional proving systems optimized for more compact proof sizes, efficient on-chain verification, and customized circuit architectures. Future releases may support multiple backends depending on deployment requirements.
Ed25519 operates over a prime field (2^255 - 19) that lacks sufficient roots of unity for efficient FFT operations. Ligetron requires FFT-friendly fields with smooth-order multiplicative subgroups (specifically BN254).
Our Solution: We implement non-native field arithmetic, decomposing Ed25519 field elements into three 85-bit limbs that fit within the BN254 scalar field. This enables emulated arithmetic with careful carry and overflow handling, at the cost of increased constraint count (around 70% of our circuit).
The ZK circuit proves the following relation:
R = { (pk, msg, hx) | ∃ seed such that
pk = HashToScalar(SHA-512(seed)[:32]) · G
∧ hx = SHA-512(msg || seed) }
Where:
seedis the 32-byte EdDSA private seed (secret witness)pkis the 32-byte Ed25519 public key (public input)msgis the 32-byte message (public input)hxis the 64-byte hash commitment (public input)Gis the Ed25519 generator point
- Public Key Derivation: The provided public key was correctly derived from the secret seed following RFC 8032
- Hash Commitment: Knowledge of the seed via
hx = SHA-512(msg || seed)
This enables a user to authorize post-quantum transactions or key rotations by proving seed ownership, without ever revealing the seed or the derived private scalar.
Ed25519 field elements (255 bits) are represented as vectors of three BN254 field elements:
element = limbs[2] + limbs[1] × 2^85 + limbs[0] × 2^170
Key implementation details:
- Lazy Reduction: Additions accumulate without immediate modular reduction
- Modular Folding: Multiplication uses 2^255 ≡ 19 (mod p) for efficient reduction
- Extended Edwards Coordinates: Point operations use (X, Y, Z, T) representation for complete addition formulas
Files added to the base Ligetron v1.1.0 release:
sdk/cpp/
├── examples/
│ ├── PQChain/
│ │ └── pqchain.cpp # Main ZK circuit implementation
│ └── CMakeLists.txt # Updated to compile pqchain circuit
├── include/
│ └── ligetron/
│ ├── ed25519.h # Ed25519 emulated arithmetic header
│ └── sha512.h # SHA-512 header
└── src/
├── ed25519.cpp # Ed25519 non-native field arithmetic
└── sha512.cpp # SHA-512 implementation
| File | Description |
|---|---|
pqchain.cpp |
ZK circuit verifying EdDSA public key derivation and hash commitment |
ed25519.cpp |
Complete Ed25519 implementation: field emulation, point arithmetic, scalar multiplication |
ed25519.h |
Defines ed25519, ed25519_emulated, and ed25519_point structures |
sha512.cpp |
SHA-512 and HMAC-SHA-512 for RFC 8032 key derivation |
sha512.h |
SHA-512 function declarations |
Follow the standard Ligetron setup instructions for your platform.
Note: Setup instructions are adapted from the Ligetron zkVM documentation.
macOS Setup
Install Homebrew if not already installed:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Install dependencies:
brew install cmake gmp mpfr libomp llvm boostUbuntu Setup
Update your system:
sudo apt-get update && sudo apt-get upgrade -yInstall dependencies:
sudo apt-get install g++ libgmp-dev libtbb-dev cmake libssl-dev libboost-all-dev git -yInstall X11 libraries:
sudo apt install libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libx11-xcb-devInstall g++ 13:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install g++-13
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 20
sudo update-alternatives --set g++ "/usr/bin/g++-13"Install Vulkan:
sudo apt install libvulkan1 vulkan-toolsUpgrade CMake:
sudo apt remove --purge cmake && sudo apt autoremove
sudo apt install -y software-properties-common lsb-release wget gpg
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
sudo apt update && sudo apt install cmakeInstall NVIDIA drivers (if applicable):
sudo apt purge nvidia*
sudo apt install nvidia-driver-535 nvidia-dkms-535 nvidia-utils-535
sudo rebootInstall OpenGL:
sudo apt install mesa-common-dev libgl1-mesa-devInstall Emscripten
Emscripten is required for building the WebAssembly version:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.shAdd the following to your shell profile (e.g., ~/.bashrc or ~/.zshrc) for persistence:
source /path/to/emsdk/emsdk_env.shgit clone https://dawn.googlesource.com/dawn
cd dawn/
git checkout cec4482eccee45696a7c0019e750c77f101ced04
mkdir release && cd release
cmake -DDAWN_FETCH_DEPENDENCIES=ON -DDAWN_BUILD_MONOLITHIC_LIBRARY=STATIC -DDAWN_ENABLE_INSTALL=ON -DCMAKE_BUILD_TYPE=Release ..
make -j
make installgit clone https://github.com/WebAssembly/wabt.git
cd wabt
git submodule update --init
mkdir build && cd build
cmake -DCMAKE_CXX_COMPILER=g++-13 .. # Ubuntu
# cmake -DCMAKE_CXX_COMPILER=clang++ .. # macOS
make -j
sudo make installgit clone https://github.com/SoundnessLabs/pqchain.git
cd pqchainFrom the project root directory:
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
makeFirst, make sure Emscripten is installed and activated on your system. See Install Emscripten for details.
Before we continue, it's important to understand how the web build works:
- All dependencies must be built as WASM and installed to
<path-to-wasm-libs>. To make life easier, we provide a repo that contains precompiled dependencies: wasm-libs. - To avoid uploading the shader and application each time you open the page, we use Emscripten's preload feature. All contents in the
<build-directory>/packfolder will be automatically bundled at compile time. (Remember to clear the cache after changing the contents since it won't trigger a recompile.) - The target prover/verifier WASM will be embedded in an HTML shell (the default one is
emscripten_templates/edit_distance.html). Depending on your needs, you can customize the shell to take a different number of inputs.
From the project root directory:
mkdir -p build-web && cd build-web
# Build system will automatically create "pack" bundle subdirectory in the build directory,
# and copy directory with WebGPU shaders there
#
# (Optional) If you need to copy the application WASM into the bundle:
mkdir pack # Manually pre-create the preload bundle directory
cp app.wasm pack/ # Copy the application into the bundle directory
#
emcmake cmake -DCMAKE_BUILD_TYPE=Web -DCMAKE_PREFIX_PATH=<path-to-wasm-libs> ..
emmake makeFrom the build directory:
./webgpu_prover '{
"program": "../sdk/cpp/build/examples/pqchain.wasm",
"shader-path": "../shader",
"packing": 8192,
"private-indices": [1],
"args": [
{"hex": "0574b75998ea6340a30096cc3b681347edae548ad43ce731873cf3b94b1b6d2d"},
{"hex": "d7e347f6f9b6a9f19460ac13d40bff77eb910a73d51d1eb4dc0dc950dd12c5da"},
{"hex": "5468697320697320612074657374206d65737361676500000000000000000000"},
{"hex": "cca8dcd0056ec5245982179a6916bbc6e4232dd58260c3bb73859021530d7f1c2dcb514dc23b6a4e0c45dac43bcc7dab05ce14fdc17fd466a772678c1cc268d5"}
]
}'The verifier uses obscured (zeroed) private inputs:
./webgpu_verifier '{
"program": "../sdk/cpp/build/examples/pqchain.wasm",
"shader-path": "../shader",
"packing": 8192,
"private-indices": [1],
"args": [
{"hex": "0000000000000000000000000000000000000000000000000000000000000000"},
{"hex": "d7e347f6f9b6a9f19460ac13d40bff77eb910a73d51d1eb4dc0dc950dd12c5da"},
{"hex": "5468697320697320612074657374206d65737361676500000000000000000000"},
{"hex": "cca8dcd0056ec5245982179a6916bbc6e4232dd58260c3bb73859021530d7f1c2dcb514dc23b6a4e0c45dac43bcc7dab05ce14fdc17fd466a772678c1cc268d5"}
]
}'| Index | Field | Type | Size | Privacy | Description |
|---|---|---|---|---|---|
| 1 | seed |
hex | 32 bytes | PRIVATE | EdDSA seed (secret witness) |
| 2 | pk |
hex | 32 bytes | Public | Expected Ed25519 public key |
| 3 | msg |
hex | 32 bytes | Public | Message (zero-padded) |
| 4 | hx |
hex | 64 bytes | Public | Hash commitment SHA-512(msg ‖ seed) |
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
program |
string | ✓ | — | Path to the WASM circuit |
shader-path |
string | "./shader" |
Path to GPU shaders | |
packing |
int | 8192 | FFT packing size | |
private-indices |
[int] | [] | Indices of private arguments (1-indexed) | |
args |
[object] | [] | Circuit arguments | |
gpu-threads |
int | packing | Number of GPU threads |
Platform: MacBook Pro M4 (12 cores, 24 GB RAM)
Methodology: Average over 100 runs
| Metric | Value |
|---|---|
| Proving Time | 5.4 seconds |
| Verification Time | 2.3 seconds |
| Proof Size | 5.4 MB |
| Memory Usage | 34 MB |
| Linear Constraints | 331,238 |
| Quadratic Constraints | 4,592,987 |
| Total Constraints | 4,924,225 |
| Component | Constraints | Percentage |
|---|---|---|
| Non-native field emulation & scalar multiplication | ~3.4M | ~70% |
| SHA-512 operations | ~1.0M | ~20% |
| Other (comparisons, assertions) | ~0.5M | ~10% |
A fully functional browser-based demonstration is available for testing the client-side proof generation without installing dependencies.
Live Demo: https://PQChain.vercel.app/
- Client-Side Proving: All proof generation occurs in the browser using WebGPU
- No Server Interaction: Private keys never leave your machine
- Wallet Integration: Supports Slush and Phantom wallet connections (TESTNET only)
- Real-Time Benchmarks: View detailed timing breakdown for each proving stage
- Chrome 113+ or Edge 113+ with WebGPU support
- GPU with WebGPU/Vulkan support
- Minimum 4GB VRAM (8GB+ recommended)
- Navigate to https://PQChain.vercel.app/
- Accept the security disclaimer (this is a TESTNET demonstration only)
- Connect a Slush or Phantom wallet
- (Optional) Configure transaction details
- Scroll to "Proof Generation" section
- Click "Generate Proof"
- View the proof output and timing breakdown
Important Warnings:
- This is an experimental proof-of-concept for research purposes only
- TESTNET ONLY — never use with mainnet or real assets
- Private keys are displayed in the browser for demonstration purposes
- Create fresh test accounts and delete them after testing
- Do not reuse test keys for any other purpose
Build Issues
CMake cannot find dependencies
- Ensure all prerequisites are installed
- Check that paths are correctly set in environment variables
Compilation errors with g++
- Verify g++ 13 is installed:
g++ --version - Set as default:
sudo update-alternatives --set g++ /usr/bin/g++-13
WebGPU/Dawn build failures
- Ensure you've checked out the correct Dawn commit
- Try a clean build:
rm -rf release && mkdir release && cd release
Runtime Issues
CORS errors when opening HTML in browser
- Don't open the HTML file directly; use
emrunor a local HTTP server - Example:
python3 -m http.server 8000then navigate tolocalhost:8000
Proof verification fails
- Ensure the public inputs match between prover and verifier
- Check that
private-indicesis correctly specified
We welcome contributions! Please note that this project is still under active development.
git clone https://github.com/SoundnessLabs/pqchain.git
cd pqchain
# Follow build instructions aboveLicensed under the Apache License, Version 2.0.
Copyright 2023-2026 Soundness Labs Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This implementation draws inspiration from several open-source projects:
- Electron-Labs/ed25519-circom for non-native field emulation techniques
- Arkworks algebra for Ed25519 curve constants
- LibTomCrypt for SHA-512 primitives
Soundness Labs builds quantum-ready cryptographic infrastructure for blockchains, replacing fragile trust with verifiable security. We design post-quantum and zero-knowledge systems that protect digital assets today and keep them safe in a quantum future.
- Website: soundness.xyz
- GitHub: github.com/SoundnessLabs
- Twitter/X: @SoundnessLabs
By Soundness Labs
Towards building a Sound Internet.