-
Notifications
You must be signed in to change notification settings - Fork 5
/
circuits.go
246 lines (202 loc) · 7.48 KB
/
circuits.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
package circuits
import (
"reflect"
"sync"
"github.com/pkg/errors"
)
// CircuitID is alias for circuit identifier
type CircuitID string
const (
// AuthCircuitID is a type that must be used for auth.circom
AuthCircuitID CircuitID = "auth"
// AuthCircuitID is a type that must be used for authV2.circom
AuthV2CircuitID CircuitID = "authV2"
// StateTransitionCircuitID is a type that must be used for stateTransition.circom
StateTransitionCircuitID CircuitID = "stateTransition"
// AtomicQueryMTPCircuitID is a type for credentialAtomicQueryMTP.circom
AtomicQueryMTPCircuitID CircuitID = "credentialAtomicQueryMTP"
// AtomicQueryMTPV2CircuitID is a type for credentialAtomicQueryMTPV2.circom
AtomicQueryMTPV2CircuitID CircuitID = "credentialAtomicQueryMTPV2"
// AtomicQueryV3CircuitID is a type for credentialAtomicQueryV3.circom
AtomicQueryV3CircuitID CircuitID = "credentialAtomicQueryV3-beta.1"
// AtomicQueryMTPV2OnChainCircuitID is a type for credentialAtomicQueryMTPV2OnChain.circom
AtomicQueryMTPV2OnChainCircuitID CircuitID = "credentialAtomicQueryMTPV2OnChain"
// AtomicQuerySigCircuitID is a type for credentialAttrQuerySig.circom
AtomicQuerySigCircuitID CircuitID = "credentialAtomicQuerySig"
// AtomicQuerySigV2CircuitID is a type for credentialAttrQuerySigV2.circom
AtomicQuerySigV2CircuitID CircuitID = "credentialAtomicQuerySigV2"
// AtomicQuerySigV2OnChainCircuitID is a type for credentialAttrQuerySigV2OnChain.circom
AtomicQuerySigV2OnChainCircuitID CircuitID = "credentialAtomicQuerySigV2OnChain"
// AtomicQueryV3OnChainCircuitID is a type for credentialAtomicQueryV3OnChain.circom
AtomicQueryV3OnChainCircuitID CircuitID = "credentialAtomicQueryV3OnChain-beta.1"
// JsonLDAtomicQueryMTPCircuitID is a type for credentialJsonLDAtomicQueryMTP.circom
JsonLDAtomicQueryMTPCircuitID CircuitID = "credentialJsonLDAtomicQueryMTP"
// SybilMTPCircuitID is a type for sybilMTP.circom
SybilMTPCircuitID CircuitID = "sybilCredentialAtomicMTP"
// SybilSigCircuitID is a type for sybilSig.circom
SybilSigCircuitID CircuitID = "sybilCredentialAtomicSig"
// LinkedMultiQuery10CircuitID is a type for linkedMultiQuery10.circom
LinkedMultiQuery10CircuitID CircuitID = "linkedMultiQuery10-beta.1"
)
// ErrorCircuitIDNotFound returns if CircuitID is not registered
var ErrorCircuitIDNotFound = errors.New("circuit id not supported")
const (
defaultMTLevels = 40 // max MT levels, default value for identity circuits
defaultValueArraySize = 64 // max value array size, default value for identity circuits
defaultMTLevelsOnChain = 64 // max MT levels on chain, default value for identity circuits
defaultMTLevelsClaim = 32 // max MT levels of JSON-LD merklization on claim
)
var circuitsRegistry = map[CircuitID]Data{}
var circuitsLock = new(sync.RWMutex)
// RegisterCircuit is factory for circuit init.
// This is done during init() in the method's implementation
func RegisterCircuit(id CircuitID, c Data) {
circuitsLock.Lock()
defer circuitsLock.Unlock()
circuitsRegistry[id] = c
}
// nolint // register supported circuit
func init() {
RegisterCircuit(AuthCircuitID, Data{
Input: AuthInputs{},
Output: &AuthPubSignals{},
})
RegisterCircuit(AuthV2CircuitID, Data{
Input: AuthV2Inputs{},
Output: &AuthV2PubSignals{},
})
RegisterCircuit(StateTransitionCircuitID, Data{
Input: StateTransitionInputs{},
Output: &StateTransitionPubSignals{},
})
RegisterCircuit(AtomicQueryMTPCircuitID, Data{
Input: AtomicQueryMTPInputs{},
Output: &AtomicQueryMTPPubSignals{},
})
RegisterCircuit(AtomicQueryMTPV2CircuitID, Data{
Input: AtomicQueryMTPV2Inputs{},
Output: &AtomicQueryMTPV2PubSignals{},
})
RegisterCircuit(AtomicQuerySigCircuitID, Data{
Input: AtomicQuerySigInputs{},
Output: &AtomicQuerySigPubSignals{},
})
RegisterCircuit(AtomicQuerySigV2CircuitID, Data{
Input: AtomicQuerySigV2Inputs{},
Output: &AtomicQuerySigV2PubSignals{},
})
RegisterCircuit(AtomicQueryV3CircuitID, Data{
Input: AtomicQueryV3Inputs{},
Output: &AtomicQueryV3PubSignals{},
})
RegisterCircuit(AtomicQuerySigV2OnChainCircuitID, Data{
Input: AtomicQuerySigV2OnChainInputs{},
Output: &AtomicQuerySigV2OnChainPubSignals{},
})
RegisterCircuit(AtomicQueryMTPV2OnChainCircuitID, Data{
Input: AtomicQueryMTPV2OnChainInputs{},
Output: &AtomicQueryMTPV2OnChainPubSignals{},
})
RegisterCircuit(SybilMTPCircuitID, Data{
Input: SybilAtomicMTPInputs{},
Output: &SybilAtomicMTPPubSignals{},
})
RegisterCircuit(SybilSigCircuitID, Data{
Input: SybilAtomicSigInputs{},
Output: &SybilAtomicSigPubSignals{},
})
RegisterCircuit(AtomicQueryV3OnChainCircuitID, Data{
Input: AtomicQueryV3OnChainInputs{},
Output: &AtomicQueryV3OnChainPubSignals{},
})
}
// BaseConfig base circuit's config, provides default configuration for default circuits
type BaseConfig struct {
MTLevel int // Max levels of MT
ValueArraySize int // Size if value array in identity circuits
MTLevelOnChain int // Max levels of MT on chain
MTLevelClaim int // Max level of JSONLD claim
}
// GetMTLevel max circuit MT levels
func (c BaseConfig) GetMTLevel() int {
if c.MTLevel == 0 {
return defaultMTLevels
}
return c.MTLevel
}
// GetValueArrSize return size of circuits value array size
func (c BaseConfig) GetValueArrSize() int {
if c.ValueArraySize == 0 {
return defaultValueArraySize
}
return c.ValueArraySize
}
// GetMTLevel max circuit MT levels on chain
func (c BaseConfig) GetMTLevelOnChain() int {
if c.MTLevelOnChain == 0 {
return defaultMTLevelsOnChain
}
return c.MTLevelOnChain
}
// GetMTLevelsClaim max jsonld Claim levels
func (c BaseConfig) GetMTLevelsClaim() int {
if c.MTLevelClaim == 0 {
return defaultMTLevelsClaim
}
return c.MTLevelClaim
}
// InputsMarshaller interface implemented by types that can marshal circuit `input` structures
type InputsMarshaller interface {
InputsMarshal() ([]byte, error)
}
// PubSignalsUnmarshaller interface implemented by types that can unmarshal circuit `output` structures
type PubSignalsUnmarshaller interface {
PubSignalsUnmarshal(data []byte) error
}
// PubSignalsMapper interface implemented by types that can unmarshal circuit `output` to map
type PubSignalsMapper interface {
GetObjMap() map[string]interface{}
}
// PubSignals interface implemented by types that can be registered in circuit registry
type PubSignals interface {
PubSignalsUnmarshaller
PubSignalsMapper
}
// KeyLoader interface, if key should be fetched from file system, CDN, IPFS etc,
// this interface may be implemented for key loading from a specific place
type KeyLoader interface {
Load() ([]byte, error)
}
// Data circuit type
type Data struct {
Input InputsMarshaller // input values type
Output PubSignals // output values type
}
// UnmarshalCircuitOutput unmarshal bytes to specific circuit Output type associated with id
func UnmarshalCircuitOutput(id CircuitID, b []byte) (map[string]interface{}, error) {
circuitsLock.RLock()
defer circuitsLock.RUnlock()
circuitOutputType, exist := circuitsRegistry[id]
if !exist {
return nil, ErrorCircuitIDNotFound
}
typ := reflect.TypeOf(circuitOutputType.Output)
val := reflect.New(typ.Elem())
newPointer := val.Interface()
err := newPointer.(PubSignalsUnmarshaller).PubSignalsUnmarshal(b)
if err != nil {
return nil, err
}
m := newPointer.(PubSignalsMapper).GetObjMap()
return m, nil
}
// GetCircuit return circuit Data
func GetCircuit(id CircuitID) (*Data, error) {
circuitsLock.RLock()
defer circuitsLock.RUnlock()
circuit, ok := circuitsRegistry[id]
if !ok {
return nil, ErrorCircuitIDNotFound
}
return &circuit, nil
}