Files
linea-monorepo/prover/circuits/srs_store.go
Julien Marchand a001342170 chore: Initial commit
Co-authored-by: Franklin Delehelle <franklin.delehelle@odena.eu>
Co-authored-by: Alexandre Belling <alexandrebelling8@gmail.com>
Co-authored-by: Pedro Novais <jpvnovais@gmail.com>
Co-authored-by: Roman Vaseev <4833306+Filter94@users.noreply.github.com>
Co-authored-by: Bradley Bown <bradbown@googlemail.com>
Co-authored-by: Victorien Gauch <85494462+VGau@users.noreply.github.com>
Co-authored-by: Nikolai Golub <nikolai.golub@consensys.net>
Co-authored-by: The Dark Jester <thedarkjester@users.noreply.github.com>
Co-authored-by: jonesho <81145364+jonesho@users.noreply.github.com>
Co-authored-by: Gaurav Ahuja <gauravahuja9@gmail.com>
Co-authored-by: Azam Soleimanian <49027816+Soleimani193@users.noreply.github.com>
Co-authored-by: Andrei A <andrei.alexandru@consensys.net>
Co-authored-by: Arijit Dutta <37040536+arijitdutta67@users.noreply.github.com>
Co-authored-by: Gautam Botrel <gautam.botrel@gmail.com>
Co-authored-by: Ivo Kubjas <ivo.kubjas@consensys.net>
Co-authored-by: gusiri <dreamerty@postech.ac.kr>
Co-authored-by: FlorianHuc <florian.huc@gmail.com>
Co-authored-by: Arya Tabaie <arya.pourtabatabaie@gmail.com>
Co-authored-by: Julink <julien.fontanel@consensys.net>
Co-authored-by: Bogdan Ursu <bogdanursuoffice@gmail.com>
Co-authored-by: Jakub Trąd <jakubtrad@gmail.com>
Co-authored-by: Alessandro Sforzin <alessandro.sforzin@consensys.net>
Co-authored-by: Olivier Bégassat <olivier.begassat.cours@gmail.com>
Co-authored-by: Steve Huang <97596526+stevehuangc7s@users.noreply.github.com>
Co-authored-by: bkolad <blazejkolad@gmail.com>
Co-authored-by: fadyabuhatoum1 <139905934+fadyabuhatoum1@users.noreply.github.com>
Co-authored-by: Blas Rodriguez Irizar <rodrigblas@gmail.com>
Co-authored-by: Eduardo Andrade <eduardofandrade@gmail.com>
Co-authored-by: Ivo Kubjas <tsimmm@gmail.com>
Co-authored-by: Ludcour <ludovic.courcelas@consensys.net>
Co-authored-by: m4sterbunny <harrie.bickle@consensys.net>
Co-authored-by: Alex Panayi <145478258+alexandrospanayi@users.noreply.github.com>
Co-authored-by: Diana Borbe - ConsenSys <diana.borbe@consensys.net>
Co-authored-by: ThomasPiellard <thomas.piellard@gmail.com>
2024-07-31 18:17:20 +02:00

176 lines
4.3 KiB
Go

