Files
crypto/docs/content/docs/verkle-ipa.mdx
T
Hanzo AI d2d6bceb89 ipa: fix stale banderwagon import path
Replace github.com/luxfi/crypto/ipa/banderwagon with the canonical
github.com/luxfi/crypto/banderwagon in ipa/batch.go and its test, plus
the verkle-ipa docs example and the rust spec_vectors comment. The old
ipa/banderwagon subdirectory was deleted in 222f3d8; banderwagon now
has a single canonical home at the top level of luxfi/crypto.

go.mod adds the indirect entries for go-verkle and go-ipa that the
rerouted test_helper graph now exercises. The luxfi-mirror replace
directives remain in place so all upstream go-ipa/go-verkle traffic
still flows through luxfi-maintained sources.

Build: go build ./... clean (one ld linker warning unrelated).
Tests: ./banderwagon/... ./ipa/... pass (7 ok, 2 no-test-files).

Pre-existing failure in ./verkle/ is unrelated: verkle_test.go
references BatchProof/VerifyBatch/ErrBatchLengthMismatch symbols that
were never implemented in the verkle package (separate gap, present on
main before this fix).
2026-04-28 01:54:51 -07:00

469 lines
10 KiB
Plaintext

---
title: Inner Product Arguments (IPA) & Verkle Trees
description: Cryptographic primitives for Verkle tree state commitments and proofs
---
# Inner Product Arguments (IPA) & Verkle Trees
IPA (Inner Product Arguments) provide the cryptographic foundation for Verkle trees, enabling efficient state proofs with smaller proof sizes than Merkle Patricia Trees.
## Overview
Verkle trees with IPA provide:
- **Smaller Proofs**: ~150 bytes vs ~1 KB for Merkle proofs
- **Efficient Updates**: O(log n) complexity for state updates
- **Constant Verification**: Fixed verification cost regardless of tree depth
- **State Commitment**: Compact commitment to entire blockchain state
## Technical Details
### Bandersnatch Curve
The implementation uses the Bandersnatch curve:
| Parameter | Value |
|-----------|-------|
| Curve | Bandersnatch (embedded in BLS12-381) |
| Field Size | 253 bits |
| Group Order | ~2^253 |
| Security Level | 128 bits |
### IPA Parameters
| Parameter | Value |
|-----------|-------|
| Vector Length | 256 |
| Number of Rounds | 8 (log2(256)) |
| Commitment Size | 32 bytes |
| Proof Size | ~544 bytes |
## Implementation
### Setting Up IPA
```go
package main
import (
"fmt"
"github.com/luxfi/crypto/ipa/ipa"
"github.com/luxfi/crypto/banderwagon"
"github.com/luxfi/crypto/ipa/bandersnatch/fr"
)
func main() {
// Initialize IPA settings (generates SRS)
config, err := ipa.NewIPASettings()
if err != nil {
panic(err)
}
fmt.Printf("SRS contains %d points\n", len(config.SRS))
fmt.Printf("Number of rounds: %d\n", config.NumRounds())
}
```
### Pedersen Commitments
Create commitments to polynomials:
```go
func commitToPolynomial(config *ipa.IPAConfig, polynomial []fr.Element) banderwagon.Element {
// Commit using precomputed MSM
commitment := config.Commit(polynomial)
fmt.Printf("Commitment: %x\n", commitment.Bytes())
return commitment
}
// Create polynomial from data
func createPolynomial(data []byte) []fr.Element {
poly := make([]fr.Element, 256)
for i := 0; i < len(data) && i < 256; i++ {
poly[i].SetUint64(uint64(data[i]))
}
return poly
}
```
### Inner Product Computation
Compute inner products of vectors:
```go
func computeInnerProduct(a, b []fr.Element) (fr.Element, error) {
if len(a) != len(b) {
return fr.Element{}, errors.New("vectors must have same length")
}
result, err := ipa.InnerProd(a, b)
if err != nil {
return fr.Element{}, err
}
fmt.Printf("Inner product: %s\n", result.String())
return result, nil
}
```
### Multi-Scalar Multiplication
Efficient MSM for group operations:
```go
func multiScalarMult(points []banderwagon.Element, scalars []fr.Element) (banderwagon.Element, error) {
result, err := ipa.MultiScalar(points, scalars)
if err != nil {
return banderwagon.Element{}, err
}
return result, nil
}
```
## Verkle Tree Structure
### Node Types
```go
type VerkleNode interface {
Commitment() banderwagon.Element
Hash() []byte
}
type InternalNode struct {
children [256]VerkleNode
commitment banderwagon.Element
}
type LeafNode struct {
stem [31]byte
values [256][]byte
commitment banderwagon.Element
}
type EmptyNode struct{}
```
### Tree Operations
```go
type VerkleTree struct {
root VerkleNode
config *ipa.IPAConfig
}
func NewVerkleTree(config *ipa.IPAConfig) *VerkleTree {
return &VerkleTree{
root: &EmptyNode{},
config: config,
}
}
// Insert a key-value pair
func (t *VerkleTree) Insert(key []byte, value []byte) error {
stem := key[:31]
suffix := key[31]
// Navigate to leaf, creating nodes as needed
// Update commitments along the path
return nil
}
// Get a value by key
func (t *VerkleTree) Get(key []byte) ([]byte, error) {
stem := key[:31]
suffix := key[31]
// Navigate to leaf
// Return value at suffix position
return nil, nil
}
// Generate proof for a key
func (t *VerkleTree) Prove(key []byte) (*VerkleProof, error) {
// Generate IPA proof for the path
return nil, nil
}
```
## IPA Proof Generation
### Prover
```go
type IPAProver struct {
config *ipa.IPAConfig
}
func (p *IPAProver) CreateProof(
commitment banderwagon.Element,
polynomial []fr.Element,
point fr.Element,
) (*IPAProof, error) {
// Generate IPA proof that polynomial evaluates to
// a specific value at the given point
proof := &IPAProof{
L: make([]banderwagon.Element, p.config.NumRounds()),
R: make([]banderwagon.Element, p.config.NumRounds()),
}
// Prover algorithm:
// 1. Split vectors in half
// 2. Compute cross terms L and R
// 3. Get challenge from verifier (Fiat-Shamir)
// 4. Fold vectors
// 5. Repeat for log(n) rounds
return proof, nil
}
type IPAProof struct {
L []banderwagon.Element // Left cross terms
R []banderwagon.Element // Right cross terms
A fr.Element // Final scalar
}
```
### Verifier
```go
type IPAVerifier struct {
config *ipa.IPAConfig
}
func (v *IPAVerifier) VerifyProof(
commitment banderwagon.Element,
point fr.Element,
evaluation fr.Element,
proof *IPAProof,
) bool {
// Verify IPA proof
// Verifier algorithm:
// 1. Recompute challenges from L, R values
// 2. Compute final commitment
// 3. Check against claimed evaluation
return true
}
```
## Multi-Proof System
Efficient proofs for multiple keys:
```go
type MultiProof struct {
D banderwagon.Element // Commitment to quotient polynomial
IPAProof *IPAProof // IPA proof for evaluation
ClaimedValues []fr.Element // Values at queried positions
}
func CreateMultiProof(
config *ipa.IPAConfig,
commitments []banderwagon.Element,
polynomials [][]fr.Element,
points []fr.Element,
) (*MultiProof, error) {
// Create proof for multiple polynomial evaluations
return nil, nil
}
func VerifyMultiProof(
config *ipa.IPAConfig,
commitments []banderwagon.Element,
points []fr.Element,
values []fr.Element,
proof *MultiProof,
) bool {
// Verify multi-proof
return true
}
```
## State Management
### State Commitment
```go
type StateCommitment struct {
Root banderwagon.Element
BlockNum uint64
StateRoot []byte
}
func (s *StateCommitment) Update(changes map[string][]byte) (*StateCommitment, error) {
// Apply changes to state tree
// Recompute affected commitments
// Return new state commitment
return nil, nil
}
```
### Witness Generation
```go
type ExecutionWitness struct {
StateDiff []KeyValuePair
VerkleProof *MultiProof
ParentState []byte
}
func GenerateWitness(
tree *VerkleTree,
accessedKeys [][]byte,
) (*ExecutionWitness, error) {
// Generate witness for accessed state
return nil, nil
}
```
## Performance Benchmarks
| Operation | Time | Notes |
|-----------|------|-------|
| Commit (256 values) | 2.5 ms | Using precomputed MSM |
| IPA Prove | 15 ms | 8 rounds |
| IPA Verify | 8 ms | Single proof |
| Multi-proof (100 keys) | 150 ms | Batched |
| Multi-verify (100 keys) | 50 ms | Batched |
### Proof Sizes
| Proof Type | Size |
|------------|------|
| Single IPA proof | 544 bytes |
| Verkle proof (depth 4) | ~600 bytes |
| Multi-proof (10 keys) | ~1.5 KB |
| Multi-proof (100 keys) | ~3 KB |
## Comparison with Merkle Trees
| Aspect | Merkle Patricia | Verkle |
|--------|-----------------|--------|
| Proof size | ~1-3 KB | ~150-600 bytes |
| Update complexity | O(log n) | O(log n) |
| Verification | O(log n) hashes | O(1) pairings |
| Witness size | Large | Small |
| Statelessness | Difficult | Feasible |
## Security Properties
### Binding
```go
// Commitments are computationally binding
// Cannot find two different polynomials with same commitment
func demonstrateBinding() {
config, _ := ipa.NewIPASettings()
poly1 := make([]fr.Element, 256)
poly2 := make([]fr.Element, 256)
poly1[0].SetUint64(1)
poly2[0].SetUint64(2)
c1 := config.Commit(poly1)
c2 := config.Commit(poly2)
// c1 != c2 with overwhelming probability
}
```
### Soundness
```go
// Cannot create valid proof for incorrect evaluation
// Soundness relies on discrete log hardness in Bandersnatch
func testSoundness(t *testing.T) {
// Create proof for correct evaluation
// Try to verify with wrong evaluation value
// Must fail
require.False(t, verifier.VerifyProof(commitment, point, wrongValue, proof))
}
```
## Integration with Lux
### Block State Root
```go
type LuxBlock struct {
Header *BlockHeader
Transactions []*Transaction
VerkleRoot banderwagon.Element
}
func (b *LuxBlock) ComputeStateRoot(tree *VerkleTree) {
b.VerkleRoot = tree.root.Commitment()
}
```
### Stateless Validation
```go
type StatelessValidator struct {
config *ipa.IPAConfig
}
func (v *StatelessValidator) ValidateBlock(
block *LuxBlock,
witness *ExecutionWitness,
) error {
// Verify witness against parent state
// Execute transactions using witness data
// Verify resulting state matches block state root
return nil
}
```
## Testing
```go
func TestIPACommitment(t *testing.T) {
config, err := ipa.NewIPASettings()
require.NoError(t, err)
// Create polynomial
poly := make([]fr.Element, 256)
for i := 0; i < 256; i++ {
poly[i].SetUint64(uint64(i))
}
// Commit
commitment := config.Commit(poly)
require.False(t, commitment.IsIdentity())
// Same polynomial should give same commitment
commitment2 := config.Commit(poly)
require.True(t, commitment.Equal(&commitment2))
// Different polynomial should give different commitment
poly[0].SetUint64(999)
commitment3 := config.Commit(poly)
require.False(t, commitment.Equal(&commitment3))
}
```
## References
- [Verkle Trees](https://vitalik.ca/general/2021/06/18/verkle.html)
- [Inner Product Arguments](https://eprint.iacr.org/2019/1021)
- [Bandersnatch Curve](https://eprint.iacr.org/2021/1152)
- [go-verkle Implementation](https://github.com/ethereum/go-verkle)
- [EIP-6800: Ethereum state using a Verkle tree](https://eips.ethereum.org/EIPS/eip-6800)