You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.5 KiB

package goldilocks
import (
"math"
"github.com/consensys/gnark/frontend"
)
// The types, structs, and functions in this file were ported over from the gnark library
// https://github.com/Consensys/gnark/blob/3421eaa7d544286abf3de8c46282b8d4da6d5da0/std/rangecheck/rangecheck_commit.go
type Type int
const (
R1CS Type = iota
SCS
)
type FrontendTyper interface {
FrontendType() Type
}
type checkedVariable struct {
v frontend.Variable
bits int
}
func getOptimalBasewidth(api frontend.API, collected []checkedVariable) int {
if ft, ok := api.(FrontendTyper); ok {
switch ft.FrontendType() {
case R1CS:
return optimalWidth(nbR1CSConstraints, collected)
case SCS:
return optimalWidth(nbPLONKConstraints, collected)
}
}
return optimalWidth(nbR1CSConstraints, collected)
}
func optimalWidth(countFn func(baseLength int, collected []checkedVariable) int, collected []checkedVariable) int {
min := math.MaxInt64
minVal := 0
for j := 2; j < 18; j++ {
current := countFn(j, collected)
if current < min {
min = current
minVal = j
}
}
return minVal
}
func decompSize(varSize int, limbSize int) int {
return (varSize + limbSize - 1) / limbSize
}
func nbR1CSConstraints(baseLength int, collected []checkedVariable) int {
nbDecomposed := 0
for i := range collected {
nbDecomposed += int(decompSize(collected[i].bits, baseLength))
}
eqs := len(collected) // correctness of decomposition
nbRight := nbDecomposed // inverse per decomposed
nbleft := (1 << baseLength) // div per table
return nbleft + nbRight + eqs + 1
}
func nbPLONKConstraints(baseLength int, collected []checkedVariable) int {
nbDecomposed := 0
for i := range collected {
nbDecomposed += int(decompSize(collected[i].bits, baseLength))
}
eqs := nbDecomposed // check correctness of every decomposition. this is nbDecomp adds + eq cost per collected
nbRight := 3 * nbDecomposed // denominator sub, inv and large sum per table entry
nbleft := 3 * (1 << baseLength) // denominator sub, div and large sum per table entry
return nbleft + nbRight + eqs + 1 // and the final assert
}
func gnarkRangeCheckerSelector(api frontend.API) RangeCheckerType {
// Emulate the logic within rangecheck.New
// https://github.com/Consensys/gnark/blob/3421eaa7d544286abf3de8c46282b8d4da6d5da0/std/rangecheck/rangecheck.go#L24
if _, ok := api.(frontend.Rangechecker); ok {
return NATIVE_RANGE_CHECKER
} else if _, ok := api.(frontend.Committer); ok {
return COMMIT_RANGE_CHECKER
} else {
return BIT_DECOMP_RANGE_CHECKER
}
}