@@ -32,6 +32,7 @@ type SubCircuit struct {
3232type SubCircuitRegistry struct {
3333 m map [uint64 ]* SubCircuit
3434 outputStructure map [uint64 ]* sliceStructure
35+ fullHash map [uint64 ][32 ]byte
3536}
3637
3738// SubCircuitAPI defines methods for working with subcircuits.
@@ -44,9 +45,22 @@ func newSubCircuitRegistry() *SubCircuitRegistry {
4445 return & SubCircuitRegistry {
4546 m : make (map [uint64 ]* SubCircuit ),
4647 outputStructure : make (map [uint64 ]* sliceStructure ),
48+ fullHash : make (map [uint64 ][32 ]byte ),
4749 }
4850}
4951
52+ func (sr * SubCircuitRegistry ) getFullHashId (h [32 ]byte ) uint64 {
53+ id := binary .LittleEndian .Uint64 (h [:8 ])
54+ if v , ok := sr .fullHash [id ]; ok {
55+ if v != h {
56+ panic ("subcircuit id collision" )
57+ }
58+ return id
59+ }
60+ sr .fullHash [id ] = h
61+ return id
62+ }
63+
5064func (parent * builder ) callSubCircuit (
5165 circuitId uint64 ,
5266 input_ []frontend.Variable ,
@@ -93,7 +107,7 @@ func (parent *builder) callSubCircuit(
93107func (parent * builder ) MemorizedSimpleCall (f SubCircuitSimpleFunc , input []frontend.Variable ) []frontend.Variable {
94108 name := GetFuncName (f )
95109 h := sha256 .Sum256 ([]byte (fmt .Sprintf ("simple_%d(%s)_%d" , len (name ), name , len (input ))))
96- circuitId := binary . LittleEndian . Uint64 ( h [: 8 ] )
110+ circuitId := parent . root . registry . getFullHashId ( h )
97111 return parent .callSubCircuit (circuitId , input , f )
98112}
99113
@@ -205,13 +219,10 @@ func rebuildSliceVariables(vars []frontend.Variable, s *sliceStructure) reflect.
205219func isTypeSimple (t reflect.Type ) bool {
206220 k := t .Kind ()
207221 switch k {
208- case reflect .Bool :
209- return true
210- case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
211- return true
212- case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 :
213- return true
214- case reflect .String :
222+ case reflect .Bool ,
223+ reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,
224+ reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 ,
225+ reflect .String :
215226 return true
216227 default :
217228 return false
@@ -310,7 +321,9 @@ func (parent *builder) MemorizedCall(fn SubCircuitFunc, inputs ...interface{}) i
310321 vs := inputVals [i ].String ()
311322 h .Write ([]byte (strconv .Itoa (len (vs )) + vs ))
312323 }
313- circuitId := binary .LittleEndian .Uint64 (h .Sum (nil )[:8 ])
324+ var tmp [32 ]byte
325+ copy (tmp [:], h .Sum (nil ))
326+ circuitId := parent .root .registry .getFullHashId (tmp )
314327
315328 // sub-circuit caller
316329 fnInner := func (api frontend.API , input []frontend.Variable ) []frontend.Variable {
0 commit comments