package circuits
import (
"bytes"
"context"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/kzg"
"github.com/consensys/gnark/backend/plonk"
"github.com/consensys/gnark/constraint"
"github.com/sirupsen/logrus"
kzg377 "github.com/consensys/gnark-crypto/ecc/bls12-377/kzg"
kzg254 "github.com/consensys/gnark-crypto/ecc/bn254/kzg"
kzgbw6 "github.com/consensys/gnark-crypto/ecc/bw6-761/kzg"
)
type SRSStore struct {
entries map[ecc.ID][]fsEntry
}
type fsEntry struct {
isCanonical bool
size int
path string
}
// NewSRSStore creates a new SRSStore
func NewSRSStore(rootDir string) (*SRSStore, error) {
// list all the files in rootDir
// for each file, make a fsEntry but do not load the SRS (lazy loaded on demand)
// store the fsEntry in map[string]fsEntry, with the key being the file name
dir, err := os.ReadDir(rootDir)
if err != nil {
return nil, err
}
srsStore := &SRSStore{
entries: make(map[ecc.ID][]fsEntry),
}
srsStore.entries[ecc.BLS12_377] = []fsEntry{}
srsStore.entries[ecc.BN254] = []fsEntry{}
srsStore.entries[ecc.BW6_761] = []fsEntry{}
srsRegexp := regexp.MustCompile(`^(kzg_srs)_(canonical|lagrange)_(\d+)_(bls12377|bn254|bw6761)_(aleo|aztec|celo)\.memdump$`)
for _, entry := range dir {
if entry.IsDir() {
continue
}
// parse the file name
// create a fsEntry
// store it in the map
fileName := entry.Name()
matches := srsRegexp.FindStringSubmatch(fileName)
if matches == nil {
continue
}
isCanonical := matches[2] == "canonical"
size, _ := strconv.Atoi(matches[3])
var curveID ecc.ID
switch matches[4] {
case "bls12377":
curveID = ecc.BLS12_377
case "bn254":
curveID = ecc.BN254
case "bw6761":
curveID = ecc.BW6_761
default:
return nil, errors.New("curve not supported")
}
srsStore.entries[curveID] = append(srsStore.entries[curveID], fsEntry{
isCanonical: isCanonical,
size: size,
path: filepath.Join(rootDir, fileName),
})
}
// sort the entries by size
for _, entries := range srsStore.entries {
sort.Slice(entries, func(i, j int) bool {
return entries[i].size < entries[j].size
})
}
return srsStore, nil
}
func (store *SRSStore) GetSRS(ctx context.Context, ccs constraint.ConstraintSystem) (kzg.SRS, kzg.SRS, error) {
sizeCanonical, sizeLagrange := plonk.SRSSize(ccs)
curveID := fieldToCurve(ccs.Field())
// find the canonical srs
var canonicalSRS kzg.SRS
for _, entry := range store.entries[curveID] {
if entry.isCanonical && entry.size >= sizeCanonical {
canonicalSRS = kzg.NewSRS(curveID)
data, err := os.ReadFile(entry.path)
if err != nil {
return nil, nil, err
}
if err := canonicalSRS.ReadDump(bytes.NewReader(data), sizeCanonical); err != nil {
return nil, nil, err
}
break
}
}
if canonicalSRS == nil {
return nil, nil, fmt.Errorf("could not find canonical SRS for curve %s and size %d", curveID, sizeCanonical)
}
// find the lagrange srs
var lagrangeSRS kzg.SRS
for _, entry := range store.entries[curveID] {
if !entry.isCanonical && entry.size == sizeLagrange {
lagrangeSRS = kzg.NewSRS(curveID)
data, err := os.ReadFile(entry.path)
if err != nil {
return nil, nil, err
}
if err := lagrangeSRS.ReadDump(bytes.NewReader(data)); err != nil {
return nil, nil, err
}
break
}
}
if lagrangeSRS == nil {
// we can compute it from the canonical one.
if sizeCanonical < sizeLagrange {
panic("canonical SRS is smaller than lagrange SRS")
}
logrus.Debugf("computing lagrange SRS from canonical SRS %d -> %d\n", sizeCanonical, sizeLagrange)
var err error
lagrangeSRS, err = toLagrange(canonicalSRS, sizeLagrange)
if err != nil {
return nil, nil, err
}
}
return canonicalSRS, lagrangeSRS, nil
}
func toLagrange(srs kzg.SRS, sizeLagrange int) (kzg.SRS, error) {
var err error
switch srs := srs.(type) {
case *kzg254.SRS:
lagrange := &kzg254.SRS{}
lagrange.Pk.G1, err = kzg254.ToLagrangeG1(srs.Pk.G1[:sizeLagrange])
return lagrange, err
case *kzg377.SRS:
lagrange := &kzg377.SRS{}
lagrange.Pk.G1, err = kzg377.ToLagrangeG1(srs.Pk.G1[:sizeLagrange])
return lagrange, err
case *kzgbw6.SRS:
lagrange := &kzgbw6.SRS{}
lagrange.Pk.G1, err = kzgbw6.ToLagrangeG1(srs.Pk.G1[:sizeLagrange])
return lagrange, err
default:
panic("unknown SRS type")
}
}