Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/distributed-lab/bulletproofs
Bulletproofs++ implementation on Go
https://github.com/distributed-lab/bulletproofs
blockhain bulletproofs cryptography zero-knowledge
Last synced: about 2 months ago
JSON representation
Bulletproofs++ implementation on Go
- Host: GitHub
- URL: https://github.com/distributed-lab/bulletproofs
- Owner: distributed-lab
- License: mit
- Created: 2024-02-26T00:04:02.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-06-20T12:52:37.000Z (7 months ago)
- Last Synced: 2024-06-22T04:49:01.038Z (7 months ago)
- Topics: blockhain, bulletproofs, cryptography, zero-knowledge
- Language: Go
- Homepage: https://distributedlab.com/whitepaper/Bulletproofs-Construction-and-Examples.pdf
- Size: 79.1 KB
- Stars: 22
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Bulletproofs++ implementation
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
⚠️ __Please note - this crypto library has not been audited, so use it at your own risk.__
## Abstract
Present Go library contains the implementation of Bulletproofs++ weight norm linear argument protocol, arithmetic
circuit
protocol and reciprocal range proof protocol described in Distributed
Lab's [Bulletproofs++ Construction and Examples](https://distributedlab.com/whitepaper/Bulletproofs-Construction-and-Examples.pdf).Explore the [circuit_test.go](./circuit_test.go) to check the examples of circuit prove and verification.
It contains several circuits:- Prove that we know such `x, y` that `x+y=r` and `x*y=z` for public `r, z`. This example encoded directly into the BP++
circuits.
- Prove the range for 4-bits value: `x` is in `[0..2^n)` range (simple binary range proof).Also, [reciprocal_test.go](./reciprocal_test.go) contains example of proving that value lies in [0, 16^n) range.
Implemented protocol has 2G points advantage over existing BP and BP+ protocols on proving of one 64-bit value and this
advantage will increase for more values per proof.| Protocol | G | F |
|----------|----|---|
| BP | 16 | 5 |
| BP+ | 15 | 3 |
| Our BP++ | 13 | 3 |## Reciprocal range proofs
Check the following snippet as an example of usage of range proof protocol:
```go
package mainimport (
"github.com/cloudflare/bn256"
"github.com/distributed-lab/bulletproofs"
"math/big"
)func main() {
// The uint64 in 16-base system will be encoded in 16 digits.
// The 16 base is selected as the most optimal base for this case.// Our private value is 0xab4f0540ab4f0540.
x := uint64(0xab4f0540ab4f0540)
X := new(big.Int).SetUint64(x)// Let's encode it as a list of digits:
digits := bulletproofs.UInt64Hex(x) // [0 4 5 0 15 4 11 10 0 4 5 0 15 4 11 10]// Public poles multiplicities i-th element corresponds to the 'i-digit' multiplicity (the count of 'i-digit' in digits list)
m := bulletproofs.HexMapping(digits) // [4 0 0 0 4 2 0 0 0 0 2 2 0 0 0 2]Nd := 16 // digits size
Np := 16 // base sizevar G *bn256.G1
// Length of our base points vector should be a power ot 2 to be used in WNLA protocol.
// So cause the real HVec size in circuit is `Nd+10` the nearest length is 32
var GVec []*bn256.G1 // len = 16
var HVec []*bn256.G1 // len = 32public := &bulletproofs.ReciprocalPublic{
G: G,
GVec: GVec[:Nd],
HVec: HVec[:Nd+10],
Nd: Nd,
Np: Np,// Remaining points that will be used in WNLA protocol
GVec_: GVec[Nd:],
HVec_: HVec[Nd+10:],
}private := &bulletproofs.ReciprocalPrivate{
X: x, // Committed value
M: m, // Corresponding multiplicities
Digits: digits, // Corresponding digits
S: MustRandScalar(), // Blinding value (secret) used for committing value as: x*G + Sx*H
}VCom := public.CommitValue(private.X, private.Sx) // Value commitment: x*G + Sx*H
// Use NewKeccakFS or your own implementation for the Fiat-Shamir heuristics.
proof := bulletproofs.ProveRange(public, bulletproofs.NewKeccakFS(), private)// If err is nil -> proof is valid.
if err := bulletproofs.VerifyRange(public, VCom, bulletproofs.NewKeccakFS(), proof); err != nil {
panic(err)
}
}```
## Weight norm linear argument (WNLA)
The [wnla.go](./wnla.go) contains the implementation of **weight norm linear argument** protocol. This is a fundamental
basis for arithmetic circuit protocol. It uses the Fiat-Shamir heuristics from [fs.go](./fs.go) to generate challenges
and make protocol non-interactive.Check the following snippet with an example of WNLA usage:
```go
package mainimport (
"github.com/distributed-lab/bulletproofs"
"math/big"
)func main() {
public := bulletproofs.NewWeightNormLinearPublic(4, 2)// Private
l := []*big.Int{big.NewInt(4), big.NewInt(5), big.NewInt(10), big.NewInt(1)}
n := []*big.Int{big.NewInt(2), big.NewInt(1)}proof := bulletproofs.ProveWNLA(public, public.Commit(l, n), bulletproofs.NewKeccakFS(), l, n)
if err := bulletproofs.VerifyWNLA(public, proof, public.Commit(l, n), bulletproofs.NewKeccakFS()); err != nil {
panic(err)
}
}```
## Arithmetic circuit
The [circuit.go](./circuit.go) contains the implementation of BP++ arithmetic circuit protocol.
It runs the WNLA protocol as the final stages of proving/verification. Uses the Fiat-Shamir heuristics
from [fs.go](./fs.go) to generate challenges
and make protocol non-interactive.Check the following snippet with an example of arithmetic circuit protocol usage:
```go
package mainimport (
"github.com/cloudflare/bn256"
"github.com/distributed-lab/bulletproofs"
)func main() {
public := &bulletproofs.ArithmeticCircuitPublic{
Nm,
Nl, // Nl = Nv * K
Nv, // Size on any v witness vector
Nw, // Nw = Nm + Nm + No
No,
K, // count of v witnesses vectors
G,// points that will be used directly in circuit protocol
GVec[:Nm], // Nm
HVec[:Nv+9], // Nv+9// Circuit definition
Wm, // Nm * Nw
Wl, // Nl * Nw
Am, // Nm
Al, // Nl
Fl,
Fm,// Partition function
F: func(typ bulletproofs.PartitionType, index int) *int {
// define
return nil
},// points that will be used in WNLA protocol to make vectors 2^n len
HVec[Nv+9:], // 2^x - (Nv+9) dimension
GVec[Nm:], // 2^y - Nm dimension
}private := &bulletproofs.ArithmeticCircuitPrivate{
V, // witness vectors v, dimension k*Nv
Sv, // witness blinding values, dimension k
Wl, // Nm
Wr, // Nm
Wo, // No
}// Commitments to the v witness vectors
V := make([]*bn256.G1, public.K)
for i := range V {
V[i] = public.CommitCircuit(private.V[i], private.Sv[i], public.G, public.HVec)
}proof := bulletproofs.ProveCircuit(public, bulletproofs.NewKeccakFS(), private)
if err := bulletproofs.VerifyCircuit(public, V, bulletproofs.NewKeccakFS(), proof); err != nil {
panic(err)
}
}
```