Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 5 additions & 1 deletion prover-ray/crypto/koalabear/fiatshamir/poseidon2.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (fs *FiatShamir) UpdateExt(vec ...field.Ext) {
if len(vec) == 0 {
return
}
vElems := unsafe.Slice((*field.Element)(unsafe.Pointer(&vec[0])), 4*len(vec)) //nolint
vElems := unsafe.Slice((*field.Element)(unsafe.Pointer(&vec[0])), field.ExtensionDegree*len(vec)) //nolint
fs.h.WriteElements(vElems...)
}

Expand Down Expand Up @@ -96,13 +96,17 @@ func (fs *FiatShamir) RandomField() field.Octuplet {
}

// RandomFext samples a random extension field element from the transcript.
// Uses the first ExtensionDegree (=6) of the 8 octuplet coordinates; the
// remaining two are discarded.
func (fs *FiatShamir) RandomFext() field.Ext {
s := fs.RandomField() // already calls safeguardUpdate()
var res field.Ext
res.B0.A0 = s[0]
res.B0.A1 = s[1]
res.B1.A0 = s[2]
res.B1.A1 = s[3]
res.B2.A0 = s[4]
res.B2.A1 = s[5]

return res
}
Expand Down
12 changes: 6 additions & 6 deletions prover-ray/crypto/koalabear/reedsolomon/reedsolomon.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (r *RsParams) rsEncodeExt(v []field.Ext) []field.Ext {

smallDomain := r.Domains[0]
largeDomain := r.Domains[1]
smallDomain.FFTInverseExt(expandedCoeffs[:n], fft.DIF, fft.WithNbTasks(1))
smallDomain.FFTInverseExt6(expandedCoeffs[:n], fft.DIF, fft.WithNbTasks(1))

// this loop dispatches the values that are all located at the beginning
// of the domain to the entire domain by homothety
Expand All @@ -155,16 +155,16 @@ func (r *RsParams) rsEncodeExt(v []field.Ext) []field.Ext {
expandedCoeffs[j] = field.Ext{}
}

largeDomain.FFTExt(expandedCoeffs, fft.DIT, fft.WithNbTasks(1))
largeDomain.FFTExt6(expandedCoeffs, fft.DIT, fft.WithNbTasks(1))
return expandedCoeffs
}

// fast path; we avoid the bit reverse operations and work on the smaller domain.
inputCoeffs := extensions.Vector(expandedCoeffs[:r.NbColumns()])
r.Domains[0].FFTInverseExt(inputCoeffs, fft.DIF, fft.WithNbTasks(1))
inputCoeffs := extensions.VectorE6(expandedCoeffs[:r.NbColumns()])
r.Domains[0].FFTInverseExt6(inputCoeffs, fft.DIF, fft.WithNbTasks(1))
inputCoeffs.MulByElement(inputCoeffs, r.CosetTableBitReverse)

