Skip to content

Commit

Permalink
feat: allow providing toxic value as an option
Browse files Browse the repository at this point in the history
  • Loading branch information
ivokub committed Oct 3, 2024
1 parent 9db0eff commit a061498
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 34 deletions.
59 changes: 27 additions & 32 deletions test/unsafekzg/kzgsrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package unsafekzg

import (
"bufio"
"crypto/sha256"
"crypto/rand"
"fmt"
"math/big"
"os"
Expand Down Expand Up @@ -59,8 +59,8 @@ var (
memLock, fsLock sync.RWMutex
)

// NewSRS returns a pair of kzg.SRS; one in canonical form, the other in lagrange form.
// Default options use a memory cache, see Option for more details & options.
// NewSRS returns a pair of [kzg.SRS]; one in canonical form, the other in Lagrange form.
// Default options use a memory cache, see [Option] for more details & options.
func NewSRS(ccs constraint.ConstraintSystem, opts ...Option) (canonical kzg.SRS, lagrange kzg.SRS, err error) {

nbConstraints := ccs.GetNbConstraints()
Expand All @@ -78,7 +78,7 @@ func NewSRS(ccs constraint.ConstraintSystem, opts ...Option) (canonical kzg.SRS,
return nil, nil, err
}

key := cacheKey(curveID, sizeCanonical)
key := cacheKey(curveID, sizeCanonical, cfg.toxicValue)
log.Debug().Str("key", key).Msg("fetching SRS from mem cache")
memLock.RLock()
entry, ok := cache[key]
Expand Down Expand Up @@ -109,17 +109,18 @@ func NewSRS(ccs constraint.ConstraintSystem, opts ...Option) (canonical kzg.SRS,
log.Debug().Msg("SRS not found in cache, generating")

// not in cache, generate
canonical, lagrange, err = newSRS(curveID, sizeCanonical)
canonical, lagrange, err = newSRS(curveID, sizeCanonical, cfg.toxicValue)
if err != nil {
return nil, nil, err
}

// cache it
// cache it. We cache the SRS in case the toxic value given only in the
// memory cache to avoid storying weak SRS on filesystem.
memLock.Lock()
cache[key] = cacheEntry{canonical, lagrange}
memLock.Unlock()

if cfg.fsCache {
if cfg.fsCache && cfg.toxicValue == nil {
log.Debug().Str("key", key).Str("cacheDir", cfg.cacheDir).Msg("writing SRS to fs cache")
fsLock.Lock()
fsWrite(key, cfg.cacheDir, canonical, lagrange)
Expand All @@ -134,7 +135,10 @@ type cacheEntry struct {
lagrange kzg.SRS
}

func cacheKey(curveID ecc.ID, size uint64) string {
func cacheKey(curveID ecc.ID, size uint64, toxicValue *big.Int) string {
if toxicValue != nil {
return fmt.Sprintf("kzgsrs-%s-%d-toxic-%s", curveID.String(), size, toxicValue.String())
}
return fmt.Sprintf("kzgsrs-%s-%d", curveID.String(), size)
}

Expand All @@ -147,30 +151,33 @@ func extractCurveID(key string) (ecc.ID, error) {
return ecc.IDFromString(matches[1])
}

func newSRS(curveID ecc.ID, size uint64) (kzg.SRS, kzg.SRS, error) {

alpha := alpha()

func newSRS(curveID ecc.ID, size uint64, tau *big.Int) (kzg.SRS, kzg.SRS, error) {
var (
srs kzg.SRS
err error
)
if tau == nil {
tau, err = rand.Int(rand.Reader, curveID.ScalarField())
if err != nil {
return nil, nil, fmt.Errorf("sample random toxic value: %w", err)
}
}

switch curveID {
case ecc.BN254:
srs, err = kzg_bn254.NewSRS(size, alpha)
srs, err = kzg_bn254.NewSRS(size, tau)
case ecc.BLS12_381:
srs, err = kzg_bls12381.NewSRS(size, alpha)
srs, err = kzg_bls12381.NewSRS(size, tau)
case ecc.BLS12_377:
srs, err = kzg_bls12377.NewSRS(size, alpha)
srs, err = kzg_bls12377.NewSRS(size, tau)
case ecc.BW6_761:
srs, err = kzg_bw6761.NewSRS(size, alpha)
srs, err = kzg_bw6761.NewSRS(size, tau)
case ecc.BLS24_317:
srs, err = kzg_bls24317.NewSRS(size, alpha)
srs, err = kzg_bls24317.NewSRS(size, tau)
case ecc.BLS24_315:
srs, err = kzg_bls24315.NewSRS(size, alpha)
srs, err = kzg_bls24315.NewSRS(size, tau)
case ecc.BW6_633:
srs, err = kzg_bw6633.NewSRS(size, alpha)
srs, err = kzg_bw6633.NewSRS(size, tau)
default:
panic("unrecognized R1CS curve type")
}
Expand All @@ -179,7 +186,7 @@ func newSRS(curveID ecc.ID, size uint64) (kzg.SRS, kzg.SRS, error) {
return nil, nil, err
}

return srs, toLagrange(srs, alpha), nil
return srs, toLagrange(srs, tau), nil
}

func toLagrange(canonicalSRS kzg.SRS, tau *big.Int) kzg.SRS {
Expand Down Expand Up @@ -415,15 +422,3 @@ func fsWrite(key string, cacheDir string, canonical kzg.SRS, lagrange kzg.SRS) {

w.Flush()
}

// alpha is the base randomness for generating the SRS
func alpha() *big.Int {
return sync.OnceValue(func() *big.Int {
h := sha256.New()
h.Write([]byte("gnark unsafe kzg-srs -- DO NOT USE IN PROD"))

var res big.Int
res.SetBytes(h.Sum(nil))
return &res
})()
}
48 changes: 46 additions & 2 deletions test/unsafekzg/options.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package unsafekzg

import (
"crypto/sha256"
"errors"
"math/big"
"os"
"path/filepath"

"github.com/consensys/gnark/logger"
)

// Option allows changing the behaviour of the unsafe KZG SRS generation.
type Option func(*config) error

// WithCacheDir enables the filesystem cache and sets the cache directory
Expand All @@ -18,9 +22,49 @@ func WithFSCache() Option {
}
}

// WithCacheDir enables the filesystem cache and sets the cache directory
// to the provided path.
func WithCacheDir(dir string) Option {
return func(opt *config) error {
opt.fsCache = true
opt.cacheDir = dir
return nil
}
}

// WithToxicValue sets the toxic value to the provided value.
//
// NB! This is a debug option and should not be used in production.
func WithToxicValue(toxicValue *big.Int) Option {
return func(opt *config) error {
if opt.toxicValue != nil {
return errors.New("toxic value already set")
}
opt.toxicValue = toxicValue
return nil
}
}

// WithToxicSeed sets the toxic value to the sha256 hash of the provided seed.
//
// NB! This is a debug option and should not be used in production.
func WithToxicSeed(seed []byte) Option {
return func(opt *config) error {
if opt.toxicValue != nil {
return errors.New("toxic value already set")
}
h := sha256.New()
h.Write(seed)
opt.toxicValue = new(big.Int)
opt.toxicValue.SetBytes(h.Sum(nil))
return nil
}
}

type config struct {
fsCache bool
cacheDir string
fsCache bool
cacheDir string
toxicValue *big.Int
}

// default options
Expand Down

0 comments on commit a061498

Please sign in to comment.