@@ -30,6 +30,7 @@ import (
3030 "fmt"
3131 "math/big"
3232
33+ "github.com/consensys/gnark-crypto/ecc"
3334 "github.com/consensys/gnark/frontend"
3435 "github.com/consensys/gnark/std/math/emulated"
3536)
@@ -38,6 +39,8 @@ const (
3839 N = 1 << 12 // 4096 evaluation points
3940)
4041
42+ var maxCanonicalBN254Scalar = emulated.ValueOf [FE ](new (big.Int ).Sub (ecc .BN254 .ScalarField (), big .NewInt (1 )))
43+
4144// FE is type modulus for BLS12‑381 Fr.
4245type FE = emulated.BLS12381Fr
4346
@@ -175,22 +178,18 @@ func VerifyFullBlobEvaluationBN254(
175178 // Convert all native scalars => emulated via the hint
176179 var blobEmu [N ]emulated.Element [FE ]
177180 for i := range N {
178- e , err := hintNativeToEmu (api , fr , blob [i ])
181+ e , err := liftNativeBN254ToEmulated (api , fr , blob [i ])
179182 if err != nil {
180183 return err
181184 }
182185 blobEmu [i ] = * e
183- // verify that the native input matches the emulated one created by the hint
184- api .AssertIsEqual (emulatedToNative (api , & blobEmu [i ]), blob [i ])
185186 }
186187
187188 // Convert the native evaluation point z => emulated
188- zEmu , err := hintNativeToEmu (api , fr , z )
189+ zEmu , err := liftNativeBN254ToEmulated (api , fr , z )
189190 if err != nil {
190191 return err
191192 }
192- // verify that the native input matches the emulated one created by the hint
193- api .AssertIsEqual (emulatedToNative (api , zEmu ), z )
194193
195194 // Verify the barycentric evaluation (does NOT check KZG commitment/proof)
196195 if err := VerifyBarycentricEvaluation (api , zEmu , y , blobEmu ); err != nil {
@@ -201,8 +200,20 @@ func VerifyFullBlobEvaluationBN254(
201200 return VerifyKZGProof (api , commitment , proof , * zEmu , * y )
202201}
203202
203+ // liftNativeBN254ToEmulated lifts a native BN254 scalar into the emulated
204+ // field, constraining the witness to the canonical BN254 scalar range [0, pBN254)
205+ // and proving it recomposes back to the original native input.
206+ func liftNativeBN254ToEmulated (api frontend.API , fr * emulated.Field [FE ], native frontend.Variable ) (* emulated.Element [FE ], error ) {
207+ emu , err := hintNativeToEmu (fr , native )
208+ if err != nil {
209+ return nil , err
210+ }
211+ fr .AssertIsLessOrEqual (emu , & maxCanonicalBN254Scalar )
212+ api .AssertIsEqual (emulatedToNative (api , emu ), native )
213+ return emu , nil
214+ }
215+
204216// emulatedToNative converts an emulated element to a native BN254 variable.
205- // This is used to ensure that the native input matches the emulated output.
206217func emulatedToNative (api frontend.API , e * emulated.Element [FE ]) frontend.Variable {
207218 nbBits := FE {}.BitsPerLimb ()
208219 acc := frontend .Variable (0 )
0 commit comments