-
Notifications
You must be signed in to change notification settings - Fork 366
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add examples into documentation
- Loading branch information
Showing
3 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package emulated_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/consensys/gnark-crypto/ecc" | ||
"github.com/consensys/gnark/backend" | ||
"github.com/consensys/gnark/backend/groth16" | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/frontend/cs/r1cs" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type ExampleFieldCircuit[T emulated.FieldParams] struct { | ||
In1 emulated.Element[T] | ||
In2 emulated.Element[T] | ||
Res emulated.Element[T] | ||
} | ||
|
||
func (c *ExampleFieldCircuit[T]) Define(api frontend.API) error { | ||
f, err := emulated.NewField[T](api) | ||
if err != nil { | ||
return fmt.Errorf("new field: %w", err) | ||
} | ||
res := f.Mul(&c.In1, &c.In2) // non-reducing | ||
res = f.Reduce(res) | ||
f.AssertIsEqual(res, &c.Res) | ||
return nil | ||
} | ||
|
||
// Example of using [Field] instance. The witness elements must be [Element] | ||
// type. | ||
func ExampleField() { | ||
circuit := ExampleFieldCircuit[emulated.BN254Fp]{} | ||
witness := ExampleFieldCircuit[emulated.BN254Fp]{ | ||
In1: emulated.NewElement[emulated.BN254Fp](3), | ||
In2: emulated.NewElement[emulated.BN254Fp](5), | ||
Res: emulated.NewElement[emulated.BN254Fp](15), | ||
} | ||
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("compiled") | ||
} | ||
witnessData, err := frontend.NewWitness(&witness, ecc.BN254.ScalarField()) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("secret witness parsed") | ||
} | ||
publicWitnessData, err := witnessData.Public() | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("public witness parsed") | ||
} | ||
pk, vk, err := groth16.Setup(ccs) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("setup done") | ||
} | ||
proof, err := groth16.Prove(ccs, pk, witnessData, backend.WithHints(emulated.GetHints()...)) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("proved") | ||
} | ||
err = groth16.Verify(proof, vk, publicWitnessData) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("verified") | ||
} | ||
// Output: compiled | ||
// secret witness parsed | ||
// public witness parsed | ||
// setup done | ||
// proved | ||
// verified | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package emulated_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/consensys/gnark-crypto/ecc" | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/frontend/cs/r1cs" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
"github.com/consensys/gnark/test" | ||
) | ||
|
||
type ExampleFieldAPIBuilderCircuit struct { | ||
In1 frontend.Variable | ||
In2 frontend.Variable | ||
Res frontend.Variable | ||
} | ||
|
||
func (c *ExampleFieldAPIBuilderCircuit) Define(api frontend.API) error { | ||
// now use API as would use native frontend.API | ||
res := api.Mul(c.In1, c.In2) // native element is converted to non-native on-the-fly | ||
api.AssertIsEqual(res, c.Res) | ||
return nil | ||
} | ||
|
||
// Example of using [FieldAPI] implementing [frontend.Builder] interface. The | ||
// witness elements may be of any type, they are converted to [Element] type | ||
// instance by the built-in hooks of the wrapped builder during parsing. | ||
func ExampleFieldAPI_builder() { | ||
circuit := ExampleFieldAPIBuilderCircuit{} | ||
witness := ExampleFieldAPIBuilderCircuit{ | ||
In1: emulated.NewElement[emulated.BN254Fp](3), | ||
In2: emulated.NewElement[emulated.BN254Fp](5), | ||
Res: emulated.NewElement[emulated.BN254Fp](15), | ||
} | ||
_, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit, frontend.WithBuilderWrapper(func(b frontend.Builder) frontend.Builder { | ||
wb, err := emulated.NewBuilder[emulated.BN254Fp](b) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return wb | ||
})) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("compiled using builder wrapper") | ||
} | ||
err = test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField(), test.WithApiWrapper(func(a frontend.API) frontend.API { | ||
wa, err := emulated.NewAPI[emulated.BN254Fp](a) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return wa | ||
})) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("solved using test engine") | ||
} | ||
// Output: compiled using builder wrapper | ||
// solved using test engine | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package emulated_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/consensys/gnark-crypto/ecc" | ||
"github.com/consensys/gnark/backend" | ||
"github.com/consensys/gnark/backend/groth16" | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/frontend/cs/r1cs" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type ExampleFieldAPICircuit struct { | ||
InNative frontend.Variable // must be integer-like, not [Element] | ||
InNonnative emulated.Element[emulated.BN254Fp] | ||
Res emulated.Element[emulated.BN254Fp] | ||
} | ||
|
||
func (c *ExampleFieldAPICircuit) Define(api frontend.API) error { | ||
api, err := emulated.NewAPI[emulated.BN254Fp](api) | ||
if err != nil { | ||
return fmt.Errorf("new api: %w", err) | ||
} | ||
// now use API as would use native frontend.API | ||
res := api.Mul(c.InNative, c.InNonnative) // native element is converted to non-native on-the-fly | ||
api.AssertIsEqual(res, c.Res) | ||
return nil | ||
} | ||
|
||
// Example of using [FieldAPI] for drop-in replacement of native API. | ||
// | ||
// Witness elements must be [Element] type for successful compiling and parsing | ||
// of the circuit. | ||
func ExampleFieldAPI_api() { | ||
// compiling the circuit | ||
circuit := ExampleFieldAPICircuit{} | ||
witness := ExampleFieldAPICircuit{ | ||
InNative: 3, | ||
InNonnative: emulated.NewElement[emulated.BN254Fp](5), | ||
Res: emulated.NewElement[emulated.BN254Fp](15), | ||
} | ||
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("compiled") | ||
} | ||
witnessData, err := frontend.NewWitness(&witness, ecc.BN254.ScalarField()) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("secret witness parsed") | ||
} | ||
publicWitnessData, err := witnessData.Public() | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("public witness parsed") | ||
} | ||
pk, vk, err := groth16.Setup(ccs) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("setup done") | ||
} | ||
proof, err := groth16.Prove(ccs, pk, witnessData, backend.WithHints(emulated.GetHints()...)) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("proved") | ||
} | ||
err = groth16.Verify(proof, vk, publicWitnessData) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("verified") | ||
} | ||
// Output: compiled | ||
// secret witness parsed | ||
// public witness parsed | ||
// setup done | ||
// proved | ||
// verified | ||
} |