r.Domains[0].FFTExt(inputCoeffs, fft.DIT, fft.WithNbTasks(1))
r.Domains[0].FFTExt6(inputCoeffs, fft.DIT, fft.WithNbTasks(1))
for j := r.NbColumns() - 1; j >= 0; j-- {
expandedCoeffs[rho*j+1] = expandedCoeffs[j]
expandedCoeffs[rho*j] = v[j]
Expand All @@ -184,7 +184,7 @@ func (r *RsParams) IsCodewordExt(v []field.Ext) error {
coeffs := make([]field.Ext, r.NbEncodedColumns())
copy(coeffs, v)

r.Domains[1].FFTInverseExt(coeffs, fft.DIF, fft.WithNbTasks(1))
r.Domains[1].FFTInverseExt6(coeffs, fft.DIF, fft.WithNbTasks(1))
utils.BitReverse(coeffs)
for i := r.NbColumns(); i < r.NbEncodedColumns(); i++ {
c := coeffs[i]
Expand Down
4 changes: 2 additions & 2 deletions prover-ray/crypto/koalabear/ringsis/ringsis.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (k Key) HashModXnMinus1(limbs []field.Ext) []field.Ext {
inputReader = nil
}

domain.FFTExt(polyK, fft.DIF)
domain.FFTExt6(polyK, fft.DIF)
domain.FFT(a, fft.DIF)

var tmp field.Ext
Expand All @@ -212,7 +212,7 @@ func (k Key) HashModXnMinus1(limbs []field.Ext) []field.Ext {
}

// by linearity, we defer the fft inverse at the end
domain.FFTInverseExt(r, fft.DIT)
domain.FFTInverseExt6(r, fft.DIT)

// also account for the Montgommery issue : in gnark's implementation
// the key is implictly multiplied by RInv
Expand Down
43 changes: 25 additions & 18 deletions prover-ray/crypto/koalabear/vortex/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ func init() {
}

var (
// ErrSizeNotAMultipleOfFour is returned when the input size is not a multiple of 4.
ErrSizeNotAMultipleOfFour = errors.New("size(inputs) should be a multiple of 4")
// ErrSizeNotAMultipleOfExtDegree is returned when the input size is not a
// multiple of field.ExtensionDegree.
ErrSizeNotAMultipleOfExtDegree = fmt.Errorf("size(inputs) should be a multiple of %d", field.ExtensionDegree)
// ErrSizesDontMatch is returned when input and output slices have different sizes.
ErrSizesDontMatch = errors.New("size(inputs) should be equal to size(outputs)")
// ErrNotAPowerOfTwo is returned when the input size is not a power of two.
Expand All @@ -32,47 +33,53 @@ func fftExtInvHintEmulated(_ *big.Int, inputs []*big.Int, output []*big.Int) err
return emulated.UnwrapHint(inputs, output, fftExtInvHintNative)
}

// Each chunk of 4 inputs corresponds to a E4 element.
// Each chunk of field.ExtensionDegree (=6) inputs corresponds to one Ext element.
func fftExtInvHintNative(_ *big.Int, inputs, outputs []*big.Int) error {

if len(inputs)%4 != 0 {
return ErrSizeNotAMultipleOfFour
const d = field.ExtensionDegree

if len(inputs)%d != 0 {
return ErrSizeNotAMultipleOfExtDegree
}

n := len(inputs) / 4
n := len(inputs) / d

_n := ecc.NextPowerOfTwo(uint64(n))
if _n != uint64(n) {
return ErrNotAPowerOfTwo
}

d := fft.NewDomain(uint64(n))
dom := fft.NewDomain(uint64(n))

_res := make([]field.Ext, n)
for i := 0; i < n; i++ {
_res[i].B0.A0.SetBigInt(inputs[4*i])
_res[i].B0.A1.SetBigInt(inputs[4*i+1])
_res[i].B1.A0.SetBigInt(inputs[4*i+2])
_res[i].B1.A1.SetBigInt(inputs[4*i+3])
_res[i].B0.A0.SetBigInt(inputs[d*i+0])
_res[i].B0.A1.SetBigInt(inputs[d*i+1])
_res[i].B1.A0.SetBigInt(inputs[d*i+2])
_res[i].B1.A1.SetBigInt(inputs[d*i+3])
_res[i].B2.A0.SetBigInt(inputs[d*i+4])
_res[i].B2.A1.SetBigInt(inputs[d*i+5])
}
d.FFTInverseExt(_res, fft.DIF)
dom.FFTInverseExt6(_res, fft.DIF)
utils.BitReverse(_res)

// we're supposed to have tail of zeros. Check
for i := len(outputs) / 4; i < len(_res); i++ {
for i := len(outputs) / d; i < len(_res); i++ {
if !_res[i].IsZero() {
return fmt.Errorf("fftExtInvHintNative: expected zero at position %d, got %s", i, _res[i].String())
}
}
// now truncate to avoid returning the zeros. In non-native we range check
// the results so it would lead to overhead
_res = _res[:len(outputs)/4]
_res = _res[:len(outputs)/d]

for i := range _res {
_res[i].B0.A0.BigInt(outputs[4*i])
_res[i].B0.A1.BigInt(outputs[4*i+1])
_res[i].B1.A0.BigInt(outputs[4*i+2])
_res[i].B1.A1.BigInt(outputs[4*i+3])
_res[i].B0.A0.BigInt(outputs[d*i+0])
_res[i].B0.A1.BigInt(outputs[d*i+1])
_res[i].B1.A0.BigInt(outputs[d*i+2])
_res[i].B1.A1.BigInt(outputs[d*i+3])
_res[i].B2.A0.BigInt(outputs[d*i+4])
_res[i].B2.A1.BigInt(outputs[d*i+5])
}

return nil
Expand Down
29 changes: 25 additions & 4 deletions prover-ray/crypto/koalabear/vortex/verifier_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"slices"

"github.com/consensys/gnark-crypto/field/koalabear/vortex"
"github.com/consensys/linea-monorepo/prover-ray/crypto/koalabear/reedsolomon"
"github.com/consensys/linea-monorepo/prover-ray/maths/koalabear/field"
"github.com/consensys/linea-monorepo/prover-ray/maths/koalabear/polynomials"
Expand Down Expand Up @@ -39,7 +38,7 @@ func CheckStatement(linComb []field.Ext, ys [][]field.Ext, x, alpha field.Ext) e
// Check the consistency of Ys and proof.Linear combination
yJoined := slices.Concat(ys...)
alphaY := polynomials.EvalLagrange(field.VecFromExt(linComb), field.ElemFromExt(x))
alphaYPrime := vortex.EvalFextPolyHorner(yJoined, alpha)
alphaYPrime := evalFextPolyHorner(yJoined, alpha)

if !alphaY.Equal(&alphaYPrime) {
return fmt.Errorf("RowLincomb and Y are inconsistent")
Expand Down Expand Up @@ -73,13 +72,35 @@ func CheckLinComb(
}

// Check the linear combination is consistent with the opened column
y := vortex.EvalBasePolyHorner(fullCol, alpha)
y := evalBasePolyHorner(fullCol, alpha)
other := linComb[selectedColID]

if y != other {
if !y.Equal(&other) {
return fmt.Errorf("the linear combination is inconsistent %v : %v", y.String(), other.String())
}
}

return nil
}

// evalFextPolyHorner evaluates a polynomial whose coefficients live in the
// extension field, at an extension point, using Horner's method.
func evalFextPolyHorner(poly []field.Ext, x field.Ext) field.Ext {
var res field.Ext
for i := len(poly) - 1; i >= 0; i-- {
res.Mul(&res, &x)
res.Add(&res, &poly[i])
}
return res
}

// evalBasePolyHorner evaluates a base-coefficient polynomial at an extension
// point. Each addition only touches the lifted constant slot of res.
func evalBasePolyHorner(poly []field.Element, x field.Ext) field.Ext {
var res field.Ext
for i := len(poly) - 1; i >= 0; i-- {
res.Mul(&res, &x)
res.B0.A0.Add(&res.B0.A0, &poly[i])
}
return res
}
2 changes: 1 addition & 1 deletion prover-ray/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.25.7

require (
github.com/consensys/gnark v0.14.1-0.20260219004710-bbfb2f70a565
github.com/consensys/gnark-crypto v0.20.1
github.com/consensys/gnark-crypto v0.20.2-0.20260514182922-df0578435b08
github.com/consensys/go-corset v1.2.10
github.com/go-playground/assert/v2 v2.2.0
github.com/sirupsen/logrus v1.9.4
Expand Down
4 changes: 2 additions & 2 deletions prover-ray/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/consensys/gnark v0.14.1-0.20260219004710-bbfb2f70a565 h1:NlOAmbLYsVb/hcuOBxza6CAA+233tB0eFiunGVEMyv4=
github.com/consensys/gnark v0.14.1-0.20260219004710-bbfb2f70a565/go.mod h1:EoWWbEboQRydCqJDSA7zrFxucIeoy/5R+MDx04oFpF4=
github.com/consensys/gnark-crypto v0.20.1 h1:PXDUBvk8AzhvWowHLWBEAfUQcV1/aZgWIqD6eMpXmDg=
github.com/consensys/gnark-crypto v0.20.1/go.mod h1:RBWrSgy+IDbGR69RRV313th3M/aZU1ubk2om+qHuTSc=
github.com/consensys/gnark-crypto v0.20.2-0.20260514182922-df0578435b08 h1:EdljQKaHxACX5JMSTXlVM9R8qASU/W1husqDsB2b5tU=
github.com/consensys/gnark-crypto v0.20.2-0.20260514182922-df0578435b08/go.mod h1:NzeBHSZ49bIM7RtrNTYYR2kymTqwvI/A4eTgQlyQc+Q=
github.com/consensys/go-corset v1.2.10 h1:uKUICiHmERuMWzDRiRJr285fV2WncNGiCENSdNcQodY=
github.com/consensys/go-corset v1.2.10/go.mod h1:QKFoNJZHdCrDslg9XFjk+GoFMgrhKSVdBNnx4hq7WJA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
2 changes: 1 addition & 1 deletion prover-ray/maths/koalabear/circuit/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This package contains two main types:
// - [Var]: A circuit variable over the KoalaBear base field
// - [Ext]: A circuit variable over the degree-4 extension field
// - [Ext]: A circuit variable over the degree-6 extension field
//
// These types abstract over native and emulated arithmetic, allowing the same
// circuit code to work in both native KoalaBear circuits and emulated circuits
Expand Down
Loading
Loading