github.com/consensys/gnark@v0.11.0/test/engine_test.go (about) 1 package test 2 3 import ( 4 "fmt" 5 "math/big" 6 "testing" 7 8 "github.com/consensys/gnark" 9 "github.com/consensys/gnark-crypto/ecc" 10 11 "github.com/consensys/gnark/constraint/solver" 12 "github.com/consensys/gnark/frontend" 13 "github.com/consensys/gnark/std/math/bits" 14 ) 15 16 type hintCircuit struct { 17 A, B frontend.Variable 18 } 19 20 func (circuit *hintCircuit) Define(api frontend.API) error { 21 res, err := api.Compiler().NewHint(bits.GetHints()[0], 1, circuit.A, 3) 22 if err != nil { 23 return fmt.Errorf("IthBit circuitA 3: %w", err) 24 } 25 a3b := res[0] 26 res, err = api.Compiler().NewHint(bits.GetHints()[0], 1, circuit.A, 25) 27 if err != nil { 28 return fmt.Errorf("IthBit circuitA 25: %w", err) 29 } 30 a25b := res[0] 31 32 res, err = api.Compiler().NewHint(solver.InvZeroHint, 1, circuit.A) 33 if err != nil { 34 return fmt.Errorf("IsZero CircuitA: %w", err) 35 } 36 aInvZero := res[0] 37 38 res, err = api.Compiler().NewHint(solver.InvZeroHint, 1, circuit.B) 39 if err != nil { 40 return fmt.Errorf("IsZero, CircuitB") 41 } 42 bInvZero := res[0] 43 44 // good witness 45 expectedA := big.NewInt(8) 46 expectedA.ModInverse(expectedA, api.Compiler().Field()) 47 48 api.AssertIsEqual(aInvZero, expectedA) 49 api.AssertIsEqual(bInvZero, 0) // b == 0, invZero(b) == 0 50 api.AssertIsEqual(a3b, 1) 51 api.AssertIsEqual(a25b, 0) 52 53 return nil 54 } 55 56 func TestBuiltinHints(t *testing.T) { 57 for _, curve := range gnark.Curves() { 58 if err := IsSolved(&hintCircuit{}, &hintCircuit{ 59 A: (0b1000), 60 B: (0), 61 }, curve.ScalarField()); err != nil { 62 t.Fatal(err) 63 } 64 65 if err := IsSolved(&hintCircuit{}, &hintCircuit{ 66 A: (0b10), 67 B: (1), 68 }, curve.ScalarField()); err == nil { 69 t.Fatal("witness shouldn't solve circuit") 70 } 71 } 72 73 } 74 75 var isDeferCalled bool 76 77 type EmptyCircuit struct { 78 X frontend.Variable 79 } 80 81 func (c *EmptyCircuit) Define(api frontend.API) error { 82 api.AssertIsEqual(c.X, 0) 83 api.Compiler().Defer(func(api frontend.API) error { 84 isDeferCalled = true 85 return nil 86 }) 87 return nil 88 } 89 90 func TestPreCompileHook(t *testing.T) { 91 c := &EmptyCircuit{} 92 w := &EmptyCircuit{ 93 X: 0, 94 } 95 isDeferCalled = false 96 err := IsSolved(c, w, ecc.BN254.ScalarField()) 97 if err != nil { 98 t.Fatal(err) 99 } 100 if !isDeferCalled { 101 t.Error("callback not called") 102 } 103 }