diff --git a/contracts/src/FunctionGateway.sol b/contracts/src/FunctionGateway.sol index 7b83d30b2..dab6a1a22 100644 --- a/contracts/src/FunctionGateway.sol +++ b/contracts/src/FunctionGateway.sol @@ -58,7 +58,7 @@ contract FunctionGateway is IFunctionGateway, FunctionRegistry, TimelockedUpgrad uint256 _gasLimit, address _refundAccount ) public payable returns (bytes32) { - bytes32 inputHash = keccak256(_input); + bytes32 inputHash = sha256(_input); bytes32 contextHash = keccak256(_context); FunctionRequest memory r = FunctionRequest({ functionId: _functionId, diff --git a/contracts/test/FunctionGateway.t.sol b/contracts/test/FunctionGateway.t.sol index c842b5975..83be30260 100644 --- a/contracts/test/FunctionGateway.t.sol +++ b/contracts/test/FunctionGateway.t.sol @@ -58,7 +58,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr expectedRequest = FunctionRequest({ functionId: FUNCTION_ID, - inputHash: keccak256(REQUEST), + inputHash: sha256(REQUEST), outputHash: bytes32(0), contextHash: keccak256(CALLBACK_CONTEXT), callbackAddress: consumer, @@ -105,7 +105,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr ) = FunctionGateway(gateway).requests(requestId); assertEq(prevNonce + 1, FunctionGateway(gateway).nonce()); assertEq(FUNCTION_ID, functionId); - assertEq(keccak256(REQUEST), inputHash); + assertEq(sha256(REQUEST), inputHash); assertEq(bytes32(0), outputHash); assertEq(keccak256(CALLBACK_CONTEXT), contextHash); assertEq(address(consumer), callbackAddress); @@ -137,7 +137,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr ) = FunctionGateway(gateway).requests(requestId); assertEq(prevNonce + 1, FunctionGateway(gateway).nonce()); assertEq(FUNCTION_ID, functionId); - assertEq(keccak256(REQUEST), inputHash); + assertEq(sha256(REQUEST), inputHash); assertEq(bytes32(0), outputHash); assertEq(keccak256(CALLBACK_CONTEXT), contextHash); assertEq(address(consumer), callbackAddress); @@ -177,7 +177,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr ) = FunctionGateway(gateway).requests(requestId); assertEq(prevNonce + 1, FunctionGateway(gateway).nonce()); assertEq(FUNCTION_ID, functionId); - assertEq(keccak256(REQUEST), inputHash); + assertEq(sha256(REQUEST), inputHash); assertEq(bytes32(0), outputHash); assertEq(keccak256(CALLBACK_CONTEXT), contextHash); assertEq(address(consumer), callbackAddress); @@ -213,7 +213,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr ) = FunctionGateway(gateway).requests(requestId); assertEq(prevNonce + 1, FunctionGateway(gateway).nonce()); assertEq(FUNCTION_ID, functionId); - assertEq(keccak256(REQUEST), inputHash); + assertEq(sha256(REQUEST), inputHash); assertEq(REQUEST_OUTPUT_HASH, outputHash); assertEq(keccak256(CALLBACK_CONTEXT), contextHash); assertEq(address(consumer), callbackAddress); @@ -251,7 +251,7 @@ contract FunctionGatewayTest is Test, IFunctionGatewayEvents, IFunctionGatewayEr ) = FunctionGateway(gateway).requests(requestId); assertEq(prevNonce + 1, FunctionGateway(gateway).nonce()); assertEq(FUNCTION_ID, functionId); - assertEq(keccak256(REQUEST), inputHash); + assertEq(sha256(REQUEST), inputHash); assertEq(REQUEST_OUTPUT_HASH, outputHash); assertEq(keccak256(CALLBACK_CONTEXT), contextHash); assertEq(address(consumer), callbackAddress); diff --git a/gnarkx/builder/debug.go b/gnarkx/builder/debug.go index 2e74b3a40..3611b3f6b 100644 --- a/gnarkx/builder/debug.go +++ b/gnarkx/builder/debug.go @@ -12,3 +12,7 @@ func (a *API) PrintVarBytes(vars []vars.Byte) { } a.api.Println(fvars) } + +func (a *API) PrintU64(u64 vars.U64) { + a.api.Println(u64.Value) +} diff --git a/gnarkx/builder/inputs.go b/gnarkx/builder/inputs.go index 8dfd83030..75ec18dfc 100644 --- a/gnarkx/builder/inputs.go +++ b/gnarkx/builder/inputs.go @@ -36,3 +36,14 @@ func (r *InputReader) ReadBytes32() [32]vars.Byte { } return out } + +// ReadUint64 reads a uint64 in big-endian from the input stream. +func (r *InputReader) ReadUint64() vars.U64 { + out := vars.NewU64() + for i := 0; i < 8; i++ { + out = r.api.MulU64(out, vars.U64{Value: vars.Variable{Value: 256}}) + byte := r.readByte() + out = r.api.AddU64(out, vars.U64{Value: byte.Value}) + } + return out +} diff --git a/gnarkx/builder/outputs.go b/gnarkx/builder/outputs.go index 22147ac8a..4010a7a88 100644 --- a/gnarkx/builder/outputs.go +++ b/gnarkx/builder/outputs.go @@ -25,6 +25,12 @@ func NewOutputWriter(api API) *OutputWriter { // Writes a single u64 to the output stream. func (w *OutputWriter) WriteU64(i1 vars.U64) { bytes := w.api.ToBytes32FromU64LE(i1) + for i := 0; i < 8; i++ { + w.bytes = append(w.bytes, bytes[8-i-1]) + } +} + +func (w *OutputWriter) WriteBytes32(bytes [32]vars.Byte) { for i := 0; i < 32; i++ { w.bytes = append(w.bytes, bytes[i]) } diff --git a/gnarkx/builder/u64.go b/gnarkx/builder/u64.go index 1016a6b6c..94d4f7a36 100644 --- a/gnarkx/builder/u64.go +++ b/gnarkx/builder/u64.go @@ -33,6 +33,30 @@ func (a *API) AddU64(in ...vars.U64) vars.U64 { return vars.U64{Value: reduced} } +func (a *API) MulU64(in ...vars.U64) vars.U64 { + // Find the maximum number of bits needed to represent the product of all inputs. + nbTerms := len(in) + nbMaxBits := 64 * nbTerms + + // Compute the product of all inputs over the field. + acc := vars.ONE + for i := 0; i < len(in); i++ { + acc = a.Mul(acc, in[i].Value) + } + + // Convert the sum to binary with the calculated number of maximum bits. + bits := a.ToBinaryLE(acc, int(nbMaxBits)) + + // Compute acc % 2^64. + reduced := vars.ZERO + power := vars.ONE + for i := 0; i < 64; i++ { + reduced = a.Add(reduced, a.Mul(bits[i].Value, power)) + power = a.Mul(power, vars.TWO) + } + return vars.U64{Value: reduced} +} + // Converts a U64 to a Bytes32 in little-endian format. In particular, the u64 is decomposed into // bytes b1, ..., b8 such that 256^0 * b1 + ... + 256^7 * b8 is the native value. The bytes32 // returned is in the form [b1, ..., b8, 0, ..., 0]. diff --git a/gnarkx/hash/sha256/sha256.go b/gnarkx/hash/sha256/sha256.go index 4cbc3c8d4..8cd8ae57d 100644 --- a/gnarkx/hash/sha256/sha256.go +++ b/gnarkx/hash/sha256/sha256.go @@ -197,7 +197,7 @@ func Hash(api builder.API, in []vars.Byte) [32]vars.Byte { // Computes sha256(in) && ((1 << nbBits) - 1). func HashAndTruncate(api builder.API, in []vars.Byte, nbBits int) vars.Variable { // Compute the untruncated hash. - hash := Hash(api, in) + hash := vars.ReverseBytes32(Hash(api, in)) // Accumulate with byte digits until we get to the last relevant byte. acc := vars.ZERO diff --git a/gnarkx/succinct/build.go b/gnarkx/succinct/build.go new file mode 100644 index 000000000..cea3e9ad6 --- /dev/null +++ b/gnarkx/succinct/build.go @@ -0,0 +1,136 @@ +package succinct + +import ( + "fmt" + "os" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/backend/groth16" + "github.com/consensys/gnark/constraint" +) + +type CircuitBuild struct { + pk groth16.ProvingKey + vk groth16.VerifyingKey + r1cs constraint.ConstraintSystem +} + +// Export exports the R1CS, proving key, and verifying key to files. +func (build *CircuitBuild) Export() { + // Make build directory. + err := os.MkdirAll("build", 0755) + if err != nil { + fmt.Printf("Failed to create directory: %v\n", err) + return + } + + // Write R1CS. + r1csFile, err := os.Create("build/r1cs.bin") + if err != nil { + fmt.Println("Failed to create file:", err) + return + } + defer r1csFile.Close() + + _, err = build.r1cs.WriteTo(r1csFile) + if err != nil { + fmt.Println("Failed to write data:", err) + return + } + + // Create the proving key file. + pkFile, err := os.Create("build/pkey.bin") + if err != nil { + fmt.Println("Failed to create file:", err) + return + } + defer pkFile.Close() + + // Write proving key. + _, err = build.pk.WriteTo(pkFile) + if err != nil { + fmt.Println("Failed to write data:", err) + return + } + + // Write verification key. + vkFile, err := os.Create("build/vkey.bin") + if err != nil { + fmt.Println("Failed to create file:", err) + return + } + defer vkFile.Close() + + _, err = build.vk.WriteTo(vkFile) + if err != nil { + fmt.Println("Failed to write data:", err) + return + } + + // Write verifier smart contract into a file. + verifierFile, err := os.Create("build/FunctionVerifier.sol") + if err != nil { + fmt.Println("Failed to create file:", err) + return + } + defer verifierFile.Close() + + svk := &SuccinctVerifyingKey{VerifyingKey: build.vk} + err = svk.ExportIFunctionVerifierSolidity(verifierFile) + if err != nil { + fmt.Println("Failed to export solidity verifier:", err) + return + } + +} + +// ImportCircuitBuild imports the R1CS, proving key, and verifying key from files. +func ImportCircuitBuild() (*CircuitBuild, error) { + r1cs := groth16.NewCS(ecc.BN254) + + // Read the proving key file. + pkFile, err := os.Open("build/pkey.bin") + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer pkFile.Close() + + // Deserialize the proving key. + pk := groth16.NewProvingKey(ecc.BN254) + _, err = pk.ReadFrom(pkFile) + if err != nil { + return nil, fmt.Errorf("failed to read data: %w", err) + } + + vkFile, err := os.Open("build/vkey.bin") + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer vkFile.Close() + + // Deserialize the verifying key. + vk := groth16.NewVerifyingKey(ecc.BN254) + _, err = vk.ReadFrom(vkFile) + if err != nil { + return nil, fmt.Errorf("failed to read data: %w", err) + } + + // Read the R1CS file. + r1csFile, err := os.Open("build/r1cs.bin") + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer r1csFile.Close() + + // Deserialize the R1CS. + _, err = r1cs.ReadFrom(r1csFile) + if err != nil { + return nil, fmt.Errorf("failed to read data: %w", err) + } + + return &CircuitBuild{ + pk: pk, + vk: vk, + r1cs: r1cs, + }, nil +} diff --git a/gnarkx/succinct/circuit.go b/gnarkx/succinct/circuit.go index 8d65da14d..97ff05718 100644 --- a/gnarkx/succinct/circuit.go +++ b/gnarkx/succinct/circuit.go @@ -2,10 +2,8 @@ package succinct import ( "bytes" - "encoding/json" "fmt" "math/big" - "os" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend/groth16" @@ -63,7 +61,6 @@ func (f *CircuitFunction) SetWitness(inputBytes []byte) { // Set inputHash = sha256(inputBytes) && ((1 << 253) - 1). inputHash := sha256utils.HashAndTruncate(inputBytes, 253) - fmt.Println("inputHash", inputHash) f.InputHash.Set(inputHash) // Set outputHash = sha256(outputBytes) && ((1 << 253) - 1). @@ -90,134 +87,45 @@ func (f *CircuitFunction) Define(baseApi frontend.API) error { } // Build the circuit and serialize the r1cs, proving key, and verifying key to files. -func (circuit *CircuitFunction) Build() { +func (circuit *CircuitFunction) Build() (*CircuitBuild, error) { r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, circuit) if err != nil { - panic(err) + return nil, err } pk, vk, err := groth16.Setup(r1cs) if err != nil { - panic(err) - } - - // Make build directory. - err = os.MkdirAll("build", 0755) - if err != nil { - fmt.Printf("Failed to create directory: %v\n", err) - return - } - - // Write R1CS. - r1csFile, err := os.Create("build/r1cs.bin") - if err != nil { - fmt.Println("Failed to create file:", err) - return - } - defer r1csFile.Close() - - _, err = r1cs.WriteTo(r1csFile) - if err != nil { - fmt.Println("Failed to write data:", err) - return - } - - // Create the proving key file. - pkFile, err := os.Create("build/pkey.bin") - if err != nil { - fmt.Println("Failed to create file:", err) - return - } - defer pkFile.Close() - - // Write proving key. - _, err = pk.WriteTo(pkFile) - if err != nil { - fmt.Println("Failed to write data:", err) - return - } - - // Write verification key. - vkFile, err := os.Create("build/vkey.bin") - if err != nil { - fmt.Println("Failed to create file:", err) - return - } - defer vkFile.Close() - - _, err = vk.WriteTo(vkFile) - if err != nil { - fmt.Println("Failed to write data:", err) - return - } - - // Write verifier smart contract into a file. - verifierFile, err := os.Create("build/FunctionVerifier.sol") - if err != nil { - fmt.Println("Failed to create file:", err) - return - } - defer verifierFile.Close() - - svk := &SuccinctVerifyingKey{VerifyingKey: vk} - err = svk.ExportIFunctionVerifierSolidity(verifierFile) - if err != nil { - fmt.Println("Failed to export solidity verifier:", err) - return + return nil, err } + return &CircuitBuild{ + pk: pk, + vk: vk, + r1cs: r1cs, + }, nil } // Generates a proof for f(inputs, witness) = outputs based on a circuit. -func (f *CircuitFunction) Prove(inputBytes []byte) { - r1cs := groth16.NewCS(ecc.BN254) - - // Read the proving key file. - pkFile, err := os.Open("build/pkey.bin") - if err != nil { - panic(fmt.Errorf("failed to open file: %w", err)) - } - defer pkFile.Close() - - // Deserialize the proving key. - pk := groth16.NewProvingKey(ecc.BN254) - _, err = pk.ReadFrom(pkFile) - if err != nil { - panic(fmt.Errorf("failed to read data: %w", err)) - } - - // Read the R1CS file. - r1csFile, err := os.Open("build/r1cs.bin") - if err != nil { - panic(fmt.Errorf("failed to open file: %w", err)) - } - defer r1csFile.Close() - - // Deserialize the R1CS. - _, err = r1cs.ReadFrom(r1csFile) - if err != nil { - panic(fmt.Errorf("failed to read data: %w", err)) - } +func (f *CircuitFunction) Prove(inputBytes []byte, build *CircuitBuild) (*types.Groth16Proof, error) { // Register hints which are used for automatic constraint generation. solver.RegisterHint() - // Create the witness. + // Fill in the witness values. f.SetWitness(inputBytes) - // Calculate the rest of the witness. + // Calculate the actual witness. witness, err := frontend.NewWitness(f, ecc.BN254.ScalarField()) if err != nil { - panic(fmt.Errorf("failed to create witness: %w", err)) + return nil, fmt.Errorf("failed to create witness: %w", err) } // Generate the proof. - proof, err := groth16.Prove(r1cs, pk, witness) + proof, err := groth16.Prove(build.r1cs, build.pk, witness) if err != nil { - panic(fmt.Errorf("failed to generate proof: %w", err)) + return nil, fmt.Errorf("failed to generate proof: %w", err) } - // Write the proof to a JSON-compatible format. const fpSize = 4 * 8 var buf bytes.Buffer proof.WriteRawTo(&buf) @@ -232,22 +140,8 @@ func (f *CircuitFunction) Prove(inputBytes []byte) { output.C[0] = new(big.Int).SetBytes(proofBytes[fpSize*6 : fpSize*7]) output.C[1] = new(big.Int).SetBytes(proofBytes[fpSize*7 : fpSize*8]) - // Create the proof file. - proofFile, err := os.Create("proof.json") - if err != nil { - panic(fmt.Errorf("failed to create file: %w", err)) - } - defer proofFile.Close() + output.Input = inputBytes + output.Output = vars.GetValuesUnsafe(*f.Circuit.GetOutputBytes()) - // Marshal the proof to JSON. - jsonString, err := json.Marshal(output) - if err != nil { - panic(fmt.Errorf("failed to marshal output: %w", err)) - } - - // Write the proof to the file. - _, err = proofFile.Write(jsonString) - if err != nil { - panic(fmt.Errorf("failed to write data: %w", err)) - } + return output, nil } diff --git a/gnarkx/succinct/circuit_test.go b/gnarkx/succinct/circuit_test.go new file mode 100644 index 000000000..d560cc14e --- /dev/null +++ b/gnarkx/succinct/circuit_test.go @@ -0,0 +1,102 @@ +package succinct + +import ( + "bytes" + "encoding/hex" + "math/big" + "testing" + + "github.com/consensys/gnark/frontend" + "github.com/stretchr/testify/assert" + "github.com/succinctlabs/sdk/gnarkx/builder" + "github.com/succinctlabs/sdk/gnarkx/utils/byteutils" + "github.com/succinctlabs/sdk/gnarkx/vars" +) + +type TestCircuit struct { + InputBytes []vars.Byte + OutputBytes []vars.Byte +} + +var _ Circuit = (*TestCircuit)(nil) + +func NewTestCircuit() *TestCircuit { + return &TestCircuit{ + InputBytes: vars.NewBytes(16), + OutputBytes: vars.NewBytes(8), + } +} + +func (c *TestCircuit) GetInputBytes() *[]vars.Byte { + return &c.InputBytes +} + +func (c *TestCircuit) GetOutputBytes() *[]vars.Byte { + return &c.OutputBytes +} + +func (c *TestCircuit) Define(baseAPI frontend.API) error { + api := builder.NewAPI(baseAPI) + inputReader := builder.NewInputReader(*api, c.InputBytes) + + a := inputReader.ReadUint64() + b := inputReader.ReadUint64() + + outputWriter := builder.NewOutputWriter(*api) + + sum := api.AddU64(a, b) + + outputWriter.WriteU64(sum) + + outputWriter.Close(c.OutputBytes) + + return nil +} + +func (c *TestCircuit) SetWitness(inputBytes []byte) { + vars.SetBytes(&c.InputBytes, inputBytes) + + a := new(big.Int).SetBytes(inputBytes[:8]) + b := new(big.Int).SetBytes(inputBytes[8:]) + + sum := new(big.Int).Add(a, b) + outputBytes := make([]byte, 8) + sum.FillBytes(outputBytes) + + vars.SetBytes(&c.OutputBytes, outputBytes[:]) +} + +func TestSimpleCircuit(t *testing.T) { + c := NewCircuitFunction(NewTestCircuit()) + + build, err := c.Build() + assert.NoError(t, err) + + // 420, 69 + input, err := hex.DecodeString("00000000000001a40000000000000045") + assert.NoError(t, err) + + proof, err := c.Prove(input, build) + assert.NoError(t, err) + + // sha256(input) + expectedInputHash, err := hex.DecodeString("ae964f1e8905240278a7429d6573ba715baf3f4134693c94533ba8a7e57b636e") + // uint64(489) + expectedOutput, err := hex.DecodeString("00000000000001e9") + // sha256(uint64(489)) + expectedOutputHash, err := hex.DecodeString("080f024e0afaa2f4ed40a8bb08976d6c1bf771342a7ddec9de94a97c0598846a") + + // Truncate hashes to rightmost 253 bits as we would in Solidity + truncatedInputHash := byteutils.TruncateBytes32([32]byte(expectedInputHash), 253) + truncatedOutputHash := byteutils.TruncateBytes32([32]byte(expectedOutputHash), 253) + + resultInput := proof.Input + inputHash := c.InputHash.Value.(*big.Int).Bytes() + output := proof.Output + outputHash := c.OutputHash.Value.(*big.Int).Bytes() + + assert.True(t, bytes.Equal(input, resultInput)) + assert.True(t, bytes.Equal(inputHash, truncatedInputHash[:])) + assert.True(t, bytes.Equal(output, expectedOutput)) + assert.True(t, bytes.Equal(outputHash, truncatedOutputHash[:])) +} diff --git a/gnarkx/types/types.go b/gnarkx/types/types.go index 0b23b5881..27351af3c 100644 --- a/gnarkx/types/types.go +++ b/gnarkx/types/types.go @@ -1,7 +1,10 @@ package types import ( + "encoding/json" + "fmt" "math/big" + "os" "github.com/ethereum/go-ethereum/common/hexutil" ) @@ -10,6 +13,32 @@ type Groth16Proof struct { A [2]*big.Int `json:"a"` B [2][2]*big.Int `json:"b"` C [2]*big.Int `json:"c"` - Inputs []*big.Int `json:"inputs"` + Input hexutil.Bytes `json:"input"` Output hexutil.Bytes `json:"output"` } + +// Export saves the proof to a file. +func (g *Groth16Proof) Export(file string) error { + // Write the proof to a JSON-compatible format. + + // Create the proof file. + proofFile, err := os.Create(file) + if err != nil { + panic(fmt.Errorf("failed to create file: %w", err)) + } + defer proofFile.Close() + + // Marshal the proof to JSON. + jsonString, err := json.Marshal(g) + if err != nil { + panic(fmt.Errorf("failed to marshal output: %w", err)) + } + + // Write the proof to the file. + _, err = proofFile.Write(jsonString) + if err != nil { + panic(fmt.Errorf("failed to write data: %w", err)) + } + + return nil +} diff --git a/gnarkx/utils/byteutils/byteutils.go b/gnarkx/utils/byteutils/byteutils.go index 838fbfb32..4a19e86c4 100644 --- a/gnarkx/utils/byteutils/byteutils.go +++ b/gnarkx/utils/byteutils/byteutils.go @@ -1,5 +1,7 @@ package byteutils +import "math/big" + func ReverseBytes(data []byte) []byte { length := len(data) reversed := make([]byte, length) @@ -48,3 +50,12 @@ func ToBytes32FromBytesRightPad(data []byte) [32]byte { copy(res[:], data) return res } + +func TruncateBytes32(data [32]byte, nbBits int) [32]byte { + value := new(big.Int).SetBytes(data[:]) + mask := new(big.Int).Lsh(big.NewInt(1), uint(nbBits)) + mask.Sub(mask, big.NewInt(1)) + result := new(big.Int).And(value, mask) + out := make([]byte, 32) + return [32]byte(result.FillBytes(out)) +} diff --git a/gnarkx/utils/sha256utils/sha256utils.go b/gnarkx/utils/sha256utils/sha256utils.go index 8131a1c36..a5c76a17b 100644 --- a/gnarkx/utils/sha256utils/sha256utils.go +++ b/gnarkx/utils/sha256utils/sha256utils.go @@ -3,8 +3,6 @@ package sha256utils import ( "crypto/sha256" "math/big" - - "github.com/succinctlabs/sdk/gnarkx/utils/byteutils" ) // Computes sha256(data) & ((1 << nbBits) - 1)). @@ -17,7 +15,7 @@ func HashAndTruncate(data []byte, nbBits int) *big.Int { copy(bytes[:], h) // Convert the hash to a big.Int and truncate it to the lower nbBits. - value := new(big.Int).SetBytes(byteutils.ReverseBytes(bytes[:])) + value := new(big.Int).SetBytes(bytes[:]) mask := new(big.Int).Lsh(big.NewInt(1), uint(nbBits)) mask.Sub(mask, big.NewInt(1)) result := new(big.Int).And(value, mask) diff --git a/gnarkx/vars/byte.go b/gnarkx/vars/byte.go index 43c98368a..97961755e 100644 --- a/gnarkx/vars/byte.go +++ b/gnarkx/vars/byte.go @@ -102,6 +102,15 @@ func SetBytes32(b *[32]Byte, i1 [32]byte) { } } +// ReverseBytes32 returns a bytes32 with the bytes reversed. +func ReverseBytes32(b [32]Byte) [32]Byte { + var result [32]Byte + for i := 0; i < 32; i++ { + result[i] = b[32-i-1] + } + return result +} + // Creates a new bytes32 as a variable in a circuit from a u64. The u64 will placed in the first // 8 bytes of the bytes32 (aka "little endian"). func SetBytes32FromU64LE(b *[32]Byte, i1 uint64) { diff --git a/go.mod b/go.mod index fa6f61dd6..f1034e69b 100644 --- a/go.mod +++ b/go.mod @@ -7,26 +7,40 @@ require ( github.com/consensys/gnark-crypto v0.11.1-0.20230724160225-800ddb59f51b github.com/ethereum/go-ethereum v1.12.0 github.com/spf13/cobra v1.5.0 + github.com/stretchr/testify v1.8.4 ) require ( + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/bits-and-blooms/bitset v1.8.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect + github.com/go-ole/go-ole v1.2.1 // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/zerolog v1.30.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.8.4 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect github.com/x448/float16 v0.8.4 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/sys v0.10.0 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 061c142b1..600c5e942 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,21 @@ +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark v0.8.1-0.20230731090741-7ca4af9b9ad0 h1:sQQ8Vvl0KTtlGob0BzMSbnnCnUTRi5iLkQKsspe9iyM= @@ -12,19 +26,48 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 h1:ZgoomqkdjGbQ3+qQXCkvYMCDvGDNg2k5JJDjjdTB6jY= github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -33,35 +76,60 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=