From 56ef11a57018a37e75730b4ffa40ae40b0eca8dd Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Mon, 17 Apr 2023 04:43:38 -0400 Subject: [PATCH 01/24] Witness implementation using tetratelabs/wazero --- witness/circom2witnesscalc_wazero.go | 643 ++++++++++++++++++++++ witness/circom2witnesscalc_wazero_test.go | 189 +++++++ witness/go.mod | 8 +- witness/go.sum | 16 +- witness/test_files/circom2_1_0/input.json | 2 +- 5 files changed, 851 insertions(+), 7 deletions(-) create mode 100644 witness/circom2witnesscalc_wazero.go create mode 100644 witness/circom2witnesscalc_wazero_test.go diff --git a/witness/circom2witnesscalc_wazero.go b/witness/circom2witnesscalc_wazero.go new file mode 100644 index 0000000..79a2484 --- /dev/null +++ b/witness/circom2witnesscalc_wazero.go @@ -0,0 +1,643 @@ +package witness + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "log" + "math" + "math/big" + "strings" + + "github.com/iden3/go-iden3-crypto/constants" + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/api" +) + +type Circom2WZWitnessCalculator struct { + runtime wazero.Runtime + modRuntime api.Module + compiledModule wazero.CompiledModule +} + +func NewCircom2WZWitnessCalculator( + wasmBytes []byte) (*Circom2WZWitnessCalculator, error) { + + runtime := wazero.NewRuntime(context.Background()) + + ctx := context.Background() + modRuntime, err := runtime.NewHostModuleBuilder("runtime"). + NewFunctionBuilder(). + WithGoFunction( + api.GoFunc(exceptionHandler), + []api.ValueType{api.ValueTypeI32}, []api.ValueType{}). + Export("exceptionHandler"). + NewFunctionBuilder(). + WithGoModuleFunction( + api.GoModuleFunc(printErrorMessage), + []api.ValueType{}, []api.ValueType{}). + Export("printErrorMessage"). + NewFunctionBuilder(). + WithGoModuleFunction( + api.GoModuleFunc(writeBufferMessage), + []api.ValueType{}, []api.ValueType{}). + Export("writeBufferMessage"). + NewFunctionBuilder(). + WithGoModuleFunction( + api.GoModuleFunc(showSharedRWMemory), + []api.ValueType{}, []api.ValueType{}). + Export("showSharedRWMemory"). + Instantiate(ctx) + if err != nil { + return nil, err + } + + compiledModule, err := runtime.CompileModule(ctx, wasmBytes) + if err != nil { + return nil, err + } + + return &Circom2WZWitnessCalculator{ + runtime: runtime, + modRuntime: modRuntime, + compiledModule: compiledModule, + }, nil +} + +func (w *Circom2WZWitnessCalculator) Close() error { + ctx := context.Background() + + err := w.compiledModule.Close(ctx) + + err2 := w.modRuntime.Close(ctx) + if err == nil { + err = err2 + } + + err2 = w.runtime.Close(ctx) + if err == nil { + err = err2 + } + + return err +} + +// CalculateWitness calculates the witness given the inputs. +func (wc *Circom2WZWitnessCalculator) CalculateWitness(inputs map[string]interface{}, + sanityCheck bool) (wtns []*big.Int, err error) { + + wCtxState := &witnessCtxState{} + ctx := withWtnsCtx(context.Background(), wCtxState) + + cfg := wazero.NewModuleConfig() + var instance api.Module + instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) + if err != nil { + return nil, err + } + defer closeWithErrOrLog(ctx, instance, &err) + + var wCtx witnessCtx + wCtx, err = calculateWtnsCtx(ctx, instance) + if err != nil { + return nil, err + } + + err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + if err != nil { + return nil, err + } + + wtns = make([]*big.Int, wCtx.witnessSize) + + for i := 0; i < int(wCtx.witnessSize); i++ { + err = wCtx.getWitness(ctx, int32(i)) + if err != nil { + return nil, err + } + arr := make([]uint32, wCtx.n32) + for j := 0; j < int(wCtx.n32); j++ { + var val int32 + val, err = wCtx.readSharedRWMemory(ctx, int32(j)) + if err != nil { + return nil, err + } + arr[int(wCtx.n32)-1-j] = uint32(val) + } + wtns[i] = fromArray32(arr) + } + + return wtns, wCtxState.err() +} + +// CalculateBinWitness calculates the witness in binary given the inputs. +func (wc *Circom2WZWitnessCalculator) CalculateBinWitness(inputs map[string]interface{}, + sanityCheck bool) (wtns []byte, err error) { + + wCtxState := &witnessCtxState{} + ctx := withWtnsCtx(context.Background(), wCtxState) + + cfg := wazero.NewModuleConfig() + var instance api.Module + instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) + if err != nil { + return nil, err + } + defer closeWithErrOrLog(ctx, instance, &err) + + var wCtx witnessCtx + // wCtx is closure around ctx, do not return it, use only in this function. + wCtx, err = calculateWtnsCtx(ctx, instance) + if err != nil { + return nil, err + } + + err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + if err != nil { + return nil, err + } + + buff := new(bytes.Buffer) + + for i := 0; i < int(wCtx.witnessSize); i++ { + err = wCtx.getWitness(ctx, int32(i)) + if err != nil { + return nil, err + } + + for j := 0; j < int(wCtx.n32); j++ { + val, err := wCtx.readSharedRWMemory(ctx, int32(j)) + if err != nil { + return nil, err + } + _ = binary.Write(buff, binary.LittleEndian, uint32(val)) + } + } + + return buff.Bytes(), wCtxState.err() +} + +// CalculateWTNSBin calculates the witness in binary given the inputs. +func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interface{}, + sanityCheck bool) (wtns []byte, err error) { + + wCtxState := &witnessCtxState{} + ctx := withWtnsCtx(context.Background(), wCtxState) + + cfg := wazero.NewModuleConfig() + var instance api.Module + instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) + if err != nil { + return nil, err + } + defer closeWithErrOrLog(ctx, instance, &err) + + var wCtx witnessCtx + // wCtx is closure around ctx, do not return it, use only in this function. + wCtx, err = calculateWtnsCtx(ctx, instance) + if err != nil { + return nil, err + } + + err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + if err != nil { + return nil, err + } + + buff := new(bytes.Buffer) + + var wResult []uint64 + wResult, err = instance.ExportedFunction("getWitnessSize").Call(ctx) + if err != nil { + return nil, err + } + witnessSize := api.DecodeI32(wResult[0]) + + buff.Grow(int(witnessSize*wCtx.n32 + wCtx.n32 + 11)) + + // wtns + _ = buff.WriteByte('w') + _ = buff.WriteByte('t') + _ = buff.WriteByte('n') + _ = buff.WriteByte('s') + + //version 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + //number of sections: 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + //id section 1 + _ = binary.Write(buff, binary.LittleEndian, uint32(1)) + + n8 := wCtx.n32 * 4 + //id section 1 length in 64bytes + idSection1length := 8 + n8 + _ = binary.Write(buff, binary.LittleEndian, uint64(idSection1length)) + + //this.n32 + _ = binary.Write(buff, binary.LittleEndian, uint32(n8)) + + //prime number + getRawPrime := instance.ExportedFunction("getRawPrime") + wResult, err = getRawPrime.Call(ctx) + if err != nil { + return nil, err + } + + for j := 0; j < int(wCtx.n32); j++ { + data, err := wCtx.readSharedRWMemory(ctx, int32(j)) + if err != nil { + return nil, err + } + _ = binary.Write(buff, binary.LittleEndian, uint32(data)) + } + + // witness size + _ = binary.Write(buff, binary.LittleEndian, uint32(witnessSize)) + + //id section 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + // section 2 length + idSection2length := n8 * witnessSize + _ = binary.Write(buff, binary.LittleEndian, uint64(idSection2length)) + + getWitness := instance.ExportedFunction("getWitness") + for i := 0; i < int(witnessSize); i++ { + _, err = getWitness.Call(ctx, api.EncodeI32(int32(i))) + if err != nil { + return nil, err + } + + for j := 0; j < int(wCtx.n32); j++ { + var data int32 + data, err = wCtx.readSharedRWMemory(ctx, int32(j)) + if err != nil { + return nil, err + } + _ = binary.Write(buff, binary.LittleEndian, uint32(data)) + } + } + + return buff.Bytes(), wCtxState.err() +} + +func (w *Circom2WZWitnessCalculator) doCalculateWitness(ctx context.Context, + instance api.Module, + wCtx witnessCtx, + inputs map[string]any, + sanityCheck bool) (err error) { + + if err = wCtx.init(ctx, sanityCheck); err != nil { + return err + } + + inputCntr := 0 + + var arrFr []int32 + var signalSize int32 + for k := range inputs { + hMSB, hLSB := fnvHash(k) + signalSize, err = wCtx.getInputSignalSize(ctx, hMSB, hLSB) + if err != nil { + return err + } + fArr := make([]*big.Int, 0, signalSize) + fArr, err = flatSlice2(fArr, inputs[k]) + if err != nil { + return err + } + if len(fArr) != int(signalSize) { + return errors.New("signal size mismatch") + } + + for i := range fArr { + arrFr = encodeInt(fArr[i], int(wCtx.n32)) + for j := range arrFr { + err = wCtx.writeSharedRWMemory(ctx, + int32(j), arrFr[int(wCtx.n32)-1-j]) + if err != nil { + return err + } + } + err = wCtx.setInputSignal(ctx, hMSB, hLSB, int32(i)) + if err != nil { + return err + } + inputCntr++ + } + } + + if wCtx.inputSize != int32(inputCntr) { + return errors.New("input size mismatch") + } + + return nil +} + +type witnessCtx struct { + n32 int32 + inputSize int32 + witnessSize int32 + init func(ctx context.Context, sanityCheck bool) error + getInputSignalSize func(ctx context.Context, hMSB, hLSB int32) (int32, + error) + writeSharedRWMemory func(ctx context.Context, sigIdx, data int32) error + setInputSignal func(ctx context.Context, hMSB, hLSB, z int32) error + readSharedRWMemory func(ctx context.Context, i int32) (int32, error) + getWitness func(ctx context.Context, i int32) error +} + +func calculateWtnsCtx(ctx context.Context, + instance api.Module) (witnessCtx, error) { + + var wCtx witnessCtx + var wResult []uint64 + var err error + + getFieldNumLen32 := instance.ExportedFunction("getFieldNumLen32") + wResult, err = getFieldNumLen32.Call(ctx) + if err != nil { + return wCtx, err + } + wCtx.n32 = api.DecodeI32(wResult[0]) + + wResult, err = instance.ExportedFunction("getInputSize").Call(ctx) + if err != nil { + return wCtx, err + } + wCtx.inputSize = api.DecodeI32(wResult[0]) + + wResult, err = instance.ExportedFunction("getWitnessSize").Call(ctx) + if err != nil { + return wCtx, err + } + wCtx.witnessSize = api.DecodeI32(wResult[0]) + + _init := instance.ExportedFunction("init") + wCtx.init = func(ctx context.Context, sanityCheck bool) error { + sch := int32(0) + if sanityCheck { + sch = 1 + } + _, err = _init.Call(ctx, api.EncodeI32(sch)) + return err + } + + _getInputSignalSize := instance.ExportedFunction("getInputSignalSize") + wCtx.getInputSignalSize = func(ctx context.Context, + hMSB, hLSB int32) (int32, error) { + + res, err2 := _getInputSignalSize.Call(ctx, + api.EncodeI32(hMSB), api.EncodeI32(hLSB)) + if err2 != nil { + return 0, err2 + } + return api.DecodeI32(res[0]), nil + } + + _writeSharedRWMemory := instance.ExportedFunction("writeSharedRWMemory") + wCtx.writeSharedRWMemory = func(ctx context.Context, + sigIdx, data int32) error { + + _, err2 := _writeSharedRWMemory.Call(ctx, + api.EncodeI32(sigIdx), api.EncodeI32(data)) + return err2 + } + + _setInputSignal := instance.ExportedFunction("setInputSignal") + wCtx.setInputSignal = func(ctx context.Context, hMSB, hLSB, i int32) error { + _, err2 := _setInputSignal.Call(ctx, + api.EncodeI32(hMSB), api.EncodeI32(hLSB), api.EncodeI32(i)) + return err2 + } + + _readSharedRWMemory := instance.ExportedFunction("readSharedRWMemory") + wCtx.readSharedRWMemory = func(ctx context.Context, + i int32) (int32, error) { + + res, err2 := _readSharedRWMemory.Call(ctx, api.EncodeI32(i)) + if err2 != nil { + return 0, err2 + } + return api.DecodeI32(res[0]), nil + } + + _getWitness := instance.ExportedFunction("getWitness") + wCtx.getWitness = func(ctx context.Context, i int32) error { + _, err2 := _getWitness.Call(ctx, api.EncodeI32(i)) + return err2 + } + + return wCtx, nil +} + +func flatSlice2(arr []*big.Int, v any) ([]*big.Int, error) { + switch vt := v.(type) { + case string: + i, ok := new(big.Int).SetString(vt, 10) + if !ok { + return nil, fmt.Errorf("can't parse string as int: %v", vt) + } + i.Rem(i, constants.Q) + return append(arr, i), nil + case *big.Int: + i := new(big.Int).Set(vt) + i.Rem(i, constants.Q) + return append(arr, i), nil + case []any: + for _, e := range vt { + var err error + arr, err = flatSlice2(arr, e) + if err != nil { + return nil, err + } + } + return arr, nil + default: + return nil, fmt.Errorf("invalid type: %T", v) + } +} + +func encodeInt(i *big.Int, ln int) []int32 { + i = new(big.Int).Set(i) + arr := make([]int32, 0, ln) + radix := big.NewInt(int64(math.MaxUint32) + 1) + for j := 0; j < ln; j++ { + arr = append(arr, int32(new(big.Int).Rem(i, radix).Int64())) + i.Div(i, radix) + } + reverse(arr) + return arr +} + +func reverse[T any](a []T) { + for i := 0; i < len(a)/2; i++ { + j := len(a) - i - 1 + a[i], a[j] = a[j], a[i] + } +} + +type ctxCloser interface { + Close(ctx context.Context) error +} + +func closeWithErrOrLog(ctx context.Context, c ctxCloser, err *error) { + err2 := c.Close(ctx) + if err2 != nil { + if *err == nil { + *err = err2 + } else { + log.Printf("error closing instance: %v", err2) + } + } + +} + +type witnessCtxState struct { + errStrs []string + msgStrs []string + errorCode int32 + errs []error +} + +func (s *witnessCtxState) errMessage() string { + switch s.errorCode { + case 0: + return "OK" + case 1: + return "Signal not found." + case 2: + return "Too many signals set." + case 3: + return "Signal already set." + case 4: + return "Assert Failed." + case 5: + return "Not enough memory." + case 6: + return "Input signal array access exceeds the size." + default: + return "Unknown error." + } +} + +func (s *witnessCtxState) err() error { + if len(s.errs) == 0 && s.errorCode == 0 { + return nil + } + + var errLines []string + errLines = append(errLines, + fmt.Sprintf("error code: %v: %v", s.errorCode, s.errMessage())) + errLines = append(errLines, s.errStrs...) + for i := range s.errs { + errLines = append(errLines, + fmt.Sprintf("Err #%v", i), + s.errs[i].Error()) + } + return errors.New(strings.Join(errLines, "\n")) +} + +type wtnsCtxKey string + +func withWtnsCtx(ctx context.Context, + wCtxState *witnessCtxState) context.Context { + + return context.WithValue(ctx, wtnsCtxKey("wtnsCtx"), wCtxState) +} + +func fromWtnsCtx(ctx context.Context) *witnessCtxState { + v := ctx.Value(wtnsCtxKey("wtnsCtx")) + if v == nil { + return nil + } + return v.(*witnessCtxState) +} + +func getMessage(ctx context.Context, m api.Module) (string, error) { + var buf bytes.Buffer + max := 4048 + for { + data, err := m.ExportedFunction("getMessageChar").Call(ctx) + if err != nil { + return "", err + } + b := byte(api.DecodeI32(data[0])) + if b == 0 { + return buf.String(), nil + } + buf.WriteByte(b) + + max-- + if max == 0 { + return "", errors.New("max iterations reached") + } + } +} + +func exceptionHandler(ctx context.Context, params []uint64) { + wtnsCtx := fromWtnsCtx(ctx) + wtnsCtx.errorCode = api.DecodeI32(params[0]) +} + +func printErrorMessage(ctx context.Context, m api.Module, _ []uint64) { + wtnsCtx := fromWtnsCtx(ctx) + + msg, err := getMessage(ctx, m) + if err != nil { + wtnsCtx.errs = append(wtnsCtx.errs, err) + return + } + + wtnsCtx.errStrs = append(wtnsCtx.errStrs, msg) +} + +func writeBufferMessage(ctx context.Context, m api.Module, _ []uint64) { + wtnsCtx := fromWtnsCtx(ctx) + + msg, err := getMessage(ctx, m) + if err != nil { + wtnsCtx.errs = append(wtnsCtx.errs, err) + return + } + + if msg == "\n" { + log.Print(strings.Join(wtnsCtx.msgStrs, " ")) + wtnsCtx.msgStrs = wtnsCtx.msgStrs[:0] + } else { + wtnsCtx.msgStrs = append(wtnsCtx.msgStrs, msg) + } +} + +func showSharedRWMemory(ctx context.Context, m api.Module, _ []uint64) { + printSharedRWMemory(ctx, m) +} + +func printSharedRWMemory(ctx context.Context, m api.Module) { + wtnsCtx := fromWtnsCtx(ctx) + + data, err := m.ExportedFunction("getFieldNumLen32").Call(ctx) + if err != nil { + wtnsCtx.errs = append(wtnsCtx.errs, err) + return + } + + sharedRwMemorySize := int(api.DecodeI32(data[0])) + var arr = make([]uint32, sharedRwMemorySize) + + for j := 0; j < sharedRwMemorySize; j++ { + data, err = m.ExportedFunction("readSharedRWMemory"). + Call(ctx, uint64(j)) + if err != nil { + wtnsCtx.errs = append(wtnsCtx.errs, err) + return + } + arr[j] = uint32(api.DecodeI32(data[0])) + } + + wtnsCtx.msgStrs = append(wtnsCtx.msgStrs, fromArray32(arr).Text(10)) +} diff --git a/witness/circom2witnesscalc_wazero_test.go b/witness/circom2witnesscalc_wazero_test.go new file mode 100644 index 0000000..8f35196 --- /dev/null +++ b/witness/circom2witnesscalc_wazero_test.go @@ -0,0 +1,189 @@ +package witness + +import ( + "crypto/md5" + "encoding/hex" + "math/big" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestWZCircom2CalculateWitness(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + witness, err := calc.CalculateWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witness) + require.Equal(t, "c1780821352c069392e9d0fab4330531", hashInts(witness)) +} + +func TestWZCircom2CalculateBinWitness(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + witnessBytes, err := calc.CalculateBinWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witnessBytes) + require.Equal(t, "d2c0486d7fd6f0715d04d535765f028b", + hashBytes(witnessBytes)) +} + +func TestWZCircom2CalculateWTNSBin(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, wtnsBytes) + require.Equal(t, "1709fbda942dabed641044f39b466e94", + hashBytes(wtnsBytes)) + +} + +// TestWZCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 +func TestWZCircom2CalculateWitness210(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + witness, err := calc.CalculateWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witness) + require.Equal(t, "c0a2b43f5a333310c2bb8d357db46d3b", hashInts(witness)) +} + +func hashInts(in []*big.Int) string { + h := md5.New() + for _, i := range in { + h.Write(i.Bytes()) + } + return hex.EncodeToString(h.Sum(nil)) +} + +func hashBytes(in []byte) string { + h := md5.New() + n, err := h.Write(in) + if err != nil { + panic(err) + } + if n != len(in) { + panic("incorrect size") + } + return hex.EncodeToString(h.Sum(nil)) +} + +// TestWZCircom2CalculateBinWitness210 tests the calculation of the witness +// for the circom 2.1.0 +func TestWZCircom2CalculateBinWitness210(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + witnessBytes, err := calc.CalculateBinWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witnessBytes) + require.Equal(t, "2b38b66035d8e923eacc028ea0f1dad2", + hashBytes(witnessBytes)) +} + +// TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness +// for the circom 2.1.0 +func TestWZCircom2CalculateWTNSBin210(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, wtnsBytes) + require.Equal(t, "75c5682a7195c20868b59d6580852fce", + hashBytes(wtnsBytes)) +} + +// TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness +// for the circom 2.1.0 +func TestWZCircom2CalculateWTNSBin210_Error(t *testing.T) { + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + require.NoError(t, err) + + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + require.NoError(t, err) + + calc, err := NewCircom2WZWitnessCalculator(wasmBytes) + require.NoError(t, err) + require.NotEmpty(t, calc) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + wrongSmtRoot, ok := big.NewInt(0).SetString( + "23891407091237035626910338386637210028103224489833886255774452947213913989795", + 10) + require.True(t, ok) + inputs["globalSmtRoot"] = wrongSmtRoot + + _, err = calc.CalculateWTNSBin(inputs, true) + require.EqualError(t, err, `error code: 4: Assert Failed. +Error in template ForceEqualIfEnabled_234 line: 56 +Error in template SMTVerifier_235 line: 134 +Error in template AuthV2_347 line: 93`) +} diff --git a/witness/go.mod b/witness/go.mod index 65a8443..7000f12 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -3,12 +3,14 @@ module github.com/iden3/go-rapidsnark/witness go 1.18 require ( + github.com/iden3/go-iden3-crypto v0.0.14 github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.2 + github.com/tetratelabs/wazero v1.0.1 ) require ( - github.com/davecgh/go-spew v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/witness/go.sum b/witness/go.sum index c0e8683..38ad383 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -1,13 +1,23 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/iden3/go-iden3-crypto v0.0.14 h1:HQnFchY735JRNQxof6n/Vbyon4owj4+Ku+LNAamWV6c= +github.com/iden3/go-iden3-crypto v0.0.14/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47 h1:KW0syFZ7yPr6NRq6Gmun4eHLg4SYp9jmFICPtipvt1A= github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tetratelabs/wazero v1.0.1 h1:xyWBoGyMjYekG3mEQ/W7xm9E05S89kJ/at696d/9yuc= +github.com/tetratelabs/wazero v1.0.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/test_files/circom2_1_0/input.json b/witness/test_files/circom2_1_0/input.json index b2f3cf0..da9e194 100644 --- a/witness/test_files/circom2_1_0/input.json +++ b/witness/test_files/circom2_1_0/input.json @@ -20,4 +20,4 @@ "globalSmtMtpAuxHi": "321655963459726004040127369337727353299407142334036950741528344494565949440", "globalSmtMtpAuxHv": "1257746809182882563786560928809910818663538703587513060503018952434273712929", "globalSmtMtpNoAux": "0" -} \ No newline at end of file +} From 1eb454a1211adc441a992cec1be608d7cdff08c8 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Mon, 17 Apr 2023 04:51:22 -0400 Subject: [PATCH 02/24] fix lint errors --- witness/circom2witnesscalc.go | 6 +++- witness/circom2witnesscalc_test.go | 2 -- witness/circom2witnesscalc_wazero.go | 3 +- witness/circom2witnesscalc_wazero_test.go | 40 +++++++++++------------ witness/utils.go | 9 ----- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/witness/circom2witnesscalc.go b/witness/circom2witnesscalc.go index b49d09d..683447f 100644 --- a/witness/circom2witnesscalc.go +++ b/witness/circom2witnesscalc.go @@ -399,8 +399,12 @@ func (wc *Circom2WitnessCalculator) doCalculateWitness(inputs map[string]interfa } } inputSize, err := wc.getInputSize() + if err != nil { + return err + } if inputCounter < int(inputSize.(int32)) { - return fmt.Errorf("not all inputs have been set: only %d out of %d", inputCounter, inputSize) + return fmt.Errorf("not all inputs have been set: only %d out of %d", + inputCounter, inputSize) } return nil } diff --git a/witness/circom2witnesscalc_test.go b/witness/circom2witnesscalc_test.go index 9ec356c..c99de22 100644 --- a/witness/circom2witnesscalc_test.go +++ b/witness/circom2witnesscalc_test.go @@ -7,8 +7,6 @@ import ( "github.com/stretchr/testify/require" ) -const defaultFileMode = 0644 - func TestCircom2CalculateWitness(t *testing.T) { wasmBytes, err := ioutil.ReadFile("test_files/circom2/circuit.wasm") require.NoError(t, err) diff --git a/witness/circom2witnesscalc_wazero.go b/witness/circom2witnesscalc_wazero.go index 79a2484..6c0dd55 100644 --- a/witness/circom2witnesscalc_wazero.go +++ b/witness/circom2witnesscalc_wazero.go @@ -241,8 +241,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interfa _ = binary.Write(buff, binary.LittleEndian, uint32(n8)) //prime number - getRawPrime := instance.ExportedFunction("getRawPrime") - wResult, err = getRawPrime.Call(ctx) + _, err = instance.ExportedFunction("getRawPrime").Call(ctx) if err != nil { return nil, err } diff --git a/witness/circom2witnesscalc_wazero_test.go b/witness/circom2witnesscalc_wazero_test.go index 8f35196..46bb8be 100644 --- a/witness/circom2witnesscalc_wazero_test.go +++ b/witness/circom2witnesscalc_wazero_test.go @@ -94,26 +94,6 @@ func TestWZCircom2CalculateWitness210(t *testing.T) { require.Equal(t, "c0a2b43f5a333310c2bb8d357db46d3b", hashInts(witness)) } -func hashInts(in []*big.Int) string { - h := md5.New() - for _, i := range in { - h.Write(i.Bytes()) - } - return hex.EncodeToString(h.Sum(nil)) -} - -func hashBytes(in []byte) string { - h := md5.New() - n, err := h.Write(in) - if err != nil { - panic(err) - } - if n != len(in) { - panic("incorrect size") - } - return hex.EncodeToString(h.Sum(nil)) -} - // TestWZCircom2CalculateBinWitness210 tests the calculation of the witness // for the circom 2.1.0 func TestWZCircom2CalculateBinWitness210(t *testing.T) { @@ -187,3 +167,23 @@ Error in template ForceEqualIfEnabled_234 line: 56 Error in template SMTVerifier_235 line: 134 Error in template AuthV2_347 line: 93`) } + +func hashInts(in []*big.Int) string { + h := md5.New() + for _, i := range in { + h.Write(i.Bytes()) + } + return hex.EncodeToString(h.Sum(nil)) +} + +func hashBytes(in []byte) string { + h := md5.New() + n, err := h.Write(in) + if err != nil { + panic(err) + } + if n != len(in) { + panic("incorrect size") + } + return hex.EncodeToString(h.Sum(nil)) +} diff --git a/witness/utils.go b/witness/utils.go index 365610d..b156dce 100644 --- a/witness/utils.go +++ b/witness/utils.go @@ -8,15 +8,6 @@ import ( "reflect" ) -// swap the order of the bytes in a slice. This allows flipping the endianness. -func swap(b []byte) []byte { - bs := make([]byte, len(b)) - for i := 0; i < len(b); i++ { - bs[len(b)-1-i] = b[i] - } - return bs -} - // parseInput is a recurisve helper function for ParseInputs func parseInput(v interface{}) (interface{}, error) { rv := reflect.ValueOf(v) From ee095033c5d8b8472861ec94ccf4c6f9804328c7 Mon Sep 17 00:00:00 2001 From: Oleksandr Brezhniev Date: Tue, 25 Apr 2023 23:43:42 +0100 Subject: [PATCH 03/24] Update wazero to v1.0.3 --- witness/go.mod | 2 +- witness/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/witness/go.mod b/witness/go.mod index 7000f12..7c85d4f 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -6,7 +6,7 @@ require ( github.com/iden3/go-iden3-crypto v0.0.14 github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47 github.com/stretchr/testify v1.8.2 - github.com/tetratelabs/wazero v1.0.1 + github.com/tetratelabs/wazero v1.0.3 ) require ( diff --git a/witness/go.sum b/witness/go.sum index 38ad383..3b9be5d 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -14,8 +14,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tetratelabs/wazero v1.0.1 h1:xyWBoGyMjYekG3mEQ/W7xm9E05S89kJ/at696d/9yuc= -github.com/tetratelabs/wazero v1.0.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/tetratelabs/wazero v1.0.3 h1:IWmaxc/5vKg71DE+c0SLjjLFAA3u3tD/Zegpgif2Wpo= +github.com/tetratelabs/wazero v1.0.3/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 066c8514c375076e4501ce2ad1cf2b05bde2af37 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 27 Apr 2023 06:51:53 -0400 Subject: [PATCH 04/24] Removed unused constructor parameter sanityCheck from NewCircom2WitnessCalculator --- witness/circom2witnesscalc.go | 6 ++--- witness/circom2witnesscalc_test.go | 38 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/witness/circom2witnesscalc.go b/witness/circom2witnesscalc.go index 683447f..40b7f35 100644 --- a/witness/circom2witnesscalc.go +++ b/witness/circom2witnesscalc.go @@ -17,7 +17,6 @@ type Circom2WitnessCalculator struct { module *wasmer.Module instance *wasmer.Instance store *wasmer.Store - sanityCheck bool n32 int32 version int32 witnessSize int32 @@ -40,9 +39,10 @@ type Circom2WitnessCalculator struct { // NewCircom2WitnessCalculator creates a new WitnessCalculator from the WitnessCalc // loaded WASM module in the runtime. -func NewCircom2WitnessCalculator(wasmBytes []byte, sanityCheck bool) (*Circom2WitnessCalculator, error) { +func NewCircom2WitnessCalculator( + wasmBytes []byte) (*Circom2WitnessCalculator, error) { + wc := Circom2WitnessCalculator{} - wc.sanityCheck = sanityCheck wc.engine = wasmer.NewEngine() wc.store = wasmer.NewStore(wc.engine) diff --git a/witness/circom2witnesscalc_test.go b/witness/circom2witnesscalc_test.go index c99de22..9a828cb 100644 --- a/witness/circom2witnesscalc_test.go +++ b/witness/circom2witnesscalc_test.go @@ -1,20 +1,20 @@ package witness import ( - "io/ioutil" + "os" "testing" "github.com/stretchr/testify/require" ) func TestCircom2CalculateWitness(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("test_files/circom2/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) @@ -27,13 +27,13 @@ func TestCircom2CalculateWitness(t *testing.T) { } func TestCircom2CalculateBinWitness(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("test_files/circom2/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) @@ -46,13 +46,13 @@ func TestCircom2CalculateBinWitness(t *testing.T) { } func TestCircom2CalculateWTNSBin(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("test_files/circom2/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) @@ -68,13 +68,13 @@ func TestCircom2CalculateWTNSBin(t *testing.T) { // TestCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateWitness210(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) @@ -88,13 +88,13 @@ func TestCircom2CalculateWitness210(t *testing.T) { // TestCircom2CalculateBinWitness210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateBinWitness210(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) @@ -108,13 +108,13 @@ func TestCircom2CalculateBinWitness210(t *testing.T) { // TestCircom2CalculateWTNSBin210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateWTNSBin210(t *testing.T) { - wasmBytes, err := ioutil.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := ioutil.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") require.NoError(t, err) - calc, err := NewCircom2WitnessCalculator(wasmBytes, true) + calc, err := NewCircom2WitnessCalculator(wasmBytes) require.NoError(t, err) require.NotEmpty(t, calc) From 1c6b8e72d6b04c7a634ac48390d2c14640656798 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 27 Apr 2023 06:53:50 -0400 Subject: [PATCH 05/24] Rename test_files directory to testdata. It's more goish. --- witness/circom2witnesscalc_test.go | 28 +++++++++--------- witness/circom2witnesscalc_wazero_test.go | 28 +++++++++--------- .../circom2/circuit.wasm | Bin .../circom2/input.json | 0 .../circom2_1_0/circuit.wasm | Bin .../circom2_1_0/input.json | 0 6 files changed, 28 insertions(+), 28 deletions(-) rename witness/{test_files => testdata}/circom2/circuit.wasm (100%) rename witness/{test_files => testdata}/circom2/input.json (100%) rename witness/{test_files => testdata}/circom2_1_0/circuit.wasm (100%) rename witness/{test_files => testdata}/circom2_1_0/input.json (100%) diff --git a/witness/circom2witnesscalc_test.go b/witness/circom2witnesscalc_test.go index 9a828cb..d6bafc8 100644 --- a/witness/circom2witnesscalc_test.go +++ b/witness/circom2witnesscalc_test.go @@ -8,10 +8,10 @@ import ( ) func TestCircom2CalculateWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -27,10 +27,10 @@ func TestCircom2CalculateWitness(t *testing.T) { } func TestCircom2CalculateBinWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -46,10 +46,10 @@ func TestCircom2CalculateBinWitness(t *testing.T) { } func TestCircom2CalculateWTNSBin(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -63,15 +63,15 @@ func TestCircom2CalculateWTNSBin(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, wtnsBytes) - //_ = ioutil.WriteFile("test_files/circom2/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) + //_ = ioutil.WriteFile("testdata/circom2/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) } // TestCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -88,10 +88,10 @@ func TestCircom2CalculateWitness210(t *testing.T) { // TestCircom2CalculateBinWitness210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateBinWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -108,10 +108,10 @@ func TestCircom2CalculateBinWitness210(t *testing.T) { // TestCircom2CalculateWTNSBin210 tests the calculation of the witness for the circom 2.1.0 func TestCircom2CalculateWTNSBin210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WitnessCalculator(wasmBytes) @@ -125,5 +125,5 @@ func TestCircom2CalculateWTNSBin210(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, wtnsBytes) - //_ = ioutil.WriteFile("test_files/circom2_1_0/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) + //_ = ioutil.WriteFile("testdata/circom2_1_0/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) } diff --git a/witness/circom2witnesscalc_wazero_test.go b/witness/circom2witnesscalc_wazero_test.go index 46bb8be..a68eb7c 100644 --- a/witness/circom2witnesscalc_wazero_test.go +++ b/witness/circom2witnesscalc_wazero_test.go @@ -11,10 +11,10 @@ import ( ) func TestWZCircom2CalculateWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -31,10 +31,10 @@ func TestWZCircom2CalculateWitness(t *testing.T) { } func TestWZCircom2CalculateBinWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -52,10 +52,10 @@ func TestWZCircom2CalculateBinWitness(t *testing.T) { } func TestWZCircom2CalculateWTNSBin(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2/input.json") + inputBytes, err := os.ReadFile("testdata/circom2/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -75,10 +75,10 @@ func TestWZCircom2CalculateWTNSBin(t *testing.T) { // TestWZCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 func TestWZCircom2CalculateWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -97,10 +97,10 @@ func TestWZCircom2CalculateWitness210(t *testing.T) { // TestWZCircom2CalculateBinWitness210 tests the calculation of the witness // for the circom 2.1.0 func TestWZCircom2CalculateBinWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -120,10 +120,10 @@ func TestWZCircom2CalculateBinWitness210(t *testing.T) { // TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness // for the circom 2.1.0 func TestWZCircom2CalculateWTNSBin210(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) @@ -143,10 +143,10 @@ func TestWZCircom2CalculateWTNSBin210(t *testing.T) { // TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness // for the circom 2.1.0 func TestWZCircom2CalculateWTNSBin210_Error(t *testing.T) { - wasmBytes, err := os.ReadFile("test_files/circom2_1_0/circuit.wasm") + wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") require.NoError(t, err) - inputBytes, err := os.ReadFile("test_files/circom2_1_0/input.json") + inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") require.NoError(t, err) calc, err := NewCircom2WZWitnessCalculator(wasmBytes) diff --git a/witness/test_files/circom2/circuit.wasm b/witness/testdata/circom2/circuit.wasm similarity index 100% rename from witness/test_files/circom2/circuit.wasm rename to witness/testdata/circom2/circuit.wasm diff --git a/witness/test_files/circom2/input.json b/witness/testdata/circom2/input.json similarity index 100% rename from witness/test_files/circom2/input.json rename to witness/testdata/circom2/input.json diff --git a/witness/test_files/circom2_1_0/circuit.wasm b/witness/testdata/circom2_1_0/circuit.wasm similarity index 100% rename from witness/test_files/circom2_1_0/circuit.wasm rename to witness/testdata/circom2_1_0/circuit.wasm diff --git a/witness/test_files/circom2_1_0/input.json b/witness/testdata/circom2_1_0/input.json similarity index 100% rename from witness/test_files/circom2_1_0/input.json rename to witness/testdata/circom2_1_0/input.json From 1f2c2b6f614502f7253542428a61e7cb6978ca49 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 27 Apr 2023 08:46:05 -0400 Subject: [PATCH 06/24] Make witness calculator pluggable with wasm engine --- witness/circom2witnesscalc.go | 2 +- witness/circom2witnesscalc_wazero.go | 13 ++-- witness/witness.go | 35 ++++++++++ witness/witness_test.go | 99 ++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 witness/witness.go create mode 100644 witness/witness_test.go diff --git a/witness/circom2witnesscalc.go b/witness/circom2witnesscalc.go index 40b7f35..1c972d4 100644 --- a/witness/circom2witnesscalc.go +++ b/witness/circom2witnesscalc.go @@ -40,7 +40,7 @@ type Circom2WitnessCalculator struct { // NewCircom2WitnessCalculator creates a new WitnessCalculator from the WitnessCalc // loaded WASM module in the runtime. func NewCircom2WitnessCalculator( - wasmBytes []byte) (*Circom2WitnessCalculator, error) { + wasmBytes []byte) (WitnessCalculator, error) { wc := Circom2WitnessCalculator{} diff --git a/witness/circom2witnesscalc_wazero.go b/witness/circom2witnesscalc_wazero.go index 6c0dd55..6d1e7b8 100644 --- a/witness/circom2witnesscalc_wazero.go +++ b/witness/circom2witnesscalc_wazero.go @@ -23,7 +23,7 @@ type Circom2WZWitnessCalculator struct { } func NewCircom2WZWitnessCalculator( - wasmBytes []byte) (*Circom2WZWitnessCalculator, error) { + wasmBytes []byte) (WitnessCalculator, error) { runtime := wazero.NewRuntime(context.Background()) @@ -105,7 +105,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWitness(inputs map[string]interfa return nil, err } - err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) if err != nil { return nil, err } @@ -154,7 +154,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateBinWitness(inputs map[string]inte return nil, err } - err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) if err != nil { return nil, err } @@ -201,7 +201,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interfa return nil, err } - err = wc.doCalculateWitness(ctx, instance, wCtx, inputs, sanityCheck) + err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) if err != nil { return nil, err } @@ -285,10 +285,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interfa } func (w *Circom2WZWitnessCalculator) doCalculateWitness(ctx context.Context, - instance api.Module, - wCtx witnessCtx, - inputs map[string]any, - sanityCheck bool) (err error) { + wCtx witnessCtx, inputs map[string]any, sanityCheck bool) (err error) { if err = wCtx.init(ctx, sanityCheck); err != nil { return err diff --git a/witness/witness.go b/witness/witness.go new file mode 100644 index 0000000..95b3365 --- /dev/null +++ b/witness/witness.go @@ -0,0 +1,35 @@ +package witness + +import "math/big" + +type Option func(cfg *calcConfig) + +func WithWasmEngine(calculator func([]byte) (WitnessCalculator, error)) Option { + return func(cfg *calcConfig) { + cfg.wasmEngine = calculator + } +} + +type WitnessCalculator interface { + CalculateWitness(inputs map[string]interface{}, + sanityCheck bool) ([]*big.Int, error) + CalculateBinWitness(inputs map[string]interface{}, + sanityCheck bool) ([]byte, error) + CalculateWTNSBin(inputs map[string]interface{}, + sanityCheck bool) ([]byte, error) +} + +type calcConfig struct { + wasmEngine func([]byte) (WitnessCalculator, error) +} + +func NewCalc(wasm []byte, ops ...Option) (WitnessCalculator, error) { + var config calcConfig + for _, op := range ops { + op(&config) + } + if config.wasmEngine == nil { + config.wasmEngine = NewCircom2WZWitnessCalculator + } + return config.wasmEngine(wasm) +} diff --git a/witness/witness_test.go b/witness/witness_test.go new file mode 100644 index 0000000..684a364 --- /dev/null +++ b/witness/witness_test.go @@ -0,0 +1,99 @@ +package witness + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEngines(t *testing.T) { + engineTestCases := []struct { + title string + engine func([]byte) (WitnessCalculator, error) + }{ + { + title: "Wazero", + engine: NewCircom2WZWitnessCalculator, + }, + { + title: "Wasmer", + engine: NewCircom2WitnessCalculator, + }, + { + title: "empty", + engine: nil, + }, + } + + circomTestCases := []struct { + wasmFile string + inputs string + wantWtnsHex string + wantBinWtnsHex string + wantWTNSBinHex string + }{ + { + wasmFile: "testdata/circom2/circuit.wasm", + inputs: "testdata/circom2/input.json", + wantWtnsHex: "c1780821352c069392e9d0fab4330531", + wantBinWtnsHex: "d2c0486d7fd6f0715d04d535765f028b", + wantWTNSBinHex: "1709fbda942dabed641044f39b466e94", + }, + { + wasmFile: "testdata/circom2_1_0/circuit.wasm", + inputs: "testdata/circom2_1_0/input.json", + wantWtnsHex: "c0a2b43f5a333310c2bb8d357db46d3b", + wantBinWtnsHex: "2b38b66035d8e923eacc028ea0f1dad2", + wantWTNSBinHex: "75c5682a7195c20868b59d6580852fce", + }, + } + + for i := range engineTestCases { + engTC := engineTestCases[i] + t.Run(engTC.title, func(t *testing.T) { + for _, circomTC := range circomTestCases { + t.Run(circomTC.wasmFile, func(t *testing.T) { + wasmBytes, err := os.ReadFile(circomTC.wasmFile) + require.NoError(t, err) + inputBytes, err := os.ReadFile(circomTC.inputs) + require.NoError(t, err) + + var ops []Option + if engTC.engine != nil { + ops = append(ops, WithWasmEngine(engTC.engine)) + } + calc, err := NewCalc(wasmBytes, ops...) + require.NoError(t, err) + + inputs, err := ParseInputs(inputBytes) + require.NoError(t, err) + + t.Run("CalculateWitness", func(t *testing.T) { + witness, err := calc.CalculateWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witness) + require.Equal(t, circomTC.wantWtnsHex, + hashInts(witness)) + }) + + t.Run("CalculateBinWitness", func(t *testing.T) { + witness, err := calc.CalculateBinWitness(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witness) + require.Equal(t, circomTC.wantBinWtnsHex, + hashBytes(witness)) + }) + + t.Run("CalculateWTNSBin", func(t *testing.T) { + witness, err := calc.CalculateWTNSBin(inputs, true) + require.NoError(t, err) + require.NotEmpty(t, witness) + require.Equal(t, circomTC.wantWTNSBinHex, + hashBytes(witness)) + }) + }) + } + }) + } +} From b0b9377989897d3f22d47733575a9f076eb6ae3d Mon Sep 17 00:00:00 2001 From: Oleksandr Brezhniev Date: Fri, 28 Apr 2023 11:39:00 +0100 Subject: [PATCH 07/24] Merge fixes --- witness/go.sum | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/witness/go.sum b/witness/go.sum index 3b9be5d..29a523d 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -1,10 +1,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/iden3/go-iden3-crypto v0.0.14 h1:HQnFchY735JRNQxof6n/Vbyon4owj4+Ku+LNAamWV6c= -github.com/iden3/go-iden3-crypto v0.0.14/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47 h1:KW0syFZ7yPr6NRq6Gmun4eHLg4SYp9jmFICPtipvt1A= -github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= +github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= +github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= +github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From dc1c5bdd683a355bb3d08c62dca691a4bb5bd36a Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Wed, 3 May 2023 01:37:13 -0400 Subject: [PATCH 08/24] Upgrade wazero dependency to v1.1.0 --- witness/go.mod | 2 +- witness/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/witness/go.mod b/witness/go.mod index 7000f12..9f0de78 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -6,7 +6,7 @@ require ( github.com/iden3/go-iden3-crypto v0.0.14 github.com/iden3/wasmer-go v0.0.0-20230217163329-62d85068ec47 github.com/stretchr/testify v1.8.2 - github.com/tetratelabs/wazero v1.0.1 + github.com/tetratelabs/wazero v1.1.0 ) require ( diff --git a/witness/go.sum b/witness/go.sum index 38ad383..c4d5710 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -14,8 +14,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tetratelabs/wazero v1.0.1 h1:xyWBoGyMjYekG3mEQ/W7xm9E05S89kJ/at696d/9yuc= -github.com/tetratelabs/wazero v1.0.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= +github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d1cc6a82a58ef49d8ad645a6e2447f5da8a935d6 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Wed, 3 May 2023 01:37:13 -0400 Subject: [PATCH 09/24] Upgrade wazero dependency to v1.1.0 --- witness/go.mod | 2 +- witness/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/witness/go.mod b/witness/go.mod index 3a6557e..f0d4ebf 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -6,7 +6,7 @@ require ( github.com/iden3/go-iden3-crypto v0.0.15 github.com/iden3/wasmer-go v0.0.1 github.com/stretchr/testify v1.8.2 - github.com/tetratelabs/wazero v1.0.3 + github.com/tetratelabs/wazero v1.1.0 ) require ( diff --git a/witness/go.sum b/witness/go.sum index 29a523d..3097dab 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -14,8 +14,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tetratelabs/wazero v1.0.3 h1:IWmaxc/5vKg71DE+c0SLjjLFAA3u3tD/Zegpgif2Wpo= -github.com/tetratelabs/wazero v1.0.3/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= +github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 9be75d1a304c49a17bd6de4ee22cfad587fe4290 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 18 May 2023 13:47:18 -0400 Subject: [PATCH 10/24] Put different wasm implementations into different modules --- witness/circom2witnesscalc_test.go | 129 ------------ witness/circom2witnesscalc_wazero_test.go | 189 ------------------ witness/go.mod | 7 +- witness/go.sum | 6 - witness/test_wasm_impls/go.mod | 26 +++ witness/test_wasm_impls/go.sum | 23 +++ .../testdata/circom2/circuit.wasm | Bin .../testdata/circom2/input.json | 0 .../testdata/circom2_1_0/circuit.wasm | Bin .../testdata/circom2_1_0/input.json | 0 witness/test_wasm_impls/witness_test.go | 140 +++++++++++++ witness/utils.go | 17 +- witness/{ => wasmer}/circom2witnesscalc.go | 35 +++- witness/wasmer/go.mod | 7 + witness/wasmer/go.sum | 18 ++ .../{ => wazero}/circom2witnesscalc_wazero.go | 37 +++- witness/wazero/go.mod | 8 + witness/wazero/go.sum | 4 + witness/witness.go | 7 +- witness/witness_test.go | 99 --------- 20 files changed, 297 insertions(+), 455 deletions(-) delete mode 100644 witness/circom2witnesscalc_test.go delete mode 100644 witness/circom2witnesscalc_wazero_test.go create mode 100644 witness/test_wasm_impls/go.mod create mode 100644 witness/test_wasm_impls/go.sum rename witness/{ => test_wasm_impls}/testdata/circom2/circuit.wasm (100%) rename witness/{ => test_wasm_impls}/testdata/circom2/input.json (100%) rename witness/{ => test_wasm_impls}/testdata/circom2_1_0/circuit.wasm (100%) rename witness/{ => test_wasm_impls}/testdata/circom2_1_0/input.json (100%) create mode 100644 witness/test_wasm_impls/witness_test.go rename witness/{ => wasmer}/circom2witnesscalc.go (94%) create mode 100644 witness/wasmer/go.mod create mode 100644 witness/wasmer/go.sum rename witness/{ => wazero}/circom2witnesscalc_wazero.go (95%) create mode 100644 witness/wazero/go.mod create mode 100644 witness/wazero/go.sum delete mode 100644 witness/witness_test.go diff --git a/witness/circom2witnesscalc_test.go b/witness/circom2witnesscalc_test.go deleted file mode 100644 index e716c87..0000000 --- a/witness/circom2witnesscalc_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package witness - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCircom2CalculateWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witness, err := calc.CalculateWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) -} - -func TestCircom2CalculateBinWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witnessBytes, err := calc.CalculateBinWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witnessBytes) -} - -func TestCircom2CalculateWTNSBin(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, wtnsBytes) - - //_ = os.WriteFile("testdata/circom2/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) -} - -// TestCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 -func TestCircom2CalculateWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witness, err := calc.CalculateWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) -} - -// TestCircom2CalculateBinWitness210 tests the calculation of the witness for the circom 2.1.0 -func TestCircom2CalculateBinWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witnessBytes, err := calc.CalculateBinWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witnessBytes) -} - -// TestCircom2CalculateWTNSBin210 tests the calculation of the witness for the circom 2.1.0 -func TestCircom2CalculateWTNSBin210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, wtnsBytes) - - //_ = os.WriteFile("testdata/circom2_1_0/witness.wtns", wtnsBytes, fs.FileMode(defaultFileMode)) -} diff --git a/witness/circom2witnesscalc_wazero_test.go b/witness/circom2witnesscalc_wazero_test.go deleted file mode 100644 index a68eb7c..0000000 --- a/witness/circom2witnesscalc_wazero_test.go +++ /dev/null @@ -1,189 +0,0 @@ -package witness - -import ( - "crypto/md5" - "encoding/hex" - "math/big" - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestWZCircom2CalculateWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witness, err := calc.CalculateWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) - require.Equal(t, "c1780821352c069392e9d0fab4330531", hashInts(witness)) -} - -func TestWZCircom2CalculateBinWitness(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witnessBytes, err := calc.CalculateBinWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witnessBytes) - require.Equal(t, "d2c0486d7fd6f0715d04d535765f028b", - hashBytes(witnessBytes)) -} - -func TestWZCircom2CalculateWTNSBin(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, wtnsBytes) - require.Equal(t, "1709fbda942dabed641044f39b466e94", - hashBytes(wtnsBytes)) - -} - -// TestWZCircom2CalculateWitness210 tests the calculation of the witness for the circom 2.1.0 -func TestWZCircom2CalculateWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witness, err := calc.CalculateWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) - require.Equal(t, "c0a2b43f5a333310c2bb8d357db46d3b", hashInts(witness)) -} - -// TestWZCircom2CalculateBinWitness210 tests the calculation of the witness -// for the circom 2.1.0 -func TestWZCircom2CalculateBinWitness210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - witnessBytes, err := calc.CalculateBinWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witnessBytes) - require.Equal(t, "2b38b66035d8e923eacc028ea0f1dad2", - hashBytes(witnessBytes)) -} - -// TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness -// for the circom 2.1.0 -func TestWZCircom2CalculateWTNSBin210(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - wtnsBytes, err := calc.CalculateWTNSBin(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, wtnsBytes) - require.Equal(t, "75c5682a7195c20868b59d6580852fce", - hashBytes(wtnsBytes)) -} - -// TestWZCircom2CalculateWTNSBin210 tests the calculation of the witness -// for the circom 2.1.0 -func TestWZCircom2CalculateWTNSBin210_Error(t *testing.T) { - wasmBytes, err := os.ReadFile("testdata/circom2_1_0/circuit.wasm") - require.NoError(t, err) - - inputBytes, err := os.ReadFile("testdata/circom2_1_0/input.json") - require.NoError(t, err) - - calc, err := NewCircom2WZWitnessCalculator(wasmBytes) - require.NoError(t, err) - require.NotEmpty(t, calc) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - wrongSmtRoot, ok := big.NewInt(0).SetString( - "23891407091237035626910338386637210028103224489833886255774452947213913989795", - 10) - require.True(t, ok) - inputs["globalSmtRoot"] = wrongSmtRoot - - _, err = calc.CalculateWTNSBin(inputs, true) - require.EqualError(t, err, `error code: 4: Assert Failed. -Error in template ForceEqualIfEnabled_234 line: 56 -Error in template SMTVerifier_235 line: 134 -Error in template AuthV2_347 line: 93`) -} - -func hashInts(in []*big.Int) string { - h := md5.New() - for _, i := range in { - h.Write(i.Bytes()) - } - return hex.EncodeToString(h.Sum(nil)) -} - -func hashBytes(in []byte) string { - h := md5.New() - n, err := h.Write(in) - if err != nil { - panic(err) - } - if n != len(in) { - panic("incorrect size") - } - return hex.EncodeToString(h.Sum(nil)) -} diff --git a/witness/go.mod b/witness/go.mod index f0d4ebf..d48e08a 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -2,12 +2,7 @@ module github.com/iden3/go-rapidsnark/witness go 1.18 -require ( - github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/wasmer-go v0.0.1 - github.com/stretchr/testify v1.8.2 - github.com/tetratelabs/wazero v1.1.0 -) +require github.com/stretchr/testify v1.8.2 require ( github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/witness/go.sum b/witness/go.sum index 3097dab..6a56e69 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -1,10 +1,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= -github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= -github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -14,8 +10,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= -github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod new file mode 100644 index 0000000..35a8afd --- /dev/null +++ b/witness/test_wasm_impls/go.mod @@ -0,0 +1,26 @@ +module github.com/iden3/go-rapidsnark/witness/test-wasm-impls + +go 1.18 + +require ( + github.com/iden3/go-rapidsnark/witness v0.0.0 + github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 + github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 + github.com/stretchr/testify v1.8.2 + +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/iden3/go-iden3-crypto v0.0.15 // indirect + github.com/iden3/wasmer-go v0.0.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/tetratelabs/wazero v1.1.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace ( + github.com/iden3/go-rapidsnark/witness => ../ + github.com/iden3/go-rapidsnark/witness/wasmer => ../wasmer + github.com/iden3/go-rapidsnark/witness/wazero => ../wazero +) diff --git a/witness/test_wasm_impls/go.sum b/witness/test_wasm_impls/go.sum new file mode 100644 index 0000000..3097dab --- /dev/null +++ b/witness/test_wasm_impls/go.sum @@ -0,0 +1,23 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= +github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= +github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= +github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/testdata/circom2/circuit.wasm b/witness/test_wasm_impls/testdata/circom2/circuit.wasm similarity index 100% rename from witness/testdata/circom2/circuit.wasm rename to witness/test_wasm_impls/testdata/circom2/circuit.wasm diff --git a/witness/testdata/circom2/input.json b/witness/test_wasm_impls/testdata/circom2/input.json similarity index 100% rename from witness/testdata/circom2/input.json rename to witness/test_wasm_impls/testdata/circom2/input.json diff --git a/witness/testdata/circom2_1_0/circuit.wasm b/witness/test_wasm_impls/testdata/circom2_1_0/circuit.wasm similarity index 100% rename from witness/testdata/circom2_1_0/circuit.wasm rename to witness/test_wasm_impls/testdata/circom2_1_0/circuit.wasm diff --git a/witness/testdata/circom2_1_0/input.json b/witness/test_wasm_impls/testdata/circom2_1_0/input.json similarity index 100% rename from witness/testdata/circom2_1_0/input.json rename to witness/test_wasm_impls/testdata/circom2_1_0/input.json diff --git a/witness/test_wasm_impls/witness_test.go b/witness/test_wasm_impls/witness_test.go new file mode 100644 index 0000000..9e75914 --- /dev/null +++ b/witness/test_wasm_impls/witness_test.go @@ -0,0 +1,140 @@ +package witness + +import ( + "crypto/md5" + "encoding/hex" + "math/big" + "os" + "testing" + + "github.com/iden3/go-rapidsnark/witness" + "github.com/iden3/go-rapidsnark/witness/wasmer" + "github.com/iden3/go-rapidsnark/witness/wazero" + "github.com/stretchr/testify/require" +) + +func wasmerAdapter(code []byte) (witness.WitnessCalculator, error) { + wc, err := wasmer.NewCircom2WitnessCalculator(code) + return wc, err +} + +func wazeroAdapter(code []byte) (witness.WitnessCalculator, error) { + wc, err := wazero.NewCircom2WZWitnessCalculator(code) + return wc, err +} + +func TestEngines(t *testing.T) { + engineTestCases := []struct { + title string + engine func(code []byte) (witness.WitnessCalculator, error) + wantErr string + }{ + { + title: "Wazero", + engine: wazeroAdapter, + }, + { + title: "Wasmer", + engine: wasmerAdapter, + }, + { + title: "empty", + wantErr: "witness calculator wasm engine not set", + }, + } + + circomTestCases := []struct { + wasmFile string + inputs string + wantWtnsHex string + wantBinWtnsHex string + wantWTNSBinHex string + }{ + { + wasmFile: "testdata/circom2/circuit.wasm", + inputs: "testdata/circom2/input.json", + wantWtnsHex: "c1780821352c069392e9d0fab4330531", + wantBinWtnsHex: "d2c0486d7fd6f0715d04d535765f028b", + wantWTNSBinHex: "1709fbda942dabed641044f39b466e94", + }, + { + wasmFile: "testdata/circom2_1_0/circuit.wasm", + inputs: "testdata/circom2_1_0/input.json", + wantWtnsHex: "c0a2b43f5a333310c2bb8d357db46d3b", + wantBinWtnsHex: "2b38b66035d8e923eacc028ea0f1dad2", + wantWTNSBinHex: "75c5682a7195c20868b59d6580852fce", + }, + } + + for i := range engineTestCases { + engTC := engineTestCases[i] + t.Run(engTC.title, func(t *testing.T) { + for _, circomTC := range circomTestCases { + t.Run(circomTC.wasmFile, func(t *testing.T) { + wasmBytes, err := os.ReadFile(circomTC.wasmFile) + require.NoError(t, err) + inputBytes, err := os.ReadFile(circomTC.inputs) + require.NoError(t, err) + + var ops []witness.Option + if engTC.engine != nil { + ops = append(ops, witness.WithWasmEngine(engTC.engine)) + } + calc, err := witness.NewCalc(wasmBytes, ops...) + if engTC.wantErr != "" { + require.EqualError(t, err, engTC.wantErr) + return + } + + require.NoError(t, err) + + inputs, err := witness.ParseInputs(inputBytes) + require.NoError(t, err) + + t.Run("CalculateWitness", func(t *testing.T) { + wtns, err2 := calc.CalculateWitness(inputs, true) + require.NoError(t, err2) + require.NotEmpty(t, wtns) + require.Equal(t, circomTC.wantWtnsHex, hashInts(wtns)) + }) + + t.Run("CalculateBinWitness", func(t *testing.T) { + wtns, err2 := calc.CalculateBinWitness(inputs, true) + require.NoError(t, err2) + require.NotEmpty(t, wtns) + require.Equal(t, circomTC.wantBinWtnsHex, + hashBytes(wtns)) + }) + + t.Run("CalculateWTNSBin", func(t *testing.T) { + wtns, err2 := calc.CalculateWTNSBin(inputs, true) + require.NoError(t, err2) + require.NotEmpty(t, wtns) + require.Equal(t, circomTC.wantWTNSBinHex, + hashBytes(wtns)) + }) + }) + } + }) + } +} + +func hashInts(in []*big.Int) string { + h := md5.New() + for _, i := range in { + h.Write(i.Bytes()) + } + return hex.EncodeToString(h.Sum(nil)) +} + +func hashBytes(in []byte) string { + h := md5.New() + n, err := h.Write(in) + if err != nil { + panic(err) + } + if n != len(in) { + panic("incorrect size") + } + return hex.EncodeToString(h.Sum(nil)) +} diff --git a/witness/utils.go b/witness/utils.go index b156dce..b1eaf45 100644 --- a/witness/utils.go +++ b/witness/utils.go @@ -3,19 +3,18 @@ package witness import ( "encoding/json" "fmt" - "hash/fnv" "math/big" "reflect" ) -// parseInput is a recurisve helper function for ParseInputs +// parseInput is a recursive helper function for ParseInputs func parseInput(v interface{}) (interface{}, error) { rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.String: n, ok := new(big.Int).SetString(v.(string), 0) if !ok { - return nil, fmt.Errorf("Error parsing input %v", v) + return nil, fmt.Errorf("error parsing input %v", v) } return n, nil case reflect.Float64: @@ -26,12 +25,12 @@ func parseInput(v interface{}) (interface{}, error) { var err error res[i], err = parseInput(rv.Index(i).Interface()) if err != nil { - return nil, fmt.Errorf("Error parsing input %v: %w", v, err) + return nil, fmt.Errorf("error parsing input %v: %w", v, err) } } return res, nil default: - return nil, fmt.Errorf("Unexpected type for input %v: %T", v, v) + return nil, fmt.Errorf("unexpected type for input %v: %T", v, v) } } @@ -74,11 +73,3 @@ func flatSlice(v interface{}) []*big.Int { _flatSlice(&res, v) return res } - -// fnvHash returns the 64 bit FNV-1a hash split into two 32 bit values: (MSB, LSB) -func fnvHash(s string) (int32, int32) { - hash := fnv.New64a() - hash.Write([]byte(s)) - h := hash.Sum64() - return int32(h >> 32), int32(h & 0xffffffff) -} diff --git a/witness/circom2witnesscalc.go b/witness/wasmer/circom2witnesscalc.go similarity index 94% rename from witness/circom2witnesscalc.go rename to witness/wasmer/circom2witnesscalc.go index 1c972d4..5f39198 100644 --- a/witness/circom2witnesscalc.go +++ b/witness/wasmer/circom2witnesscalc.go @@ -1,11 +1,13 @@ -package witness +package wasmer import ( "bytes" "encoding/binary" "errors" "fmt" + "hash/fnv" "math/big" + "reflect" "github.com/iden3/wasmer-go/wasmer" ) @@ -40,7 +42,7 @@ type Circom2WitnessCalculator struct { // NewCircom2WitnessCalculator creates a new WitnessCalculator from the WitnessCalc // loaded WASM module in the runtime. func NewCircom2WitnessCalculator( - wasmBytes []byte) (WitnessCalculator, error) { + wasmBytes []byte) (*Circom2WitnessCalculator, error) { wc := Circom2WitnessCalculator{} @@ -584,3 +586,32 @@ func fromArray32(arr []uint32) *big.Int { } return res } + +// fnvHash returns the 64 bit FNV-1a hash split into two 32 bit values: (MSB, LSB) +func fnvHash(s string) (int32, int32) { + hash := fnv.New64a() + hash.Write([]byte(s)) + h := hash.Sum64() + return int32(h >> 32), int32(h & 0xffffffff) +} + +// _flatSlice is a recursive helper function for flatSlice. +func _flatSlice(acc *[]*big.Int, v interface{}) { + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Slice: + for i := 0; i < rv.Len(); i++ { + _flatSlice(acc, rv.Index(i).Interface()) + } + default: + *acc = append(*acc, v.(*big.Int)) + } +} + +// flatSlice takes a structure that contains a recursive combination of slices +// and *big.Int and flattens it into a single slice. +func flatSlice(v interface{}) []*big.Int { + res := make([]*big.Int, 0) + _flatSlice(&res, v) + return res +} diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod new file mode 100644 index 0000000..fb851ff --- /dev/null +++ b/witness/wasmer/go.mod @@ -0,0 +1,7 @@ +module github.com/iden3/go-rapidsnark/witness/wasmer + +go 1.18 + +require github.com/iden3/wasmer-go v0.0.1 + +require github.com/stretchr/testify v1.8.2 // indirect diff --git a/witness/wasmer/go.sum b/witness/wasmer/go.sum new file mode 100644 index 0000000..f3b4323 --- /dev/null +++ b/witness/wasmer/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= +github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/circom2witnesscalc_wazero.go b/witness/wazero/circom2witnesscalc_wazero.go similarity index 95% rename from witness/circom2witnesscalc_wazero.go rename to witness/wazero/circom2witnesscalc_wazero.go index 6d1e7b8..9d53130 100644 --- a/witness/circom2witnesscalc_wazero.go +++ b/witness/wazero/circom2witnesscalc_wazero.go @@ -1,4 +1,4 @@ -package witness +package wazero import ( "bytes" @@ -6,26 +6,27 @@ import ( "encoding/binary" "errors" "fmt" + "hash/fnv" "log" "math" "math/big" "strings" "github.com/iden3/go-iden3-crypto/constants" - "github.com/tetratelabs/wazero" + wz "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/api" ) type Circom2WZWitnessCalculator struct { - runtime wazero.Runtime + runtime wz.Runtime modRuntime api.Module - compiledModule wazero.CompiledModule + compiledModule wz.CompiledModule } func NewCircom2WZWitnessCalculator( - wasmBytes []byte) (WitnessCalculator, error) { + wasmBytes []byte) (*Circom2WZWitnessCalculator, error) { - runtime := wazero.NewRuntime(context.Background()) + runtime := wz.NewRuntime(context.Background()) ctx := context.Background() modRuntime, err := runtime.NewHostModuleBuilder("runtime"). @@ -91,7 +92,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWitness(inputs map[string]interfa wCtxState := &witnessCtxState{} ctx := withWtnsCtx(context.Background(), wCtxState) - cfg := wazero.NewModuleConfig() + cfg := wz.NewModuleConfig() var instance api.Module instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) if err != nil { @@ -139,7 +140,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateBinWitness(inputs map[string]inte wCtxState := &witnessCtxState{} ctx := withWtnsCtx(context.Background(), wCtxState) - cfg := wazero.NewModuleConfig() + cfg := wz.NewModuleConfig() var instance api.Module instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) if err != nil { @@ -186,7 +187,7 @@ func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interfa wCtxState := &witnessCtxState{} ctx := withWtnsCtx(context.Background(), wCtxState) - cfg := wazero.NewModuleConfig() + cfg := wz.NewModuleConfig() var instance api.Module instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) if err != nil { @@ -637,3 +638,21 @@ func printSharedRWMemory(ctx context.Context, m api.Module) { wtnsCtx.msgStrs = append(wtnsCtx.msgStrs, fromArray32(arr).Text(10)) } + +func fromArray32(arr []uint32) *big.Int { + res := new(big.Int) + radix := big.NewInt(0x100000000) + for i := 0; i < len(arr); i++ { + res.Mul(res, radix) + res.Add(res, big.NewInt(int64(arr[i]))) + } + return res +} + +// fnvHash returns the 64 bit FNV-1a hash split into two 32 bit values: (MSB, LSB) +func fnvHash(s string) (int32, int32) { + hash := fnv.New64a() + hash.Write([]byte(s)) + h := hash.Sum64() + return int32(h >> 32), int32(h & 0xffffffff) +} diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod new file mode 100644 index 0000000..3d7825d --- /dev/null +++ b/witness/wazero/go.mod @@ -0,0 +1,8 @@ +module github.com/iden3/go-rapidsnark/witness/wazero + +go 1.18 + +require ( + github.com/iden3/go-iden3-crypto v0.0.15 + github.com/tetratelabs/wazero v1.1.0 +) diff --git a/witness/wazero/go.sum b/witness/wazero/go.sum new file mode 100644 index 0000000..796c854 --- /dev/null +++ b/witness/wazero/go.sum @@ -0,0 +1,4 @@ +github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= +github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= +github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= diff --git a/witness/witness.go b/witness/witness.go index 95b3365..2ea3a8a 100644 --- a/witness/witness.go +++ b/witness/witness.go @@ -1,6 +1,9 @@ package witness -import "math/big" +import ( + "errors" + "math/big" +) type Option func(cfg *calcConfig) @@ -29,7 +32,7 @@ func NewCalc(wasm []byte, ops ...Option) (WitnessCalculator, error) { op(&config) } if config.wasmEngine == nil { - config.wasmEngine = NewCircom2WZWitnessCalculator + return nil, errors.New("witness calculator wasm engine not set") } return config.wasmEngine(wasm) } diff --git a/witness/witness_test.go b/witness/witness_test.go deleted file mode 100644 index 684a364..0000000 --- a/witness/witness_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package witness - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestEngines(t *testing.T) { - engineTestCases := []struct { - title string - engine func([]byte) (WitnessCalculator, error) - }{ - { - title: "Wazero", - engine: NewCircom2WZWitnessCalculator, - }, - { - title: "Wasmer", - engine: NewCircom2WitnessCalculator, - }, - { - title: "empty", - engine: nil, - }, - } - - circomTestCases := []struct { - wasmFile string - inputs string - wantWtnsHex string - wantBinWtnsHex string - wantWTNSBinHex string - }{ - { - wasmFile: "testdata/circom2/circuit.wasm", - inputs: "testdata/circom2/input.json", - wantWtnsHex: "c1780821352c069392e9d0fab4330531", - wantBinWtnsHex: "d2c0486d7fd6f0715d04d535765f028b", - wantWTNSBinHex: "1709fbda942dabed641044f39b466e94", - }, - { - wasmFile: "testdata/circom2_1_0/circuit.wasm", - inputs: "testdata/circom2_1_0/input.json", - wantWtnsHex: "c0a2b43f5a333310c2bb8d357db46d3b", - wantBinWtnsHex: "2b38b66035d8e923eacc028ea0f1dad2", - wantWTNSBinHex: "75c5682a7195c20868b59d6580852fce", - }, - } - - for i := range engineTestCases { - engTC := engineTestCases[i] - t.Run(engTC.title, func(t *testing.T) { - for _, circomTC := range circomTestCases { - t.Run(circomTC.wasmFile, func(t *testing.T) { - wasmBytes, err := os.ReadFile(circomTC.wasmFile) - require.NoError(t, err) - inputBytes, err := os.ReadFile(circomTC.inputs) - require.NoError(t, err) - - var ops []Option - if engTC.engine != nil { - ops = append(ops, WithWasmEngine(engTC.engine)) - } - calc, err := NewCalc(wasmBytes, ops...) - require.NoError(t, err) - - inputs, err := ParseInputs(inputBytes) - require.NoError(t, err) - - t.Run("CalculateWitness", func(t *testing.T) { - witness, err := calc.CalculateWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) - require.Equal(t, circomTC.wantWtnsHex, - hashInts(witness)) - }) - - t.Run("CalculateBinWitness", func(t *testing.T) { - witness, err := calc.CalculateBinWitness(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) - require.Equal(t, circomTC.wantBinWtnsHex, - hashBytes(witness)) - }) - - t.Run("CalculateWTNSBin", func(t *testing.T) { - witness, err := calc.CalculateWTNSBin(inputs, true) - require.NoError(t, err) - require.NotEmpty(t, witness) - require.Equal(t, circomTC.wantWTNSBinHex, - hashBytes(witness)) - }) - }) - } - }) - } -} From 103878e2217024178089a809c3667dc3c002a216 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 18 May 2023 14:02:12 -0400 Subject: [PATCH 11/24] add linter and tests for witness calc --- .github/workflows/lint.yaml | 32 ++++++++++++++++++++++++++++++++ .github/workflows/test.yaml | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .github/workflows/lint.yaml create mode 100644 .github/workflows/test.yaml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..573fdcc --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,32 @@ +name: lint + +on: + push: + branches: + - master + pull_request: + +jobs: + lint: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: 1.20.4 + - uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 + working-directory: witness + - uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 + working-directory: witness/wazero + - uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 + working-directory: witness/wasmer + - uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 + working-directory: witness/test_wasm_impls diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..7e82bc4 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,32 @@ +name: test + +on: + push: + branches: + - master + pull_request: + +jobs: + test: + strategy: + matrix: + containers: + - 1.18.10-bullseye + - 1.19.9-bullseye + - 1.20.4-bullseye + runs-on: ubuntu-20.04 + container: golang:${{matrix.containers}} + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + /go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - run: pushd witness; go test -race -timeout=60s -v ./...; popd + - run: pushd witness/wazero; go test -race -timeout=60s -v ./...; popd + - run: pushd witness/wasmer; go test -race -timeout=60s -v ./...; popd + - run: pushd witness/test_wasm_impls; go test -race -timeout=60s -v ./...; popd From 7d3d51bd5a0e9227be51e4895a22fb6741b55e05 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 18 May 2023 14:06:45 -0400 Subject: [PATCH 12/24] fix test commands --- .github/workflows/{lint.yaml => lint-witness.yaml} | 12 ++++++++---- .github/workflows/{test.yaml => test-witness.yaml} | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) rename .github/workflows/{lint.yaml => lint-witness.yaml} (63%) rename .github/workflows/{test.yaml => test-witness.yaml} (64%) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint-witness.yaml similarity index 63% rename from .github/workflows/lint.yaml rename to .github/workflows/lint-witness.yaml index 573fdcc..5b7afed 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint-witness.yaml @@ -14,19 +14,23 @@ jobs: - uses: actions/setup-go@v4 with: go-version: 1.20.4 - - uses: golangci/golangci-lint-action@v3 + - name: lint witness + uses: golangci/golangci-lint-action@v3 with: version: v1.52.2 working-directory: witness - - uses: golangci/golangci-lint-action@v3 + - name: lint witness/wazero + uses: golangci/golangci-lint-action@v3 with: version: v1.52.2 working-directory: witness/wazero - - uses: golangci/golangci-lint-action@v3 + - name: lint witness/wasmer + uses: golangci/golangci-lint-action@v3 with: version: v1.52.2 working-directory: witness/wasmer - - uses: golangci/golangci-lint-action@v3 + - name: lint witness/test_wasm_impls + uses: golangci/golangci-lint-action@v3 with: version: v1.52.2 working-directory: witness/test_wasm_impls diff --git a/.github/workflows/test.yaml b/.github/workflows/test-witness.yaml similarity index 64% rename from .github/workflows/test.yaml rename to .github/workflows/test-witness.yaml index 7e82bc4..6c9d607 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test-witness.yaml @@ -26,7 +26,7 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - - run: pushd witness; go test -race -timeout=60s -v ./...; popd - - run: pushd witness/wazero; go test -race -timeout=60s -v ./...; popd - - run: pushd witness/wasmer; go test -race -timeout=60s -v ./...; popd - - run: pushd witness/test_wasm_impls; go test -race -timeout=60s -v ./...; popd + - run: cd witness && go test -race -timeout=60s -v ./... + - run: cd witness/wazero && go test -race -timeout=60s -v ./... + - run: cd witness/wasmer && go test -race -timeout=60s -v ./... + - run: cd witness/test_wasm_impls && go test -race -timeout=60s -v ./... From b548f2fa75096d63b4a0c1b7f715f59ab622329c Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 18 May 2023 14:08:50 -0400 Subject: [PATCH 13/24] rename lint and test ci jobs --- .github/workflows/lint-witness.yaml | 2 +- .github/workflows/test-witness.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-witness.yaml b/.github/workflows/lint-witness.yaml index 5b7afed..84737bc 100644 --- a/.github/workflows/lint-witness.yaml +++ b/.github/workflows/lint-witness.yaml @@ -1,4 +1,4 @@ -name: lint +name: lint-witness on: push: diff --git a/.github/workflows/test-witness.yaml b/.github/workflows/test-witness.yaml index 6c9d607..4e413d9 100644 --- a/.github/workflows/test-witness.yaml +++ b/.github/workflows/test-witness.yaml @@ -1,4 +1,4 @@ -name: test +name: test-witness on: push: From 68eb2c8974af89e1aaea2eb7ba7b9218db392d74 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Thu, 18 May 2023 14:18:55 -0400 Subject: [PATCH 14/24] Increate timeout for testing witness --- .github/workflows/test-witness.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-witness.yaml b/.github/workflows/test-witness.yaml index 4e413d9..ccd60c1 100644 --- a/.github/workflows/test-witness.yaml +++ b/.github/workflows/test-witness.yaml @@ -29,4 +29,4 @@ jobs: - run: cd witness && go test -race -timeout=60s -v ./... - run: cd witness/wazero && go test -race -timeout=60s -v ./... - run: cd witness/wasmer && go test -race -timeout=60s -v ./... - - run: cd witness/test_wasm_impls && go test -race -timeout=60s -v ./... + - run: cd witness/test_wasm_impls && go test -race -timeout=300s -v ./... From 431fa89ab4b1892c4f46f752825a3d1b6bba1336 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Mon, 22 May 2023 09:03:02 -0400 Subject: [PATCH 15/24] Simplify interface for witness calculator implamentation. Do all serialization and formatting logic in one place. --- witness/go.mod | 6 +- witness/go.sum | 5 + witness/test_wasm_impls/go.mod | 3 +- witness/test_wasm_impls/go.sum | 3 + witness/test_wasm_impls/witness_test.go | 16 +- witness/wasmer/circom2witnesscalc.go | 188 ++++--------- witness/wasmer/go.mod | 10 +- witness/wasmer/go.sum | 17 +- witness/wazero/circom2witnesscalc_wazero.go | 280 ++++++-------------- witness/wazero/go.mod | 3 + witness/witness.go | 140 +++++++++- 11 files changed, 300 insertions(+), 371 deletions(-) diff --git a/witness/go.mod b/witness/go.mod index d48e08a..bcbbcd7 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -2,10 +2,14 @@ module github.com/iden3/go-rapidsnark/witness go 1.18 -require github.com/stretchr/testify v1.8.2 +require ( + github.com/iden3/go-iden3-crypto v0.0.15 + github.com/stretchr/testify v1.8.2 +) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/sys v0.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/witness/go.sum b/witness/go.sum index 6a56e69..da8815d 100644 --- a/witness/go.sum +++ b/witness/go.sum @@ -1,6 +1,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= +github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -10,6 +13,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod index 35a8afd..b45b0b8 100644 --- a/witness/test_wasm_impls/go.mod +++ b/witness/test_wasm_impls/go.mod @@ -3,7 +3,7 @@ module github.com/iden3/go-rapidsnark/witness/test-wasm-impls go 1.18 require ( - github.com/iden3/go-rapidsnark/witness v0.0.0 + github.com/iden3/go-rapidsnark/witness v0.0.6 github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 github.com/stretchr/testify v1.8.2 @@ -16,6 +16,7 @@ require ( github.com/iden3/wasmer-go v0.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/tetratelabs/wazero v1.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/witness/test_wasm_impls/go.sum b/witness/test_wasm_impls/go.sum index 3097dab..8bbbede 100644 --- a/witness/test_wasm_impls/go.sum +++ b/witness/test_wasm_impls/go.sum @@ -5,6 +5,7 @@ github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZ github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -16,6 +17,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/test_wasm_impls/witness_test.go b/witness/test_wasm_impls/witness_test.go index 9e75914..b85bb6b 100644 --- a/witness/test_wasm_impls/witness_test.go +++ b/witness/test_wasm_impls/witness_test.go @@ -13,29 +13,19 @@ import ( "github.com/stretchr/testify/require" ) -func wasmerAdapter(code []byte) (witness.WitnessCalculator, error) { - wc, err := wasmer.NewCircom2WitnessCalculator(code) - return wc, err -} - -func wazeroAdapter(code []byte) (witness.WitnessCalculator, error) { - wc, err := wazero.NewCircom2WZWitnessCalculator(code) - return wc, err -} - func TestEngines(t *testing.T) { engineTestCases := []struct { title string - engine func(code []byte) (witness.WitnessCalculator, error) + engine func(code []byte) (witness.CalculatorImpl, error) wantErr string }{ { title: "Wazero", - engine: wazeroAdapter, + engine: wazero.NewCircom2WZWitnessCalculator, }, { title: "Wasmer", - engine: wasmerAdapter, + engine: wasmer.NewCircom2WitnessCalculator, }, { title: "empty", diff --git a/witness/wasmer/circom2witnesscalc.go b/witness/wasmer/circom2witnesscalc.go index 5f39198..d67915c 100644 --- a/witness/wasmer/circom2witnesscalc.go +++ b/witness/wasmer/circom2witnesscalc.go @@ -9,6 +9,8 @@ import ( "math/big" "reflect" + "github.com/iden3/go-iden3-crypto/utils" + "github.com/iden3/go-rapidsnark/witness" "github.com/iden3/wasmer-go/wasmer" ) @@ -39,10 +41,10 @@ type Circom2WitnessCalculator struct { msgStr bytes.Buffer } -// NewCircom2WitnessCalculator creates a new WitnessCalculator from the WitnessCalc +// NewCircom2WitnessCalculator creates a new CalculatorImpl from the WitnessCalc // loaded WASM module in the runtime. func NewCircom2WitnessCalculator( - wasmBytes []byte) (*Circom2WitnessCalculator, error) { + wasmBytes []byte) (witness.CalculatorImpl, error) { wc := Circom2WitnessCalculator{} @@ -201,139 +203,8 @@ func NewCircom2WitnessCalculator( } // CalculateWitness calculates the witness given the inputs. -func (wc *Circom2WitnessCalculator) CalculateWitness(inputs map[string]interface{}, sanityCheck bool) ([]*big.Int, error) { - - w := make([]*big.Int, wc.witnessSize) - - err := wc.doCalculateWitness(inputs, sanityCheck) - if err != nil { - return nil, err - } - - for i := 0; i < int(wc.witnessSize); i++ { - _, err := wc.getWitness(i) - if err != nil { - return nil, err - } - arr := make([]uint32, wc.n32) - for j := 0; j < int(wc.n32); j++ { - val, err := wc.readSharedRWMemory(int32(j)) - if err != nil { - return nil, err - } - arr[int(wc.n32)-1-j] = uint32(val.(int32)) - } - w[i] = fromArray32(arr) - } - - return w, nil -} - -// CalculateBinWitness calculates the witness in binary given the inputs. -func (wc *Circom2WitnessCalculator) CalculateBinWitness(inputs map[string]interface{}, sanityCheck bool) ([]byte, error) { - buff := new(bytes.Buffer) - - err := wc.doCalculateWitness(inputs, sanityCheck) - if err != nil { - return nil, err - } - - for i := 0; i < int(wc.witnessSize); i++ { - _, err := wc.getWitness(i) - if err != nil { - return nil, err - } - - for j := 0; j < int(wc.n32); j++ { - val, err := wc.readSharedRWMemory(j) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(val.(int32))) - } - } - - return buff.Bytes(), nil -} - -// CalculateWTNSBin calculates the witness in binary given the inputs. -func (wc *Circom2WitnessCalculator) CalculateWTNSBin(inputs map[string]interface{}, sanityCheck bool) ([]byte, error) { - buff := new(bytes.Buffer) - - err := wc.doCalculateWitness(inputs, sanityCheck) - if err != nil { - return nil, err - } - - buff.Grow(int(wc.witnessSize*wc.n32 + wc.n32 + 11)) - - // wtns - _ = buff.WriteByte('w') - _ = buff.WriteByte('t') - _ = buff.WriteByte('n') - _ = buff.WriteByte('s') - - //version 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - //number of sections: 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - //id section 1 - _ = binary.Write(buff, binary.LittleEndian, uint32(1)) - - n8 := wc.n32 * 4 - //id section 1 length in 64bytes - idSection1length := 8 + n8 - _ = binary.Write(buff, binary.LittleEndian, uint64(idSection1length)) - - //this.n32 - _ = binary.Write(buff, binary.LittleEndian, uint32(n8)) - - //prime number - _, err = wc.getRawPrime() - if err != nil { - return nil, err - } - - for j := 0; j < int(wc.n32); j++ { - val, err := wc.readSharedRWMemory(int32(j)) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(val.(int32))) - } - - // witness size - _ = binary.Write(buff, binary.LittleEndian, uint32(wc.witnessSize)) - - //id section 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - // section 2 length - idSection2length := n8 * wc.witnessSize - _ = binary.Write(buff, binary.LittleEndian, uint64(idSection2length)) - - for i := 0; i < int(wc.witnessSize); i++ { - _, err := wc.getWitness(i) - if err != nil { - return nil, err - } - - for j := 0; j < int(wc.n32); j++ { - val, err := wc.readSharedRWMemory(j) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(val.(int32))) - } - } - - return buff.Bytes(), nil -} - -// CalculateWitness calculates the witness given the inputs. -func (wc *Circom2WitnessCalculator) doCalculateWitness(inputs map[string]interface{}, sanityCheck bool) (funcErr error) { +func (wc *Circom2WitnessCalculator) doCalculateWitness(inputs map[string]interface{}, + sanityCheck bool) (funcErr error) { //input is assumed to be a map from signals to arrays of bigInts sanityCheckVal := int32(0) if sanityCheck { @@ -615,3 +486,50 @@ func flatSlice(v interface{}) []*big.Int { _flatSlice(&res, v) return res } + +func (wc *Circom2WitnessCalculator) Calculate(inputs map[string]interface{}, + sanityCheck bool) (wtns witness.Wtns, err error) { + + err = wc.doCalculateWitness(inputs, sanityCheck) + if err != nil { + return wtns, err + } + + //prime number + _, err = wc.getRawPrime() + if err != nil { + return wtns, err + } + + n8 := wc.n32 * 4 + bigIntBuf := make([]byte, n8) + for j := 0; j < int(wc.n32); j++ { + val, err := wc.readSharedRWMemory(int32(j)) + if err != nil { + return wtns, err + } + binary.LittleEndian.PutUint32(bigIntBuf[j*4:], uint32(val.(int32))) + } + + wtns.Prime = new(big.Int).SetBytes(utils.SwapEndianness(bigIntBuf)) + wtns.N32 = int(wc.n32) + + wtns.Wtns = make([]*big.Int, wc.witnessSize) + for i := 0; i < int(wc.witnessSize); i++ { + _, err := wc.getWitness(i) + if err != nil { + return wtns, err + } + + for j := 0; j < int(wc.n32); j++ { + val, err := wc.readSharedRWMemory(j) + if err != nil { + return wtns, err + } + binary.LittleEndian.PutUint32(bigIntBuf[j*4:], uint32(val.(int32))) + } + wtns.Wtns[i] = new(big.Int).SetBytes(utils.SwapEndianness(bigIntBuf)) + } + + return wtns, nil +} diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index fb851ff..ad8e19e 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -2,6 +2,12 @@ module github.com/iden3/go-rapidsnark/witness/wasmer go 1.18 -require github.com/iden3/wasmer-go v0.0.1 +require ( + github.com/iden3/go-iden3-crypto v0.0.15 + github.com/iden3/go-rapidsnark/witness v0.0.6 + github.com/iden3/wasmer-go v0.0.1 +) -require github.com/stretchr/testify v1.8.2 // indirect +require golang.org/x/sys v0.6.0 // indirect + +replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wasmer/go.sum b/witness/wasmer/go.sum index f3b4323..df3411f 100644 --- a/witness/wasmer/go.sum +++ b/witness/wasmer/go.sum @@ -1,18 +1,11 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= +github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/witness/wazero/circom2witnesscalc_wazero.go b/witness/wazero/circom2witnesscalc_wazero.go index 9d53130..c7e6a22 100644 --- a/witness/wazero/circom2witnesscalc_wazero.go +++ b/witness/wazero/circom2witnesscalc_wazero.go @@ -3,7 +3,6 @@ package wazero import ( "bytes" "context" - "encoding/binary" "errors" "fmt" "hash/fnv" @@ -13,6 +12,7 @@ import ( "strings" "github.com/iden3/go-iden3-crypto/constants" + "github.com/iden3/go-rapidsnark/witness" wz "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/api" ) @@ -24,7 +24,7 @@ type Circom2WZWitnessCalculator struct { } func NewCircom2WZWitnessCalculator( - wasmBytes []byte) (*Circom2WZWitnessCalculator, error) { + wasmBytes []byte) (witness.CalculatorImpl, error) { runtime := wz.NewRuntime(context.Background()) @@ -85,206 +85,6 @@ func (w *Circom2WZWitnessCalculator) Close() error { return err } -// CalculateWitness calculates the witness given the inputs. -func (wc *Circom2WZWitnessCalculator) CalculateWitness(inputs map[string]interface{}, - sanityCheck bool) (wtns []*big.Int, err error) { - - wCtxState := &witnessCtxState{} - ctx := withWtnsCtx(context.Background(), wCtxState) - - cfg := wz.NewModuleConfig() - var instance api.Module - instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) - if err != nil { - return nil, err - } - defer closeWithErrOrLog(ctx, instance, &err) - - var wCtx witnessCtx - wCtx, err = calculateWtnsCtx(ctx, instance) - if err != nil { - return nil, err - } - - err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) - if err != nil { - return nil, err - } - - wtns = make([]*big.Int, wCtx.witnessSize) - - for i := 0; i < int(wCtx.witnessSize); i++ { - err = wCtx.getWitness(ctx, int32(i)) - if err != nil { - return nil, err - } - arr := make([]uint32, wCtx.n32) - for j := 0; j < int(wCtx.n32); j++ { - var val int32 - val, err = wCtx.readSharedRWMemory(ctx, int32(j)) - if err != nil { - return nil, err - } - arr[int(wCtx.n32)-1-j] = uint32(val) - } - wtns[i] = fromArray32(arr) - } - - return wtns, wCtxState.err() -} - -// CalculateBinWitness calculates the witness in binary given the inputs. -func (wc *Circom2WZWitnessCalculator) CalculateBinWitness(inputs map[string]interface{}, - sanityCheck bool) (wtns []byte, err error) { - - wCtxState := &witnessCtxState{} - ctx := withWtnsCtx(context.Background(), wCtxState) - - cfg := wz.NewModuleConfig() - var instance api.Module - instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) - if err != nil { - return nil, err - } - defer closeWithErrOrLog(ctx, instance, &err) - - var wCtx witnessCtx - // wCtx is closure around ctx, do not return it, use only in this function. - wCtx, err = calculateWtnsCtx(ctx, instance) - if err != nil { - return nil, err - } - - err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) - if err != nil { - return nil, err - } - - buff := new(bytes.Buffer) - - for i := 0; i < int(wCtx.witnessSize); i++ { - err = wCtx.getWitness(ctx, int32(i)) - if err != nil { - return nil, err - } - - for j := 0; j < int(wCtx.n32); j++ { - val, err := wCtx.readSharedRWMemory(ctx, int32(j)) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(val)) - } - } - - return buff.Bytes(), wCtxState.err() -} - -// CalculateWTNSBin calculates the witness in binary given the inputs. -func (wc *Circom2WZWitnessCalculator) CalculateWTNSBin(inputs map[string]interface{}, - sanityCheck bool) (wtns []byte, err error) { - - wCtxState := &witnessCtxState{} - ctx := withWtnsCtx(context.Background(), wCtxState) - - cfg := wz.NewModuleConfig() - var instance api.Module - instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) - if err != nil { - return nil, err - } - defer closeWithErrOrLog(ctx, instance, &err) - - var wCtx witnessCtx - // wCtx is closure around ctx, do not return it, use only in this function. - wCtx, err = calculateWtnsCtx(ctx, instance) - if err != nil { - return nil, err - } - - err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) - if err != nil { - return nil, err - } - - buff := new(bytes.Buffer) - - var wResult []uint64 - wResult, err = instance.ExportedFunction("getWitnessSize").Call(ctx) - if err != nil { - return nil, err - } - witnessSize := api.DecodeI32(wResult[0]) - - buff.Grow(int(witnessSize*wCtx.n32 + wCtx.n32 + 11)) - - // wtns - _ = buff.WriteByte('w') - _ = buff.WriteByte('t') - _ = buff.WriteByte('n') - _ = buff.WriteByte('s') - - //version 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - //number of sections: 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - //id section 1 - _ = binary.Write(buff, binary.LittleEndian, uint32(1)) - - n8 := wCtx.n32 * 4 - //id section 1 length in 64bytes - idSection1length := 8 + n8 - _ = binary.Write(buff, binary.LittleEndian, uint64(idSection1length)) - - //this.n32 - _ = binary.Write(buff, binary.LittleEndian, uint32(n8)) - - //prime number - _, err = instance.ExportedFunction("getRawPrime").Call(ctx) - if err != nil { - return nil, err - } - - for j := 0; j < int(wCtx.n32); j++ { - data, err := wCtx.readSharedRWMemory(ctx, int32(j)) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(data)) - } - - // witness size - _ = binary.Write(buff, binary.LittleEndian, uint32(witnessSize)) - - //id section 2 - _ = binary.Write(buff, binary.LittleEndian, uint32(2)) - - // section 2 length - idSection2length := n8 * witnessSize - _ = binary.Write(buff, binary.LittleEndian, uint64(idSection2length)) - - getWitness := instance.ExportedFunction("getWitness") - for i := 0; i < int(witnessSize); i++ { - _, err = getWitness.Call(ctx, api.EncodeI32(int32(i))) - if err != nil { - return nil, err - } - - for j := 0; j < int(wCtx.n32); j++ { - var data int32 - data, err = wCtx.readSharedRWMemory(ctx, int32(j)) - if err != nil { - return nil, err - } - _ = binary.Write(buff, binary.LittleEndian, uint32(data)) - } - } - - return buff.Bytes(), wCtxState.err() -} - func (w *Circom2WZWitnessCalculator) doCalculateWitness(ctx context.Context, wCtx witnessCtx, inputs map[string]any, sanityCheck bool) (err error) { @@ -346,6 +146,30 @@ type witnessCtx struct { setInputSignal func(ctx context.Context, hMSB, hLSB, z int32) error readSharedRWMemory func(ctx context.Context, i int32) (int32, error) getWitness func(ctx context.Context, i int32) error + getRawPrime func(ctx context.Context) error +} + +func (wCtx *witnessCtx) prime(ctx context.Context) (*big.Int, error) { + + err := wCtx.getRawPrime(ctx) + if err != nil { + return nil, err + } + + return wCtx.readInt(ctx) +} + +func (wCtx *witnessCtx) readInt(ctx context.Context) (*big.Int, error) { + arr := make([]uint32, wCtx.n32) + for j := 0; j < int(wCtx.n32); j++ { + val, err := wCtx.readSharedRWMemory(ctx, int32(j)) + if err != nil { + return nil, err + } + arr[int(wCtx.n32)-1-j] = uint32(val) + } + + return fromArray32(arr), nil } func calculateWtnsCtx(ctx context.Context, @@ -429,6 +253,12 @@ func calculateWtnsCtx(ctx context.Context, return err2 } + _getRawPrime := instance.ExportedFunction("getRawPrime") + wCtx.getRawPrime = func(ctx context.Context) error { + _, err2 := _getRawPrime.Call(ctx) + return err2 + } + return wCtx, nil } @@ -656,3 +486,49 @@ func fnvHash(s string) (int32, int32) { h := hash.Sum64() return int32(h >> 32), int32(h & 0xffffffff) } + +// Calculate calculates the witness given the inputs. +func (wc *Circom2WZWitnessCalculator) Calculate(inputs map[string]interface{}, + sanityCheck bool) (wtns witness.Wtns, err error) { + + wCtxState := &witnessCtxState{} + ctx := withWtnsCtx(context.Background(), wCtxState) + + cfg := wz.NewModuleConfig() + var instance api.Module + instance, err = wc.runtime.InstantiateModule(ctx, wc.compiledModule, cfg) + if err != nil { + return wtns, err + } + defer closeWithErrOrLog(ctx, instance, &err) + + var wCtx witnessCtx + wCtx, err = calculateWtnsCtx(ctx, instance) + if err != nil { + return wtns, err + } + + wtns.N32 = int(wCtx.n32) + + err = wc.doCalculateWitness(ctx, wCtx, inputs, sanityCheck) + if err != nil { + return wtns, err + } + + wtns.Wtns = make([]*big.Int, wCtx.witnessSize) + + for i := 0; i < int(wCtx.witnessSize); i++ { + err = wCtx.getWitness(ctx, int32(i)) + if err != nil { + return wtns, err + } + wtns.Wtns[i], err = wCtx.readInt(ctx) + } + + wtns.Prime, err = wCtx.prime(ctx) + if err != nil { + return wtns, err + } + + return wtns, wCtxState.err() +} diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index 3d7825d..f8ae6a9 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -5,4 +5,7 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 github.com/tetratelabs/wazero v1.1.0 + github.com/iden3/go-rapidsnark/witness v0.0.0 ) + +replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/witness.go b/witness/witness.go index 2ea3a8a..a234cc1 100644 --- a/witness/witness.go +++ b/witness/witness.go @@ -1,19 +1,29 @@ package witness import ( + "bytes" + "encoding/binary" "errors" + "io" "math/big" + + "github.com/iden3/go-iden3-crypto/utils" ) type Option func(cfg *calcConfig) -func WithWasmEngine(calculator func([]byte) (WitnessCalculator, error)) Option { +func WithWasmEngine(calculator func([]byte) (CalculatorImpl, error)) Option { return func(cfg *calcConfig) { cfg.wasmEngine = calculator } } -type WitnessCalculator interface { +type CalculatorImpl interface { + Calculate(inputs map[string]interface{}, + sanityCheck bool) (wtns Wtns, err error) +} + +type Calculator interface { CalculateWitness(inputs map[string]interface{}, sanityCheck bool) ([]*big.Int, error) CalculateBinWitness(inputs map[string]interface{}, @@ -23,10 +33,119 @@ type WitnessCalculator interface { } type calcConfig struct { - wasmEngine func([]byte) (WitnessCalculator, error) + wasmEngine func([]byte) (CalculatorImpl, error) +} + +type calc struct { + wc CalculatorImpl +} + +func (c *calc) CalculateWitness(inputs map[string]interface{}, + sanityCheck bool) ([]*big.Int, error) { + + wtns, err := c.wc.Calculate(inputs, sanityCheck) + if err != nil { + return nil, err + } + return wtns.Wtns, nil } -func NewCalc(wasm []byte, ops ...Option) (WitnessCalculator, error) { +func (c *calc) CalculateBinWitness(inputs map[string]interface{}, + sanityCheck bool) ([]byte, error) { + + wtns, err := c.wc.Calculate(inputs, sanityCheck) + if err != nil { + return nil, err + } + + var b bytes.Buffer + b.Grow(wtns.N32 * 4 * len(wtns.Wtns)) + for _, i := range wtns.Wtns { + bs := utils.SwapEndianness(i.Bytes()) + b.Write(bs) + if len(bs) < wtns.N32*4 { + for j := 0; j < (wtns.N32*4)-len(bs); j++ { + b.WriteByte(0) + } + } + } + + return b.Bytes(), nil +} + +func (c *calc) CalculateWTNSBin(inputs map[string]interface{}, + sanityCheck bool) ([]byte, error) { + + wtns, err := c.wc.Calculate(inputs, sanityCheck) + if err != nil { + return nil, err + } + + buff := new(bytes.Buffer) + + n8 := wtns.N32 * 4 + idSection2length := n8 * len(wtns.Wtns) + + totalLn := 4 + 4 + 4 + 4 + 8 + 4 + n8 + 4 + 4 + 8 + idSection2length + buff.Grow(totalLn) + + // wtns + _, _ = buff.Write([]byte("wtns")) + + //version 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + //number of sections: 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + //id section 1 + _ = binary.Write(buff, binary.LittleEndian, uint32(1)) + + //id section 1 length in 64bytes + idSection1length := 8 + n8 + _ = binary.Write(buff, binary.LittleEndian, uint64(idSection1length)) + + //this.n32 + _ = binary.Write(buff, binary.LittleEndian, uint32(n8)) + + err = writeInt(buff, wtns.Prime, n8) + if err != nil { + return nil, err + } + + // witness size + _ = binary.Write(buff, binary.LittleEndian, uint32(len(wtns.Wtns))) + + //id section 2 + _ = binary.Write(buff, binary.LittleEndian, uint32(2)) + + // section 2 length + _ = binary.Write(buff, binary.LittleEndian, uint64(idSection2length)) + + for _, i := range wtns.Wtns { + err = writeInt(buff, i, n8) + if err != nil { + return nil, err + } + } + + return buff.Bytes(), nil +} + +func writeInt(out io.Writer, i *big.Int, bytesLn int) error { + bs := utils.SwapEndianness(i.Bytes()) + _, err := out.Write(bs) + if err != nil { + return err + } + if len(bs) < bytesLn { + _, err = out.Write(make([]byte, bytesLn-len(bs))) + } + + return err +} + +func NewCalc(wasm []byte, ops ...Option) (Calculator, error) { var config calcConfig for _, op := range ops { op(&config) @@ -34,5 +153,16 @@ func NewCalc(wasm []byte, ops ...Option) (WitnessCalculator, error) { if config.wasmEngine == nil { return nil, errors.New("witness calculator wasm engine not set") } - return config.wasmEngine(wasm) + wc, err := config.wasmEngine(wasm) + if err != nil { + return nil, err + } + return &calc{wc: wc}, nil +} + +type Wtns struct { + // number of int32 values required to represent the *big.Int + N32 int + Prime *big.Int + Wtns []*big.Int } From b106fd58a9a9d42640cf32df4b5f2982606a54ec Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Mon, 22 May 2023 09:04:11 -0400 Subject: [PATCH 16/24] go mod tidy --- witness/wazero/go.mod | 4 +++- witness/wazero/go.sum | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index f8ae6a9..62b15ea 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -4,8 +4,10 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/tetratelabs/wazero v1.1.0 github.com/iden3/go-rapidsnark/witness v0.0.0 + github.com/tetratelabs/wazero v1.1.0 ) +require golang.org/x/sys v0.6.0 // indirect + replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wazero/go.sum b/witness/wazero/go.sum index 796c854..ee7bf7b 100644 --- a/witness/wazero/go.sum +++ b/witness/wazero/go.sum @@ -1,4 +1,11 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 6515ad7d0c8d7ae658e08fa73105e4064ad55b9c Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 07:30:58 -0400 Subject: [PATCH 17/24] Update dependencies --- witness/wasmer/go.mod | 4 +--- witness/wasmer/go.sum | 2 ++ witness/wazero/go.mod | 4 +--- witness/wazero/go.sum | 2 ++ 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index ad8e19e..926e6f0 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -4,10 +4,8 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.6 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 github.com/iden3/wasmer-go v0.0.1 ) require golang.org/x/sys v0.6.0 // indirect - -replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wasmer/go.sum b/witness/wasmer/go.sum index df3411f..399d9e1 100644 --- a/witness/wasmer/go.sum +++ b/witness/wasmer/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 h1:NpkuYOKd5E2b1QaFNi9Uo/bMf+iNp/OP8oZqrTgbO2M= +github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9/go.mod h1:DRZPAmtvOtj7EHUCxrH8UH0KNgJTxhWf7q1fxiwDK78= github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index 62b15ea..439bcbb 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -4,10 +4,8 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.0 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 github.com/tetratelabs/wazero v1.1.0 ) require golang.org/x/sys v0.6.0 // indirect - -replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wazero/go.sum b/witness/wazero/go.sum index ee7bf7b..2244cc5 100644 --- a/witness/wazero/go.sum +++ b/witness/wazero/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 h1:NpkuYOKd5E2b1QaFNi9Uo/bMf+iNp/OP8oZqrTgbO2M= +github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9/go.mod h1:DRZPAmtvOtj7EHUCxrH8UH0KNgJTxhWf7q1fxiwDK78= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= From d92296cebddf49d2ee6dd33212d9a2c2f835b7fc Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 08:20:18 -0400 Subject: [PATCH 18/24] upgrade dependencies --- witness/test_wasm_impls/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod index b45b0b8..fcc1101 100644 --- a/witness/test_wasm_impls/go.mod +++ b/witness/test_wasm_impls/go.mod @@ -3,7 +3,7 @@ module github.com/iden3/go-rapidsnark/witness/test-wasm-impls go 1.18 require ( - github.com/iden3/go-rapidsnark/witness v0.0.6 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 github.com/stretchr/testify v1.8.2 From 060a2d3d4a853356cf76f3ee8ff4ffba70c90aa9 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 08:29:16 -0400 Subject: [PATCH 19/24] refactor names --- witness/test_wasm_impls/witness_test.go | 2 +- witness/wasmer/circom2witnesscalc.go | 6 +++--- witness/wasmer/go.mod | 4 ++++ witness/wazero/circom2witnesscalc_wazero.go | 6 +++--- witness/wazero/go.mod | 4 ++++ witness/witness.go | 24 ++++++++++----------- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/witness/test_wasm_impls/witness_test.go b/witness/test_wasm_impls/witness_test.go index b85bb6b..61ad296 100644 --- a/witness/test_wasm_impls/witness_test.go +++ b/witness/test_wasm_impls/witness_test.go @@ -70,7 +70,7 @@ func TestEngines(t *testing.T) { if engTC.engine != nil { ops = append(ops, witness.WithWasmEngine(engTC.engine)) } - calc, err := witness.NewCalc(wasmBytes, ops...) + calc, err := witness.NewCalculator(wasmBytes, ops...) if engTC.wantErr != "" { require.EqualError(t, err, engTC.wantErr) return diff --git a/witness/wasmer/circom2witnesscalc.go b/witness/wasmer/circom2witnesscalc.go index d67915c..1052273 100644 --- a/witness/wasmer/circom2witnesscalc.go +++ b/witness/wasmer/circom2witnesscalc.go @@ -488,7 +488,7 @@ func flatSlice(v interface{}) []*big.Int { } func (wc *Circom2WitnessCalculator) Calculate(inputs map[string]interface{}, - sanityCheck bool) (wtns witness.Wtns, err error) { + sanityCheck bool) (wtns witness.Witness, err error) { err = wc.doCalculateWitness(inputs, sanityCheck) if err != nil { @@ -514,7 +514,7 @@ func (wc *Circom2WitnessCalculator) Calculate(inputs map[string]interface{}, wtns.Prime = new(big.Int).SetBytes(utils.SwapEndianness(bigIntBuf)) wtns.N32 = int(wc.n32) - wtns.Wtns = make([]*big.Int, wc.witnessSize) + wtns.Witness = make([]*big.Int, wc.witnessSize) for i := 0; i < int(wc.witnessSize); i++ { _, err := wc.getWitness(i) if err != nil { @@ -528,7 +528,7 @@ func (wc *Circom2WitnessCalculator) Calculate(inputs map[string]interface{}, } binary.LittleEndian.PutUint32(bigIntBuf[j*4:], uint32(val.(int32))) } - wtns.Wtns[i] = new(big.Int).SetBytes(utils.SwapEndianness(bigIntBuf)) + wtns.Witness[i] = new(big.Int).SetBytes(utils.SwapEndianness(bigIntBuf)) } return wtns, nil diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index 926e6f0..42b3f40 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -9,3 +9,7 @@ require ( ) require golang.org/x/sys v0.6.0 // indirect + +replace ( + github.com/iden3/go-rapidsnark/witness => ../ +) diff --git a/witness/wazero/circom2witnesscalc_wazero.go b/witness/wazero/circom2witnesscalc_wazero.go index c7e6a22..8f06875 100644 --- a/witness/wazero/circom2witnesscalc_wazero.go +++ b/witness/wazero/circom2witnesscalc_wazero.go @@ -489,7 +489,7 @@ func fnvHash(s string) (int32, int32) { // Calculate calculates the witness given the inputs. func (wc *Circom2WZWitnessCalculator) Calculate(inputs map[string]interface{}, - sanityCheck bool) (wtns witness.Wtns, err error) { + sanityCheck bool) (wtns witness.Witness, err error) { wCtxState := &witnessCtxState{} ctx := withWtnsCtx(context.Background(), wCtxState) @@ -515,14 +515,14 @@ func (wc *Circom2WZWitnessCalculator) Calculate(inputs map[string]interface{}, return wtns, err } - wtns.Wtns = make([]*big.Int, wCtx.witnessSize) + wtns.Witness = make([]*big.Int, wCtx.witnessSize) for i := 0; i < int(wCtx.witnessSize); i++ { err = wCtx.getWitness(ctx, int32(i)) if err != nil { return wtns, err } - wtns.Wtns[i], err = wCtx.readInt(ctx) + wtns.Witness[i], err = wCtx.readInt(ctx) } wtns.Prime, err = wCtx.prime(ctx) diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index 439bcbb..3d1f7c8 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -9,3 +9,7 @@ require ( ) require golang.org/x/sys v0.6.0 // indirect + +replace ( + github.com/iden3/go-rapidsnark/witness => ../ +) diff --git a/witness/witness.go b/witness/witness.go index a234cc1..69ad56b 100644 --- a/witness/witness.go +++ b/witness/witness.go @@ -20,7 +20,7 @@ func WithWasmEngine(calculator func([]byte) (CalculatorImpl, error)) Option { type CalculatorImpl interface { Calculate(inputs map[string]interface{}, - sanityCheck bool) (wtns Wtns, err error) + sanityCheck bool) (wtns Witness, err error) } type Calculator interface { @@ -47,7 +47,7 @@ func (c *calc) CalculateWitness(inputs map[string]interface{}, if err != nil { return nil, err } - return wtns.Wtns, nil + return wtns.Witness, nil } func (c *calc) CalculateBinWitness(inputs map[string]interface{}, @@ -59,8 +59,8 @@ func (c *calc) CalculateBinWitness(inputs map[string]interface{}, } var b bytes.Buffer - b.Grow(wtns.N32 * 4 * len(wtns.Wtns)) - for _, i := range wtns.Wtns { + b.Grow(wtns.N32 * 4 * len(wtns.Witness)) + for _, i := range wtns.Witness { bs := utils.SwapEndianness(i.Bytes()) b.Write(bs) if len(bs) < wtns.N32*4 { @@ -84,7 +84,7 @@ func (c *calc) CalculateWTNSBin(inputs map[string]interface{}, buff := new(bytes.Buffer) n8 := wtns.N32 * 4 - idSection2length := n8 * len(wtns.Wtns) + idSection2length := n8 * len(wtns.Witness) totalLn := 4 + 4 + 4 + 4 + 8 + 4 + n8 + 4 + 4 + 8 + idSection2length buff.Grow(totalLn) @@ -114,7 +114,7 @@ func (c *calc) CalculateWTNSBin(inputs map[string]interface{}, } // witness size - _ = binary.Write(buff, binary.LittleEndian, uint32(len(wtns.Wtns))) + _ = binary.Write(buff, binary.LittleEndian, uint32(len(wtns.Witness))) //id section 2 _ = binary.Write(buff, binary.LittleEndian, uint32(2)) @@ -122,7 +122,7 @@ func (c *calc) CalculateWTNSBin(inputs map[string]interface{}, // section 2 length _ = binary.Write(buff, binary.LittleEndian, uint64(idSection2length)) - for _, i := range wtns.Wtns { + for _, i := range wtns.Witness { err = writeInt(buff, i, n8) if err != nil { return nil, err @@ -145,7 +145,7 @@ func writeInt(out io.Writer, i *big.Int, bytesLn int) error { return err } -func NewCalc(wasm []byte, ops ...Option) (Calculator, error) { +func NewCalculator(wasm []byte, ops ...Option) (Calculator, error) { var config calcConfig for _, op := range ops { op(&config) @@ -160,9 +160,9 @@ func NewCalc(wasm []byte, ops ...Option) (Calculator, error) { return &calc{wc: wc}, nil } -type Wtns struct { +type Witness struct { // number of int32 values required to represent the *big.Int - N32 int - Prime *big.Int - Wtns []*big.Int + N32 int + Prime *big.Int + Witness []*big.Int } From 860eea28aa29daa182e421f986a41c043f9b9a11 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 08:30:56 -0400 Subject: [PATCH 20/24] upgrade dependencies --- witness/wasmer/go.mod | 6 ++---- witness/wasmer/go.sum | 2 -- witness/wazero/go.mod | 6 ++---- witness/wazero/go.sum | 2 -- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index 42b3f40..d65b273 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -4,12 +4,10 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 github.com/iden3/wasmer-go v0.0.1 ) require golang.org/x/sys v0.6.0 // indirect -replace ( - github.com/iden3/go-rapidsnark/witness => ../ -) +replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wasmer/go.sum b/witness/wasmer/go.sum index 399d9e1..df3411f 100644 --- a/witness/wasmer/go.sum +++ b/witness/wasmer/go.sum @@ -1,8 +1,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 h1:NpkuYOKd5E2b1QaFNi9Uo/bMf+iNp/OP8oZqrTgbO2M= -github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9/go.mod h1:DRZPAmtvOtj7EHUCxrH8UH0KNgJTxhWf7q1fxiwDK78= github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= github.com/iden3/wasmer-go v0.0.1/go.mod h1:ZnZBAO012M7o+Q1INXLRIxKQgEcH2FuwL0Iga8A4ufg= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index 3d1f7c8..ebfd71a 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -4,12 +4,10 @@ go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 github.com/tetratelabs/wazero v1.1.0 ) require golang.org/x/sys v0.6.0 // indirect -replace ( - github.com/iden3/go-rapidsnark/witness => ../ -) +replace github.com/iden3/go-rapidsnark/witness => ../ diff --git a/witness/wazero/go.sum b/witness/wazero/go.sum index 2244cc5..ee7bf7b 100644 --- a/witness/wazero/go.sum +++ b/witness/wazero/go.sum @@ -1,8 +1,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 h1:NpkuYOKd5E2b1QaFNi9Uo/bMf+iNp/OP8oZqrTgbO2M= -github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9/go.mod h1:DRZPAmtvOtj7EHUCxrH8UH0KNgJTxhWf7q1fxiwDK78= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= From c22d4d377297baa5cf29226ff672c3963289bac5 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 08:34:03 -0400 Subject: [PATCH 21/24] go mod tidy --- witness/test_wasm_impls/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod index fcc1101..e0cff23 100644 --- a/witness/test_wasm_impls/go.mod +++ b/witness/test_wasm_impls/go.mod @@ -3,7 +3,7 @@ module github.com/iden3/go-rapidsnark/witness/test-wasm-impls go 1.18 require ( - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230522130411-b106fd58a9a9 + github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 github.com/stretchr/testify v1.8.2 From fcfab2575c4dfba8405159ea1f80578fa1f10c9b Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 08:59:54 -0400 Subject: [PATCH 22/24] Dump v2 for witness --- witness/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/witness/go.mod b/witness/go.mod index bcbbcd7..bc7e1d8 100644 --- a/witness/go.mod +++ b/witness/go.mod @@ -1,4 +1,4 @@ -module github.com/iden3/go-rapidsnark/witness +module github.com/iden3/go-rapidsnark/witness/v2 go 1.18 From f25cd597c08d2418fde2442e2cb368227500a94a Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 09:05:24 -0400 Subject: [PATCH 23/24] dump wasmer/wazero versions to v2 --- witness/README.md | 2 +- witness/test_wasm_impls/go.mod | 12 ++++++------ witness/test_wasm_impls/witness_test.go | 6 +++--- witness/wasmer/circom2witnesscalc.go | 2 +- witness/wasmer/go.mod | 6 +++--- witness/wazero/circom2witnesscalc_wazero.go | 2 +- witness/wazero/go.mod | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/witness/README.md b/witness/README.md index aced525..3561c8e 100644 --- a/witness/README.md +++ b/witness/README.md @@ -5,7 +5,7 @@ Calculates witness, that can be passed to a prover ([snarkjs](https://github.com ## Installation ``` -go get github.com/iden3/go-rapidsnark/witness +go get github.com/iden3/go-rapidsnark/witness/v2 ``` ## Dependencies diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod index e0cff23..e69de41 100644 --- a/witness/test_wasm_impls/go.mod +++ b/witness/test_wasm_impls/go.mod @@ -3,9 +3,9 @@ module github.com/iden3/go-rapidsnark/witness/test-wasm-impls go 1.18 require ( - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 - github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 - github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 + github.com/iden3/go-rapidsnark/witness/v2 v2.0.0-20230523125954-fcfab2575c4d + github.com/iden3/go-rapidsnark/witness/v2/wasmer v0.0.0 + github.com/iden3/go-rapidsnark/witness/v2/wazero v0.0.0 github.com/stretchr/testify v1.8.2 ) @@ -21,7 +21,7 @@ require ( ) replace ( - github.com/iden3/go-rapidsnark/witness => ../ - github.com/iden3/go-rapidsnark/witness/wasmer => ../wasmer - github.com/iden3/go-rapidsnark/witness/wazero => ../wazero + github.com/iden3/go-rapidsnark/witness/v2 => ../ + github.com/iden3/go-rapidsnark/witness/v2/wasmer => ../wasmer + github.com/iden3/go-rapidsnark/witness/v2/wazero => ../wazero ) diff --git a/witness/test_wasm_impls/witness_test.go b/witness/test_wasm_impls/witness_test.go index 61ad296..aa008b9 100644 --- a/witness/test_wasm_impls/witness_test.go +++ b/witness/test_wasm_impls/witness_test.go @@ -7,9 +7,9 @@ import ( "os" "testing" - "github.com/iden3/go-rapidsnark/witness" - "github.com/iden3/go-rapidsnark/witness/wasmer" - "github.com/iden3/go-rapidsnark/witness/wazero" + "github.com/iden3/go-rapidsnark/witness/v2" + "github.com/iden3/go-rapidsnark/witness/v2/wasmer" + "github.com/iden3/go-rapidsnark/witness/v2/wazero" "github.com/stretchr/testify/require" ) diff --git a/witness/wasmer/circom2witnesscalc.go b/witness/wasmer/circom2witnesscalc.go index 1052273..6df24d0 100644 --- a/witness/wasmer/circom2witnesscalc.go +++ b/witness/wasmer/circom2witnesscalc.go @@ -10,7 +10,7 @@ import ( "reflect" "github.com/iden3/go-iden3-crypto/utils" - "github.com/iden3/go-rapidsnark/witness" + "github.com/iden3/go-rapidsnark/witness/v2" "github.com/iden3/wasmer-go/wasmer" ) diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index d65b273..753e144 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -1,13 +1,13 @@ -module github.com/iden3/go-rapidsnark/witness/wasmer +module github.com/iden3/go-rapidsnark/witness/v2/wasmer go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 + github.com/iden3/go-rapidsnark/witness/v2 v2.0.0-20230523125954-fcfab2575c4d github.com/iden3/wasmer-go v0.0.1 ) require golang.org/x/sys v0.6.0 // indirect -replace github.com/iden3/go-rapidsnark/witness => ../ +replace github.com/iden3/go-rapidsnark/witness/v2 => ../ diff --git a/witness/wazero/circom2witnesscalc_wazero.go b/witness/wazero/circom2witnesscalc_wazero.go index 8f06875..cea8514 100644 --- a/witness/wazero/circom2witnesscalc_wazero.go +++ b/witness/wazero/circom2witnesscalc_wazero.go @@ -12,7 +12,7 @@ import ( "strings" "github.com/iden3/go-iden3-crypto/constants" - "github.com/iden3/go-rapidsnark/witness" + "github.com/iden3/go-rapidsnark/witness/v2" wz "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/api" ) diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index ebfd71a..d81497d 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -1,13 +1,13 @@ -module github.com/iden3/go-rapidsnark/witness/wazero +module github.com/iden3/go-rapidsnark/witness/v2/wazero go 1.18 require ( github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-rapidsnark/witness v0.0.7-0.20230523122916-060a2d3d4a85 + github.com/iden3/go-rapidsnark/witness/v2 v2.0.0-20230523125954-fcfab2575c4d github.com/tetratelabs/wazero v1.1.0 ) require golang.org/x/sys v0.6.0 // indirect -replace github.com/iden3/go-rapidsnark/witness => ../ +replace github.com/iden3/go-rapidsnark/witness/v2 => ../ From 2c28846a034f612deea16fb5f775d2d401a6bb00 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 23 May 2023 09:09:10 -0400 Subject: [PATCH 24/24] fix wazero/wasmer versions --- witness/test_wasm_impls/go.mod | 8 ++++---- witness/test_wasm_impls/witness_test.go | 4 ++-- witness/wasmer/go.mod | 2 +- witness/wazero/go.mod | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/witness/test_wasm_impls/go.mod b/witness/test_wasm_impls/go.mod index e69de41..723f778 100644 --- a/witness/test_wasm_impls/go.mod +++ b/witness/test_wasm_impls/go.mod @@ -4,8 +4,8 @@ go 1.18 require ( github.com/iden3/go-rapidsnark/witness/v2 v2.0.0-20230523125954-fcfab2575c4d - github.com/iden3/go-rapidsnark/witness/v2/wasmer v0.0.0 - github.com/iden3/go-rapidsnark/witness/v2/wazero v0.0.0 + github.com/iden3/go-rapidsnark/witness/wasmer v0.0.0 + github.com/iden3/go-rapidsnark/witness/wazero v0.0.0 github.com/stretchr/testify v1.8.2 ) @@ -22,6 +22,6 @@ require ( replace ( github.com/iden3/go-rapidsnark/witness/v2 => ../ - github.com/iden3/go-rapidsnark/witness/v2/wasmer => ../wasmer - github.com/iden3/go-rapidsnark/witness/v2/wazero => ../wazero + github.com/iden3/go-rapidsnark/witness/wasmer => ../wasmer + github.com/iden3/go-rapidsnark/witness/wazero => ../wazero ) diff --git a/witness/test_wasm_impls/witness_test.go b/witness/test_wasm_impls/witness_test.go index aa008b9..df8944e 100644 --- a/witness/test_wasm_impls/witness_test.go +++ b/witness/test_wasm_impls/witness_test.go @@ -8,8 +8,8 @@ import ( "testing" "github.com/iden3/go-rapidsnark/witness/v2" - "github.com/iden3/go-rapidsnark/witness/v2/wasmer" - "github.com/iden3/go-rapidsnark/witness/v2/wazero" + "github.com/iden3/go-rapidsnark/witness/wasmer" + "github.com/iden3/go-rapidsnark/witness/wazero" "github.com/stretchr/testify/require" ) diff --git a/witness/wasmer/go.mod b/witness/wasmer/go.mod index 753e144..1a05969 100644 --- a/witness/wasmer/go.mod +++ b/witness/wasmer/go.mod @@ -1,4 +1,4 @@ -module github.com/iden3/go-rapidsnark/witness/v2/wasmer +module github.com/iden3/go-rapidsnark/witness/wasmer go 1.18 diff --git a/witness/wazero/go.mod b/witness/wazero/go.mod index d81497d..73ad2e2 100644 --- a/witness/wazero/go.mod +++ b/witness/wazero/go.mod @@ -1,4 +1,4 @@ -module github.com/iden3/go-rapidsnark/witness/v2/wazero +module github.com/iden3/go-rapidsnark/witness/wazero go 1.18