Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat constant 'randomness' - domain-size-independent vk #1269

Merged
merged 2 commits into from
Oct 3, 2024
Merged
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
35 changes: 21 additions & 14 deletions test/unsafekzg/kzgsrs.go
Original file line number Diff line number Diff line change
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,15 +151,18 @@ func extractCurveID(key string) (ecc.ID, error) {
return ecc.IDFromString(matches[1])
}

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

tau, err := rand.Int(rand.Reader, curveID.ScalarField())
if err != nil {
return nil, nil, err
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)
}
}

var srs kzg.SRS

switch curveID {
case ecc.BN254:
srs, err = kzg_bn254.NewSRS(size, tau)
Expand Down
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