Skip to content
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
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
14 changes: 7 additions & 7 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 All @@ -210,6 +210,6 @@ func (r *RsParams) EncodeFromMonomials(coefficients []field.Ext) []field.Ext {
copy(buf, coefficients)
// DIT FFT expects bit-reversed input; natural-order evaluations come out.
utils.BitReverse(buf)
r.Domains[1].FFTExt(buf, fft.DIT)
r.Domains[1].FFTExt6(buf, fft.DIT)
return buf
}
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
2 changes: 1 addition & 1 deletion prover-ray/crypto/koalabear/vortex/verifier_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func CheckLinComb(
y := polynomials.EvalCanonical(field.VecFromBase(fullCol), field.ElemFromExt(alpha)).AsExt()
other := evals[selectedColID]

if y != other {
if !y.Equal(&other) {
return fmt.Errorf("the linear combination is inconsistent %v : %v", y.String(), other.String())
}
}
Expand Down
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
40 changes: 24 additions & 16 deletions prover-ray/maths/koalabear/circuit/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ func TestVarEmulated(t *testing.T) {

// TestExtCircuit tests Ext operations
type TestExtCircuit struct {
A, B Ext
AddAB Ext
SubAB Ext
MulAB Ext
SquareA Ext
DivAB Ext
InvA Ext
A, B Ext
AddAB Ext
SubAB Ext
MulAB Ext
SquareA Ext
MulByNonResidueA Ext
DivAB Ext
InvA Ext
}

func (c *TestExtCircuit) Define(api frontend.API) error {
Expand All @@ -121,6 +122,9 @@ func (c *TestExtCircuit) Define(api frontend.API) error {
squareA := f.SquareExt(c.A)
f.AssertIsEqualExt(squareA, c.SquareA)

mulByNonResidueA := f.MulByNonResidueExt(c.A)
f.AssertIsEqualExt(mulByNonResidueA, c.MulByNonResidueA)

divAB := f.DivExt(c.A, c.B)
f.AssertIsEqualExt(divAB, c.DivAB)

Expand All @@ -131,29 +135,33 @@ func (c *TestExtCircuit) Define(api frontend.API) error {
}

func getExtWitness() *TestExtCircuit {
var a, b, addab, subab, mulab, squarea, inva, divab field.Ext
var a, b, addab, subab, mulab, squarea, mulByNonResidueA, inva, divab field.Ext
if _, err := a.SetRandom(); err != nil {
panic(err)
}
if _, err := b.SetRandom(); err != nil {
panic(err)
}
var nonResidueRoot field.Ext
nonResidueRoot.B1.A0.SetOne()
addab.Add(&a, &b)
subab.Sub(&a, &b)
mulab.Mul(&a, &b)
squarea.Square(&a)
mulByNonResidueA.Mul(&a, &nonResidueRoot)
divab.Div(&a, &b)
inva.Inverse(&a)

return &TestExtCircuit{
A: NewExt(a),
B: NewExt(b),
AddAB: NewExt(addab),
SubAB: NewExt(subab),
MulAB: NewExt(mulab),
SquareA: NewExt(squarea),
DivAB: NewExt(divab),
InvA: NewExt(inva),
A: NewExt(a),
B: NewExt(b),
AddAB: NewExt(addab),
SubAB: NewExt(subab),
MulAB: NewExt(mulab),
SquareA: NewExt(squarea),
MulByNonResidueA: NewExt(mulByNonResidueA),
DivAB: NewExt(divab),
InvA: NewExt(inva),
}
}

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