Skip to content

Commit

Permalink
docs: add examples into documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ivokub committed Nov 14, 2022
1 parent 1662e35 commit c233c7c
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 0 deletions.
82 changes: 82 additions & 0 deletions std/math/emulated/doc_example_field_test.go
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
}
62 changes: 62 additions & 0 deletions std/math/emulated/doc_example_fieldapi_builder_test.go
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
}
85 changes: 85 additions & 0 deletions std/math/emulated/doc_example_fieldapi_test.go
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
}

0 comments on commit c233c7c

Please sign in to comment.