@ -4,10 +4,6 @@ import (
"fmt"
. "gnark-plonky2-verifier/field"
"regexp"
"strconv"
"strings"
"github.com/consensys/gnark-crypto/field/goldilocks"
)
type gate interface {
@ -15,231 +11,39 @@ type gate interface {
EvalUnfiltered ( p * PlonkChip , vars EvaluationVars ) [ ] QuadraticExtension
}
func GateInstanceFromId ( gateId string ) gate {
if strings . HasPrefix ( gateId , "ArithmeticGate" ) {
numOpsRaw := strings . Split ( gateId , ":" ) [ 1 ]
numOpsRaw = strings . Split ( numOpsRaw , "}" ) [ 0 ]
numOpsRaw = strings . TrimSpace ( numOpsRaw )
numOps , err := strconv . Atoi ( numOpsRaw )
if err != nil {
panic ( "Invalid gate ID for ArithmeticGate" )
}
return NewArithmeticGate ( uint64 ( numOps ) )
}
if strings . HasPrefix ( gateId , "ConstantGate" ) {
numConstsRaw := strings . Split ( gateId , ":" ) [ 1 ]
numConstsRaw = strings . Split ( numConstsRaw , "}" ) [ 0 ]
numConstsRaw = strings . TrimSpace ( numConstsRaw )
numConsts , err := strconv . Atoi ( numConstsRaw )
if err != nil {
panic ( "Invalid gate ID" )
}
return NewConstantGate ( uint64 ( numConsts ) )
}
if gateId == "NoopGate" {
return NewNoopGate ( )
}
if gateId == "PublicInputGate" {
return NewPublicInputGate ( )
}
if strings . HasPrefix ( gateId , "PoseidonGate" ) {
return NewPoseidonGate ( )
}
if strings . HasPrefix ( gateId , "BaseSumGate" ) {
// Has the format "BaseSumGate { num_limbs: 32 } + Base: 2"
regEx := "BaseSumGate { num_limbs: (?P<numLimbs>[0-9]+) } \\+ Base: (?P<base>[0-9]+)"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid BaseSumGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numLimbs , hasNumLimbs := matches [ "numLimbs" ]
base , hasBase := matches [ "base" ]
if ! hasNumLimbs || ! hasBase {
panic ( "Invalid BaseSumGate ID" )
}
return NewBaseSumGate ( uint64 ( numLimbs ) , uint64 ( base ) )
}
if strings . HasPrefix ( gateId , "RandomAccessGate" ) {
// Has the format "RandomAccessGate { bits: 2, num_copies: 13, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
regEx := "RandomAccessGate { bits: (?P<bits>[0-9]+), num_copies: (?P<numCopies>[0-9]+), num_extra_constants: (?P<numExtraConstants>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid RandomAccessGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
bits , hasBits := matches [ "bits" ]
numCopies , hasNumCopies := matches [ "numCopies" ]
numExtraConstants , hasNumExtraConstants := matches [ "numExtraConstants" ]
if ! hasBits || ! hasNumCopies || ! hasNumExtraConstants {
panic ( "Invalid RandomAccessGate ID" )
}
return NewRandomAccessGate ( uint64 ( bits ) , uint64 ( numCopies ) , uint64 ( numExtraConstants ) )
}
if strings . HasPrefix ( gateId , "ArithmeticExtension" ) {
// Has the format "ArithmeticExtensionGate { num_ops: 10 }"
regEx := "ArithmeticExtensionGate { num_ops: (?P<numOps>[0-9]+) }"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid ArithmeticExtensionGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numOps , hasNumOps := matches [ "numOps" ]
if ! hasNumOps {
panic ( "Invalid ArithmeticExtensionGate ID" )
}
return NewArithmeticExtensionGate ( uint64 ( numOps ) )
}
if strings . HasPrefix ( gateId , "MulExtensionGate" ) {
// Has the format "MulExtensionGate { num_ops: 13 }"
regEx := "MulExtensionGate { num_ops: (?P<numOps>[0-9]+) }"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid MulExtensionGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numOps , hasNumOps := matches [ "numOps" ]
if ! hasNumOps {
panic ( "Invalid MulExtensionGate ID" )
}
return NewMultiplicationExtensionGate ( uint64 ( numOps ) )
}
if strings . HasPrefix ( gateId , "ReducingExtensionGate" ) {
// Has the format "ReducingExtensionGate { num_coeffs: 33 }"
regEx := "ReducingExtensionGate { num_coeffs: (?P<numCoeffs>[0-9]+) }"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid ReducingExtensionGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numCoeffs , hasNumCoeffs := matches [ "numCoeffs" ]
if ! hasNumCoeffs {
panic ( "Invalid ReducingExtensionGate ID" )
}
return NewReducingExtensionGate ( uint64 ( numCoeffs ) )
}
if strings . HasPrefix ( gateId , "ReducingGate" ) {
// Has the format "ReducingGate { num_coeffs: 33 }"
regEx := "ReducingGate { num_coeffs: (?P<numCoeffs>[0-9]+) }"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid ReducingGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numCoeffs , hasNumCoeffs := matches [ "numCoeffs" ]
if ! hasNumCoeffs {
panic ( "Invalid ReducingGate ID" )
}
return NewReducingGate ( uint64 ( numCoeffs ) )
}
if strings . HasPrefix ( gateId , "ExponentiationGate" ) {
// Has the format "ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
regEx := "ExponentiationGate { num_power_bits: (?P<numPowerBits>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid ExponentiationGate regular expression" )
}
matches := getRegExMatches ( r , gateId )
numPowerBits , hasNumPowerBits := matches [ "numPowerBits" ]
if ! hasNumPowerBits {
panic ( "Invalid ExponentiationGate ID" )
}
return NewExponentiationGate ( uint64 ( numPowerBits ) )
}
// CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
if strings . HasPrefix ( gateId , "CosetInterpolationGate" ) {
// Has the format CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
var gateRegexHandlers = map [ * regexp . Regexp ] func ( parameters map [ string ] string ) gate {
aritheticGateRegex : deserializeArithmeticGate ,
aritheticExtensionGateRegex : deserializeExtensionArithmeticGate ,
baseSumGateRegex : deserializeBaseSumGate ,
constantGateRegex : deserializeConstantGate ,
cosetInterpolationGateRegex : deserializeCosetInterpolationGate ,
exponentiationGateRegex : deserializeExponentiationGate ,
mulExtensionGateRegex : deserializeMulExtensionGate ,
noopGateRegex : deserializeNoopGate ,
poseidonGateRegex : deserializePoseidonGate ,
publicInputGateRegex : deserializePublicInputGate ,
randomAccessGateRegex : deserializeRandomAccessGate ,
reducingExtensionGateRegex : deserializeReducingExtensionGate ,
reducingGateRegex : deserializeReducingGate ,
}
/ *
regEx := "CosetInterpolationGate { subgroup_bits: (?P<subgroupBits>[0-9]+), degree: (?P<degree>[0-9]+), barycentric_weights: \\[(?P<barycentricWeights>[0-9, ]+)\\], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
r , err := regexp . Compile ( regEx )
if err != nil {
panic ( "Invalid CosetInterpolationGate regular expression" )
func GateInstanceFromId ( gateId string ) gate {
for regex , handler := range gateRegexHandlers {
matches := regex . FindStringSubmatch ( gateId )
if matches != nil {
parameters := make ( map [ string ] string )
for i , name := range regex . SubexpNames ( ) {
if i != 0 && name != "" {
parameters [ name ] = matches [ i ]
}
}
matches := getRegExMatches ( r , gateId )
subgroupBits , hasSubgroupBits := matches [ "subgroupBits" ]
degree , hasDegree := matches [ "degree" ]
barycentricWeights , hasBarycentricWeights := matches [ "barycentricWeights" ]
if ! hasSubgroupBits || ! hasDegree || ! hasBarycentricWeights {
panic ( "Invalid CosetInterpolationGate ID" )
} * /
return NewCosetInterpolationGate (
4 ,
6 ,
[ ] goldilocks . Element {
goldilocks . NewElement ( 17293822565076172801 ) ,
goldilocks . NewElement ( 18374686475376656385 ) ,
goldilocks . NewElement ( 18446744069413535745 ) ,
goldilocks . NewElement ( 281474976645120 ) ,
goldilocks . NewElement ( 17592186044416 ) ,
goldilocks . NewElement ( 18446744069414584577 ) ,
goldilocks . NewElement ( 18446744000695107601 ) ,
goldilocks . NewElement ( 18446744065119617025 ) ,
goldilocks . NewElement ( 1152921504338411520 ) ,
goldilocks . NewElement ( 72057594037927936 ) ,
goldilocks . NewElement ( 18446744069415632897 ) ,
goldilocks . NewElement ( 18446462594437939201 ) ,
goldilocks . NewElement ( 18446726477228539905 ) ,
goldilocks . NewElement ( 18446744069414584065 ) ,
goldilocks . NewElement ( 68719476720 ) ,
goldilocks . NewElement ( 4294967296 ) ,
} ,
)
}
panic ( fmt . Sprintf ( "Unknown gate ID %s" , gateId ) )
}
func getRegExMatches ( r * regexp . Regexp , gateId string ) map [ string ] int {
matches := r . FindStringSubmatch ( gateId )
result := make ( map [ string ] int )
for i , name := range r . SubexpNames ( ) {
if i != 0 && name != "" {
value , err := strconv . Atoi ( matches [ i ] )
if err != nil {
panic ( "Invalid field value for \"name\": " + err . Error ( ) )
if matches != nil {
return handler ( parameters )
}
result [ name ] = value
}
}
return result
panic ( fmt . Sprintf ( "Unknown gate ID %s" , gateId ) )
}
func ( p * PlonkChip ) computeFilter (