Skip to content
This repository was archived by the owner on Sep 8, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions pkg/core/curves/native/bls12381/g1.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,28 @@ func (g1 *G1) BigInt() (x, y *big.Int) {
return
}

// SetRaw creates a point from raw arrays x, y
// and returns the point if it is on the curve
func (g1 *G1) SetRaw(x, y *[Limbs]uint64) (*G1, error) {
var xx, yy fp
var pp G1
pp.x = *(xx.SetRaw(x))
pp.y = *(yy.SetRaw(y))

if pp.x.IsZero()&pp.y.IsZero() == 1 {
pp.Identity()
return g1.Set(&pp), nil
}

pp.z.SetOne()

// If not the identity point and not on the curve then invalid
if (pp.IsOnCurve()&pp.InCorrectSubgroup())|(xx.IsZero()&yy.IsZero()) == 0 {
return nil, fmt.Errorf("invalid coordinates")
}
return g1.Set(&pp), nil
}

// SetBigInt creates a point from affine x, y
// and returns the point if it is on the curve
func (g1 *G1) SetBigInt(x, y *big.Int) (*G1, error) {
Expand Down
20 changes: 20 additions & 0 deletions pkg/core/curves/native/bls12381/g2.go
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,26 @@ func (g2 *G2) BigInt() (x, y *big.Int) {
return
}

// SetRaw creates a point from raw arrays x, y
// and returns the point if it is on the curve
func (g2 *G2) SetRaw(xc0, xc1, yc0, yc1 *[Limbs]uint64) (*G2, error) {
var p G2
p.x.A.SetRaw(xc0)
p.x.B.SetRaw(xc1)
p.y.A.SetRaw(yc0)
p.y.B.SetRaw(yc1)
p.z.SetOne()

if p.IsIdentity() == 1 {
return g2.Identity(), nil
}

if p.IsOnCurve() == 0 {
return nil, errors.New("point is not on the curve")
}
return g2.Set(&p), nil
}

// SetBigInt creates a point from affine x, y
// and returns the point if it is on the curve
func (g2 *G2) SetBigInt(x, y *big.Int) (*G2, error) {
Expand Down
221 changes: 221 additions & 0 deletions pkg/zkp/kzg/kate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package kzg

import (
crand "crypto/rand"
"fmt"
"math/big"

"github.com/coinbase/kryptology/pkg/core/curves/native"
bls "github.com/coinbase/kryptology/pkg/core/curves/native/bls12381"
"github.com/pkg/errors"
)

var (
MAX_BIG = new(big.Int)
)

func init() {
MAX_BIG.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(MAX_BIG, big.NewInt(1))
}

type KZGSetupParamaters struct {
TG1 []*bls.G1
TG2 []*bls.G2
}

// NewKZGSetupParamaters returns the kzg10 setup paramaters
func NewKZGSetupParamaters(tg1 []*bls.G1, tg2 []*bls.G2) (*KZGSetupParamaters, error) {
if len(tg1) != len(tg2) {
return nil, errors.New("Number of elements in each group must match")
}
return &KZGSetupParamaters{
TG1: tg1,
TG2: tg2,
}, nil
}

// Setup performs an untrusted ceremony and returns the kzg10 setup paramaters
func Setup(t int) ([]*bls.G1, []*bls.G2, error) {
fmt.Printf("WARNING: This is not a secure trusted setup, do not use in a production environment\n")

if t < 0 {
return nil, nil, fmt.Errorf("reference string degree must be positive")
}

// α: "hidden" number no one should know
a, err := crand.Int(crand.Reader, MAX_BIG)
if err != nil {
return nil, nil, errors.Wrap(err, "unable to create system paramaters")
}
alpha := bls.Bls12381FqNew().SetBigInt(a)

sg1 := make([]*bls.G1, t)
sg2 := make([]*bls.G2, t)

// Evaluate point multiplication of progressive powers of alpha
// [g, g^(α^1), ..., g^(α^t)]
for i := 0; i < t; i++ {
sg1[i] = new(bls.G1).Mul(new(bls.G1).Generator(), alpha.Exp(alpha, bls.Bls12381FqNew().SetUint64(uint64(i))))
sg2[i] = new(bls.G2).Mul(new(bls.G2).Generator(), alpha.Exp(alpha, bls.Bls12381FqNew().SetUint64(uint64(i))))
}

return sg1, sg2, nil
}

// EvalPolyG1 evaluates a polynomial in g1 using the setup paramaters
func EvalPolyG1(rs *KZGSetupParamaters, p *Polynomial) (*bls.G1, error) {

// Confirm that polynomial is valid
if p.Order() == -1 {
return nil, errors.New("Cannot evaluate polynomial, must have at least one coefficients")
}
if p.Order()+1 > len(rs.TG1) {
return nil, errors.New("Cannot evaluate polynomial of higher degree than reference string elements")
}

// Evalute polynomial in the exponent of the reference string
// g ^ ( a_0 + a_1 * α ^ 1 + a_2 * α ^ 2 + ... + a_n * α ^ n)
result := new(bls.G1).Identity()
for i, c := range p.Coefficients {
result = result.Add(result, new(bls.G1).Mul(rs.TG1[i], bls.Bls12381FqNew().Set(c)))
}
return result, nil
}

// EvalPolyG2 evaluates a polynomial in g2 using the setup paramaters
func EvalPolyG2(rs *KZGSetupParamaters, p *Polynomial) (*bls.G2, error) {

// Confirm that polynomial is valid
if p.Order() == -1 {
return nil, errors.New("Cannot evaluate polynomial, must have at least one coefficients")
}
if p.Order()+1 > len(rs.TG2) {
return nil, errors.New("Cannot evaluate polynomial of higher degree than reference string elements")
}

// Evalute polynomial in the exponent of the reference string
// g ^ ( a_0 + a_1 * α ^ 1 + a_2 * α ^ 2 + ... + a_n * α ^ n)
result := new(bls.G2).Identity()
for i, c := range p.Coefficients {
result = result.Add(result, new(bls.G2).Mul(rs.TG2[i], bls.Bls12381FqNew().Set(c)))
}
return result, nil
}

// Commit converts a polynomial to a point in g1 by evaluation with the setup paramaters
func Commit(rs *KZGSetupParamaters, p *Polynomial) (*bls.G1, error) {
polyEvalG1, err := EvalPolyG1(rs, p)
if err != nil {
return nil, err
}
return polyEvalG1, nil
}

// VerifyPoly returns 1 if the commitment matches an evaluated polynomial, 0 otherwise
func VerifyPoly(rs *KZGSetupParamaters, c *bls.G1, p *Polynomial) (int, error) {
pc, err := Commit(rs, p)
if err != nil {
return 0, err
}
return pc.Equal(c), nil
}

// CreateWitness creates an evaluation proof of a point on a polynomial as a g1 element
func CreateWitness(rs *KZGSetupParamaters, p *Polynomial, x, phiX *native.Field) (*bls.G1, error) {
n := p.Sub(new(Polynomial).Set([]*native.Field{phiX})) // p - phi(x)
d := new(Polynomial).Set( // x - z
[]*native.Field{
bls.Bls12381FqNew().Neg(x),
bls.Bls12381FqNew().SetOne(),
},
)

// q = ( p - phi(x) ) / (x - z)
q, r := n.Div(d)
if !r.IsZero() {
return nil,
fmt.Errorf("remainder must be 0")
}

// proof = eval(q)
e, err := EvalPolyG1(rs, q)
if err != nil {
return nil, err
}
return e, nil
}

// VerifyEval checks the commitment, proof, input point, and evaluation coincide via pairings
func VerifyEval(rs *KZGSetupParamaters, commitment, proof *bls.G1, x, y *native.Field) int {

// g ^ ( α - x )
gmx := new(bls.G2).Neg(new(bls.G2).Mul(new(bls.G2).Generator(), x))
gamx := new(bls.G2).Add(rs.TG2[1], gmx)

// g ^ ( f(α) - f(x) )
gmfx := new(bls.G1).Neg(new(bls.G1).Mul(new(bls.G1).Generator(), y))
gfamfx := new(bls.G1).Add(commitment, gmfx)

// e(proof,g^(α-x)) == e(g^(f(α) - f(x)),g)
p1 := new(bls.Engine)
p2 := new(bls.Engine)
e1 := p1.AddPair(proof, gamx).Result()
e2 := p2.AddPair(gfamfx, new(bls.G2).Generator()).Result()
return e1.Equal(e2)
}

// CreateWitnessBatch creates an evaluation proof of multiple points on a polynomial as a g1 element
func CreateWitnessBatch(rs *KZGSetupParamaters, p *Polynomial, x, phiX []*native.Field) (*bls.G1, error) {

// I(x)
ix, err := CreateLagrangePolynomial(x, phiX)
if err != nil {
return nil, err
}

// q(x) = ( p(x) - I(x) ) / z(x)
q, r := p.Sub(ix).Div(CreateZeroPolynomial(x))
if !r.IsZero() {
return nil,
fmt.Errorf("remainder must be 0")
}

// proof = eval(q(x))
e, err := EvalPolyG1(rs, q)
if err != nil {
return nil, err
}
return e, nil
}

// VerifyEvalBatch checks the commitment, proof, input points, and evaluation coincide via pairings
func VerifyEvalBatch(rs *KZGSetupParamaters, commitment, proof *bls.G1, z, y []*native.Field) (int, error) {

// I(x)
ix, err := CreateLagrangePolynomial(z, y)
if err != nil {
return 0, err
}

// f(I(x))
fiG1, err := EvalPolyG1(rs, ix)
if err != nil {
return 0, err
}

// f(z(x))
fzG2, err := EvalPolyG2(rs, CreateZeroPolynomial(z))
if err != nil {
return 0, err
}

// c - f(I(x))
cmit := new(bls.G1).Add(commitment, new(bls.G1).Neg(fiG1))

// e(proof, f(z(x))) == e(c - f(I(x)), g)
p1 := new(bls.Engine)
p2 := new(bls.Engine)
e1 := p1.AddPair(proof, fzG2).Result()
e2 := p2.AddPair(cmit, new(bls.G2).Generator()).Result()
return e1.Equal(e2), nil
}
Loading