forked from Consensys/gnark
-
Notifications
You must be signed in to change notification settings - Fork 0
/
witness.go
98 lines (85 loc) · 2.33 KB
/
witness.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package frontend
import (
"math/big"
"reflect"
"github.com/consensys/gnark/backend/witness"
"github.com/consensys/gnark/frontend/schema"
)
// NewWitness build an ordered vector of field elements from the given assignment (Circuit)
// if PublicOnly is specified, returns the public part of the witness only
// else returns [public | secret]. The result can then be serialized to / from json & binary.
//
// See ExampleWitness in witness package for usage.
func NewWitness(assignment Circuit, field *big.Int, opts ...WitnessOption) (witness.Witness, error) {
opt, err := options(opts...)
if err != nil {
return nil, err
}
// count the leaves
s, err := schema.Walk(assignment, tVariable, nil)
if err != nil {
return nil, err
}
if opt.publicOnly {
s.Secret = 0
}
// allocate the witness
w, err := witness.New(field)
if err != nil {
return nil, err
}
// write the public | secret values in a chan
chValues := make(chan any)
go func() {
defer close(chValues)
schema.Walk(assignment, tVariable, func(leaf schema.LeafInfo, tValue reflect.Value) error {
if leaf.Visibility == schema.Public {
chValues <- tValue.Interface()
}
return nil
})
if !opt.publicOnly {
schema.Walk(assignment, tVariable, func(leaf schema.LeafInfo, tValue reflect.Value) error {
if leaf.Visibility == schema.Secret {
chValues <- tValue.Interface()
}
return nil
})
}
}()
if err := w.Fill(s.Public, s.Secret, chValues); err != nil {
return nil, err
}
return w, nil
}
// NewSchema returns the schema corresponding to the circuit structure.
//
// This is used to JSON (un)marshall witnesses.
func NewSchema(circuit Circuit) (*schema.Schema, error) {
return schema.New(circuit, tVariable)
}
// default options
func options(opts ...WitnessOption) (witnessConfig, error) {
// apply options
opt := witnessConfig{
publicOnly: false,
}
for _, option := range opts {
if err := option(&opt); err != nil {
return opt, err
}
}
return opt, nil
}
// WitnessOption sets optional parameter to witness instantiation from an assignment
type WitnessOption func(*witnessConfig) error
type witnessConfig struct {
publicOnly bool
}
// PublicOnly enables to instantiate a witness with the public part only of the assignment
func PublicOnly() WitnessOption {
return func(opt *witnessConfig) error {
opt.publicOnly = true
return nil
}
}