{"slug": "show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments", "title": "Show HN: CUDA-verkle – GPU-accelerated 256-MSM for Verkle tree commitments", "summary": "A C++/CUDA research implementation called CUDA-verkle has been released, providing GPU-accelerated 256-element multi-scalar multiplication (MSM) for Pedersen vector commitments over the Banderwagon group targeting Ethereum's Verkle tree proposal EIP-6800. The project covers Montgomery field arithmetic, twisted Edwards curve operations, Pippenger MSM, Pedersen commitments, 256-element IPA opening proofs, and an EIP-6800 sparse key/value state tree, with host unit, property, differential, IPA, and state-tree tests passing alongside a windowed CUDA Pippenger MSM with batched, stream-aware execution. The author states the software remains experimental and not production-ready, requiring NVIDIA hardware validation and an independent cryptographic audit before any production claim.", "body_md": "A C++/CUDA research implementation of Pedersen vector commitments over the Banderwagon group, targeting Ethereum's Verkle tree proposal ([EIP-6800](https://eips.ethereum.org/EIPS/eip-6800)).\n\nCovers the core commitment stack: Montgomery field arithmetic → twisted Edwards curve operations → Pippenger multi-scalar multiplication → Pedersen commitments → 256-element IPA opening proofs → an EIP-6800 sparse key/value state tree. The tree implements extension/suffix nodes, absent-vs-zero leaf encoding, recursive main-tree commitments, EIP-6800 `group_to_scalar_field`, and Pedersen state-key derivation. It remains experimental cryptographic software, not production-ready.\n\nThe state tree exposes `set`, `get`, `erase`, `root`, `serialize`/` deserialize`, and `save`/` load`. Its versioned persistence format stores canonical, lexicographically ordered key/value records and reconstructs the branch/extension topology on load; malformed or non-canonical snapshots are rejected without modifying the loaded tree.\n\nSerialized public inputs must use the strict decoding APIs: `fr_from_bytes_strict` accepts only canonical 32-byte big-endian scalars, while `bw_from_bytes_strict` additionally recovers the curve point and rejects off-curve and non-subgroup Banderwagon encodings. These validation routines are variable-time and must not be used with secret inputs.\n\n**Status:** Host unit, property, differential, IPA, and EIP-6800 state-tree tests pass. A windowed CUDA Pippenger MSM with batched, stream-aware execution, GPU integration tests, and CUDA-event benchmarking is included. CI builds host and CUDA targets and scans committed secrets and Rust dependencies; NVIDIA hardware validation and an independent cryptographic audit remain required before any production claim.\n\nEthereum's state transition requires recomputing Pedersen commitments over 256-wide vectors on every block. Each commitment is a multi-scalar multiplication (MSM) of 256 scalars against a fixed basis on the Banderwagon curve. Every existing implementation ([rust-verkle](https://github.com/crate-crypto/rust-verkle), [go-verkle](https://github.com/crate-crypto/go-ipa), [constantine](https://github.com/mratsim/constantine)) runs on CPU. This project explores GPU acceleration of that inner loop.\n\nAny C++17 compiler (`clang++` or `g++`) works directly:\n\n```\ngit clone <this-repo> && cd cuda-verkle\n\n# Run host unit, property, differential, and state-tree tests\nc++ -std=c++17 -x c++ -O2 -I src -o test_field tests/test_field.cu && ./test_field\nc++ -std=c++17 -x c++ -O2 -I src -o test_curve tests/test_curve.cu && ./test_curve\nc++ -std=c++17 -x c++ -O2 -I src -o test_msm tests/test_msm.cu src/msm/msm_kernel.cu && ./test_msm\nc++ -std=c++17 -x c++ -O2 -I src -o test_commitment tests/test_commitment.cu src/msm/msm_kernel.cu src/commitment/pedersen.cu && ./test_commitment\nc++ -std=c++17 -x c++ -O2 -I src -o test_tree tests/test_tree.cu src/msm/msm_kernel.cu && ./test_tree\nc++ -std=c++17 -x c++ -O2 -I src -o test_properties tests/test_properties.cu src/msm/msm_kernel.cu && ./test_properties\nc++ -std=c++17 -x c++ -O2 -I src -o test_ipa tests/test_ipa.cu src/msm/msm_kernel.cu && ./test_ipa\n\n# Run CPU benchmarks\nc++ -std=c++17 -x c++ -O2 -I src -o bench src/benchmark/bench_msm.cu src/msm/msm_kernel.cu && ./bench\n```\n\nIf you have an NVIDIA GPU and the CUDA Toolkit installed:\n\n```\n# Compile and run test suite with nvcc\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_field tests/test_field.cu && ./test_field\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_curve tests/test_curve.cu && ./test_curve\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_msm tests/test_msm.cu src/msm/msm_kernel.cu && ./test_msm\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_commitment tests/test_commitment.cu src/msm/msm_kernel.cu src/commitment/pedersen.cu && ./test_commitment\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_tree tests/test_tree.cu src/msm/msm_kernel.cu && ./test_tree\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_msm_gpu tests/test_msm_gpu.cu src/msm/msm_kernel.cu && ./test_msm_gpu\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o test_ipa tests/test_ipa.cu src/msm/msm_kernel.cu && ./test_ipa\n\n# Compile and run benchmarks\nnvcc -std=c++17 -O3 -I src -arch=sm_75 -o bench src/benchmark/bench_msm.cu src/msm/msm_kernel.cu && ./bench\n```\n\n**Target Architecture (`-arch=sm_XX`):**\n\n`sm_75` — Tesla T4 / Turing (Google Colab free tier)\n`sm_80` — A100 / Ampere\n`sm_86` — RTX 3080 / 3090\n`sm_89` — RTX 4080 / 4090 / Ada Lovelace\n\n```\nmkdir build && cd build\ncmake .. -DCMAKE_CUDA_ARCHITECTURES=75\nmake -j$(nproc)\nctest --output-on-failure\n```\n\n1. \nOpen a new notebook on [Google Colab](https://colab.research.google.com) .\n2. \nSet runtime to **GPU** (`Runtime` →`Change runtime type` →`T4 GPU` ).\n3. \nClone and run the complete validation script: \n\n```\n!git clone https://github.com/<your-username>/cuda-verkle.git\n%cd cuda-verkle\n!chmod +x scripts/run_gpu_validation.sh\n!CUDA_ARCH=75 ./scripts/run_gpu_validation.sh\n```\n\n The script checks the GPU/toolkit, performs a Release CMake build, runs every test (including `test_msm_gpu` ), then runs the GPU benchmark. Change`CUDA_ARCH` if the GPU is not a T4:`80` for A100,`86` for RTX 30-series,\nor`89` for RTX 40-series. Save the full output together with`git rev-parse HEAD` ; it is the hardware-validation record for that commit.\n\n```\ndocker compose build\ndocker compose run --rm cuda-verkle bash -c \"cd build && ctest --output-on-failure\"\n```\n\nBefore relying on a CUDA result, run the Colab validation script from a clean checkout and retain its complete output. A successful run must show:\n\n- all host suites passing;\n- `TestMSMGPU` passing rather than being skipped;\n- the benchmark reporting `First result matches CPU: yes` ; and\n- the GPU name, driver version, CUDA version, and commit recorded by the script.\n\nHardware validation demonstrates correctness only for the tested GPU, driver,\nand CUDA combination. It does not replace the independent cryptographic audit\nrequired by [`SECURITY.md`](https://github.com/Dyslex7c/cuda-verkle/blob/main/SECURITY.md).\n\nThe host suites include deterministic known-answer tests generated by the locked Rust reference dependencies: field arithmetic, 256-wide Pedersen commitments, logarithmic 256-element IPA opening proofs, and depth-1 incremental tree updates. IPA tests compare the exact compressed proof encoding and verify a proof generated independently by the Rust reference. They complement algebraic identities, on-curve verification of CRS points, CPU/GPU-windowed Pippenger cross-validation, commitment homomorphism, and incremental-vs-full tree recomputation.\n\n`src/proof/ipa.cuh` implements the transparent Fiat–Shamir inner-product argument used by the pinned `ipa-multipoint` reference: one commitment evaluation is proven with 8 L/R rounds (544 serialized bytes). `ipa_proof_from_bytes_strict` accepts only that exact format and rejects truncated input, non-canonical scalars, malformed curve encodings, and points outside the Banderwagon subgroup before verification.\n\nThe fixtures in [`test_vectors/`](https://github.com/Dyslex7c/cuda-verkle/blob/main/test_vectors) are versioned, deterministic outputs from `rust-reference/`, which uses the pinned [rust-verkle](https://github.com/crate-crypto/rust-verkle) dependencies. Regenerate them with `make vectors` (or `cd rust-reference && cargo run --locked --release -- generate`), then review and commit the JSON diff. C++ tests fail if their required fixture is missing or malformed.\n\n`bench_msm` reports CPU reference timings on every platform. When built with\n`nvcc` and run on an NVIDIA GPU, it additionally measures batched GPU\nPippenger MSMs with CUDA events. The GPU figure is end-to-end: pinned-host\ninput transfer, scalar conversion, all window kernels, result transfer, and\nstream completion. It reports batch size, average time per 256-point MSM,\nthroughput, device name, and a CPU cross-check of the first result.\n\n| Param | Value | \n|---|---|\n| Base field Fp | BLS12-381 scalar field: p = `0x73eda753299d7d48…00000001` | \n| Scalar field Fr | Bandersnatch subgroup order: n = `0x1cfb69d4ca675f52…2876e7e1` | \n| Curve | Twisted Edwards: −5x² + y² = 1 + dx²y² | \n| Coordinates | Extended projective (X : Y : T : Z), T = XY/Z | \n| CRS | 256 generators + Q, seed `eth_verkle_oct_2021` | \n\n**Montgomery arithmetic.** Every field element is stored as a·R mod p. Multiplication uses the CIOS (Coarsely Integrated Operand Scanning) algorithm with 8 rounds of multiply-accumulate-reduce. The GPU path emits PTX `mad.lo.cc.u32` / `madc.hi.cc.u32` carry chains; the host path uses `uint64_t` widening. The n′ constant for Fp happens to be 0xFFFFFFFF, which makes the reduction step a simple multiply-by-minus-one.\n\n**Extended projective coordinates.** Storing (X, Y, T, Z) with T = XY/Z trades one extra field element per point for elimination of all inversions during addition (8M + 1D) and doubling (4S + 3M). Inversions only happen during final affine conversion for serialization.\n\n**Struct-of-Arrays CRS.** The 256 basis points are stored as `x[256]`, `y[256]` rather than `{x,y}[256]`. On GPU, this means consecutive threads in a warp read consecutive memory addresses — coalesced access at full bandwidth.\n\n**Incremental recommitment.** When leaf i changes from v to v′, the tree updates the parent commitment via C′ = C + (v′ − v) · Gᵢ — a single scalar multiplication instead of a full 256-wide MSM. This is the operation that dominates Ethereum block processing at scale.\n\n- [EIP-6800](https://eips.ethereum.org/EIPS/eip-6800) — Ethereum state using Verkle trees\n- [rust-verkle](https://github.com/crate-crypto/rust-verkle) — Canonical Rust implementation\n- [Bandersnatch](https://eprint.iacr.org/2021/1152) — Masson, Sanso, Zhang (2021)\n- [Pippenger](https://cr.yp.to/papers/pippenger.pdf) — Bucket method for multi-scalar multiplication\n\nThis project is licensed under the [MIT License](https://github.com/Dyslex7c/cuda-verkle/blob/main/LICENSE).\nSee [third-party notices](https://github.com/Dyslex7c/cuda-verkle/blob/main/THIRD_PARTY_NOTICES.md) for CRS-data provenance.", "url": "https://wpnews.pro/news/show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments", "canonical_source": "https://github.com/Dyslex7c/cuda-verkle", "published_at": "2026-09-23 13:49:26+00:00", "updated_at": "2026-09-23 13:59:48.129095+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-chips"], "entities": ["CUDA-verkle", "Ethereum", "EIP-6800", "Banderwagon", "rust-verkle", "go-verkle", "constantine", "NVIDIA"], "alternates": {"html": "https://wpnews.pro/news/show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments", "markdown": "https://wpnews.pro/news/show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments.md", "text": "https://wpnews.pro/news/show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments.txt", "jsonld": "https://wpnews.pro/news/show-hn-cuda-verkle-gpu-accelerated-256-msm-for-verkle-tree-commitments.jsonld"}}