From 215ce74cab0faeebe29e32d289b838006326b621 Mon Sep 17 00:00:00 2001 From: youben11 Date: Wed, 8 Nov 2023 15:33:36 +0100 Subject: [PATCH] tests: add tests previously used in geth --- fhevm/contracts_test.go | 3154 ++++++++++++++++++++++++++++++++++++ fhevm/instructions.go | 2 +- fhevm/instructions_test.go | 537 ++++++ go.mod | 36 + go.sum | 424 ++++- 5 files changed, 4151 insertions(+), 2 deletions(-) create mode 100644 fhevm/contracts_test.go create mode 100644 fhevm/instructions_test.go diff --git a/fhevm/contracts_test.go b/fhevm/contracts_test.go new file mode 100644 index 0000000..b4e1216 --- /dev/null +++ b/fhevm/contracts_test.go @@ -0,0 +1,3154 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package fhevm + +import ( + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" +) + +func init() { + // register errors from geth so that tests recognize them + RegisterErrors( + vm.ErrOutOfGas, + vm.ErrCodeStoreOutOfGas, + vm.ErrDepth, + vm.ErrInsufficientBalance, + vm.ErrContractAddressCollision, + vm.ErrExecutionReverted, + vm.ErrMaxInitCodeSizeExceeded, + vm.ErrMaxCodeSizeExceeded, + vm.ErrInvalidJump, + vm.ErrWriteProtection, + vm.ErrReturnDataOutOfBounds, + vm.ErrGasUintOverflow, + vm.ErrInvalidCode, + vm.ErrNonceUintOverflow, + nil, + nil, + nil, + ) +} + +func toPrecompileInput(isScalar bool, hashes ...common.Hash) []byte { + ret := make([]byte, 0) + for _, hash := range hashes { + ret = append(ret, hash.Bytes()...) + } + var isScalarByte byte + if isScalar { + isScalarByte = 1 + } else { + isScalarByte = 0 + } + ret = append(ret, isScalarByte) + return ret +} + +var scalarBytePadding = make([]byte, 31) + +func toLibPrecompileInput(method string, isScalar bool, hashes ...common.Hash) []byte { + ret := make([]byte, 0) + hashRes := crypto.Keccak256([]byte(method)) + signature := hashRes[0:4] + ret = append(ret, signature...) + for _, hash := range hashes { + ret = append(ret, hash.Bytes()...) + } + var isScalarByte byte + if isScalar { + isScalarByte = 1 + } else { + isScalarByte = 0 + } + ret = append(ret, isScalarByte) + ret = append(ret, scalarBytePadding...) + return ret +} + +func toLibPrecompileInputNoScalar(method string, hashes ...common.Hash) []byte { + ret := make([]byte, 0) + hashRes := crypto.Keccak256([]byte(method)) + signature := hashRes[0:4] + ret = append(ret, signature...) + for _, hash := range hashes { + ret = append(ret, hash.Bytes()...) + } + return ret +} + +func VerifyCiphertext(t *testing.T, fheUintType FheUintType) { + var value uint32 + switch fheUintType { + case FheUint8: + value = 2 + case FheUint16: + value = 4283 + case FheUint32: + value = 1333337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + compact := encryptAndSerializeCompact(value, fheUintType) + input := append(compact, byte(fheUintType)) + out, err := verifyCiphertextRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + ct := new(tfheCiphertext) + if err = ct.deserializeCompact(compact, fheUintType); err != nil { + t.Fatalf(err.Error()) + } + if common.BytesToHash(out) != ct.getHash() { + t.Fatalf("output hash in verifyCipertext is incorrect") + } + res := getVerifiedCiphertextFromEVM(environment, ct.getHash()) + if res == nil { + t.Fatalf("verifyCiphertext must have verified given ciphertext") + } +} + +func VerifyCiphertextBadType(t *testing.T, actualType FheUintType, metadataType FheUintType) { + var value uint32 + switch actualType { + case FheUint8: + value = 2 + case FheUint16: + value = 4283 + case FheUint32: + value = 1333337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + compact := encryptAndSerializeCompact(value, actualType) + input := append(compact, byte(metadataType)) + _, err := verifyCiphertextRun(environment, addr, addr, input, readOnly) + if err == nil { + t.Fatalf("verifyCiphertext must have failed on type mismatch") + } + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("verifyCiphertext mustn't have verified given ciphertext") + } +} + +func TrivialEncrypt(t *testing.T, fheUintType FheUintType) { + var value big.Int + switch fheUintType { + case FheUint8: + value = *big.NewInt(2) + case FheUint16: + value = *big.NewInt(4283) + case FheUint32: + value = *big.NewInt(1333337) + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + valueBytes := make([]byte, 32) + input := append(value.FillBytes(valueBytes), byte(fheUintType)) + out, err := trivialEncryptRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + ct := new(tfheCiphertext).trivialEncrypt(value, fheUintType) + if common.BytesToHash(out) != ct.getHash() { + t.Fatalf("output hash in verifyCipertext is incorrect") + } + res := getVerifiedCiphertextFromEVM(environment, ct.getHash()) + if res == nil { + t.Fatalf("verifyCiphertext must have verified given ciphertext") + } +} + +func FheLibAdd(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs + rhs + signature := "fheAdd(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibSub(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs - rhs + signature := "fheSub(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibMul(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 3 + rhs = 2 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs * rhs + signature := "fheMul(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibLe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + signature := "fheLe(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + // lhs <= rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs <= lhs + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + } +} + +func FheLibLt(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + signature := "fheLt(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + // lhs < rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs < lhs + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + } +} + +func FheLibEq(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + signature := "fheLt(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs == rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } +} + +func FheLibGe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + signature := "fheGe(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs >= rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs >= lhs + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + } +} + +func FheLibGt(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + signature := "fheGt(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs > rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs > lhs + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + } +} + +func FheLibShl(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 2 + case FheUint32: + lhs = 1333337 + rhs = 3 + } + expected := lhs << rhs + signature := "fheShl(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibShr(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 2 + case FheUint32: + lhs = 1333337 + rhs = 3 + } + expected := lhs >> rhs + signature := "fheShr(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibNe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + signature := "fheNe(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs == rhs + input1 := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } +} + +func FheLibMin(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + signature := "fheMin(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != rhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), rhs) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != rhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), rhs) + } + } +} + +func FheLibMax(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + signature := "fheMax(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != lhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), lhs) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + input2 := toLibPrecompileInput(signature, false, rhsHash, lhsHash) + out, err = FheLibRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != lhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), lhs) + } + } +} + +func FheLibNeg(t *testing.T, fheUintType FheUintType) { + var pt, expected uint64 + switch fheUintType { + case FheUint8: + pt = 2 + expected = uint64(-uint8(pt)) + case FheUint16: + pt = 4283 + expected = uint64(-uint16(pt)) + case FheUint32: + pt = 1333337 + expected = uint64(-uint32(pt)) + } + + signature := "fheNeg(uint256)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + ptHash := verifyCiphertextInTestMemory(environment, pt, depth, fheUintType).getHash() + + input := toLibPrecompileInputNoScalar(signature, ptHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibNot(t *testing.T, fheUintType FheUintType) { + var pt, expected uint64 + switch fheUintType { + case FheUint8: + pt = 2 + expected = uint64(^uint8(pt)) + case FheUint16: + pt = 4283 + expected = uint64(^uint16(pt)) + case FheUint32: + pt = 1333337 + expected = uint64(^uint32(pt)) + } + + signature := "fheNot(uint256)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + ptHash := verifyCiphertextInTestMemory(environment, pt, depth, fheUintType).getHash() + + input := toLibPrecompileInputNoScalar(signature, ptHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheLibDiv(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 4 + rhs = 2 + case FheUint16: + lhs = 721 + rhs = 1000 + case FheUint32: + lhs = 137 + rhs = 17 + } + expected := lhs / rhs + + signature := "fheDiv(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if scalar { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } else { + if err == nil { + t.Fatal("Non scalar multiplication should fail") + } + } +} + +func FheLibRem(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 7 + rhs = 3 + case FheUint16: + lhs = 721 + rhs = 1000 + case FheUint32: + lhs = 1337 + rhs = 73 + } + expected := lhs % rhs + signature := "fheRem(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if scalar { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } else { + if err == nil { + t.Fatal("Non scalar remainder should fail") + } + } +} + +func FheLibBitAnd(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs & rhs + signature := "fheBitAnd(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit and should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheLibBitOr(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs | rhs + signature := "fheBitOr(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit or should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheLibBitXor(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs ^ rhs + signature := "fheBitXor(uint256,uint256,bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toLibPrecompileInput(signature, scalar, lhsHash, rhsHash) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit xor should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheLibRand(t *testing.T, fheUintType FheUintType) { + signature := "fheRand(bytes1)" + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + input := make([]byte, 0) + input = append(input, signatureBytes...) + input = append(input, byte(fheUintType)) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } else if len(out) != 32 { + t.Fatalf("fheRand expected output len of 32, got %v", len(out)) + } + if len(environment.FhevmData().verifiedCiphertexts) != 1 { + t.Fatalf("fheRand expected 1 verified ciphertext") + } + + hash := common.BytesToHash(out) + _, err = environment.FhevmData().verifiedCiphertexts[hash].ciphertext.decrypt() + if err != nil { + t.Fatalf(err.Error()) + } +} + +func LibTrivialEncrypt(t *testing.T, fheUintType FheUintType) { + var value big.Int + switch fheUintType { + case FheUint8: + value = *big.NewInt(2) + case FheUint16: + value = *big.NewInt(4283) + case FheUint32: + value = *big.NewInt(1333337) + } + signature := "trivialEncrypt(uint256,bytes1)" + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + valueBytes := make([]byte, 32) + input := make([]byte, 0) + input = append(input, signatureBytes...) + input = append(input, value.FillBytes(valueBytes)...) + input = append(input, byte(fheUintType)) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + ct := new(tfheCiphertext).trivialEncrypt(value, fheUintType) + if common.BytesToHash(out) != ct.getHash() { + t.Fatalf("output hash in verifyCipertext is incorrect") + } + res := getVerifiedCiphertextFromEVM(environment, ct.getHash()) + if res == nil { + t.Fatalf("verifyCiphertext must have verified given ciphertext") + } +} + +func LibDecrypt(t *testing.T, fheUintType FheUintType) { + var value uint64 + switch fheUintType { + case FheUint8: + value = 2 + case FheUint16: + value = 4283 + case FheUint32: + value = 1333337 + } + signature := "decrypt(uint256)" + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + input := make([]byte, 0) + hash := verifyCiphertextInTestMemory(environment, value, depth, fheUintType).getHash() + input = append(input, signatureBytes...) + input = append(input, hash.Bytes()...) + out, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } else if len(out) != 32 { + t.Fatalf("decrypt expected output len of 32, got %v", len(out)) + } + result := big.Int{} + result.SetBytes(out) + if result.Uint64() != value { + t.Fatalf("decrypt result not equal to value, result %v != value %v", result.Uint64(), value) + } +} + +func TestLibVerifyCiphertextInvalidType(t *testing.T) { + signature := "verifyCiphertext(bytes)" + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + invalidType := FheUintType(255) + input := make([]byte, 0) + input = append(input, signatureBytes...) + compact := encryptAndSerializeCompact(0, FheUint32) + input = append(input, compact...) + input = append(input, byte(invalidType)) + _, err := FheLibRun(environment, addr, addr, input, readOnly) + if err == nil { + t.Fatalf("verifyCiphertext must have failed on invalid ciphertext type") + } + + if !strings.Contains(err.Error(), "ciphertext type is invalid") { + t.Fatalf("Unexpected test error: %s", err.Error()) + } +} + +func TestLibReencrypt(t *testing.T) { + signature := "reencrypt(uint256,uint256)" + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + environment.ethCall = true + toEncrypt := 7 + fheUintType := FheUint8 + encCiphertext := verifyCiphertextInTestMemory(environment, uint64(toEncrypt), depth, fheUintType).getHash() + addr := common.Address{} + readOnly := false + input := make([]byte, 0) + input = append(input, signatureBytes...) + input = append(input, encCiphertext.Bytes()...) + // just append twice not to generate public key + input = append(input, encCiphertext.Bytes()...) + _, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf("Reencrypt error: %s", err.Error()) + } +} + +func TestLibCast(t *testing.T) { + signature := "cast(uint256,bytes1)" + hashRes := crypto.Keccak256([]byte(signature)) + signatureBytes := hashRes[0:4] + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + environment.ethCall = true + toEncrypt := 7 + fheUintType := FheUint8 + encCiphertext := verifyCiphertextInTestMemory(environment, uint64(toEncrypt), depth, fheUintType).getHash() + addr := common.Address{} + readOnly := false + input := make([]byte, 0) + input = append(input, signatureBytes...) + input = append(input, encCiphertext.Bytes()...) + input = append(input, byte(FheUint32)) + _, err := FheLibRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf("Reencrypt error: %s", err.Error()) + } +} + +func FheAdd(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs + rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheAddRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheSub(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs - rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheSubRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheMul(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 169 + rhs = 5 + case FheUint32: + lhs = 137 + rhs = 17 + } + expected := lhs * rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheMulRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheDiv(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 4 + rhs = 2 + case FheUint16: + lhs = 721 + rhs = 1000 + case FheUint32: + lhs = 137 + rhs = 17 + } + expected := lhs / rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheDivRun(environment, addr, addr, input, readOnly) + if scalar { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } else { + if err == nil { + t.Fatal("Non scalar multiplication should fail") + } + } +} + +func FheRem(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 9 + rhs = 5 + case FheUint16: + lhs = 1773 + rhs = 523 + case FheUint32: + lhs = 123765 + rhs = 2179 + } + expected := lhs % rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheRemRun(environment, addr, addr, input, readOnly) + if scalar { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } else { + if err == nil { + t.Fatal("Non scalar remainder should fail") + } + } +} + +func FheBitAnd(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs & rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheBitAndRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit and should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheBitOr(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs | rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheBitOrRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit or should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheBitXor(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + expected := lhs ^ rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheBitXorRun(environment, addr, addr, input, readOnly) + if scalar { + if err == nil { + t.Fatalf("scalar bit xor should have failed") + } + } else { + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } + } +} + +func FheShl(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 2 + case FheUint32: + lhs = 1333337 + rhs = 3 + } + expected := lhs << rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheShlRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheShr(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 2 + case FheUint32: + lhs = 1333337 + rhs = 3 + } + expected := lhs >> rhs + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheShrRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheEq(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs == rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheEqRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } +} + +func FheNe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs == rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheNeRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } +} + +func FheGe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs >= rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheGeRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs >= lhs + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheGeRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + } +} + +func FheGt(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + // lhs > rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheGtRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs > lhs + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheGtRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + } +} + +func FheLe(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + // lhs <= rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheLeRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs <= lhs + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheLeRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + } +} + +func FheLt(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + // lhs < rhs + input1 := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheLtRun(environment, addr, addr, input1, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 0 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 0) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + // rhs < lhs + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheLtRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != 1 { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), 1) + } + } +} + +func FheMin(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheMinRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != rhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), rhs) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheMinRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != rhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), rhs) + } + } +} + +func FheMax(t *testing.T, fheUintType FheUintType, scalar bool) { + var lhs, rhs uint64 + switch fheUintType { + case FheUint8: + lhs = 2 + rhs = 1 + case FheUint16: + lhs = 4283 + rhs = 1337 + case FheUint32: + lhs = 1333337 + rhs = 133337 + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + lhsHash := verifyCiphertextInTestMemory(environment, lhs, depth, fheUintType).getHash() + var rhsHash common.Hash + if scalar { + rhsHash = common.BytesToHash(big.NewInt(int64(rhs)).Bytes()) + } else { + rhsHash = verifyCiphertextInTestMemory(environment, rhs, depth, fheUintType).getHash() + } + + input := toPrecompileInput(scalar, lhsHash, rhsHash) + out, err := fheMaxRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != lhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), lhs) + } + + // Inverting operands is only possible in the non scalar case as scalar + // operators expect the scalar to be on the rhs. + if !scalar { + input2 := toPrecompileInput(false, rhsHash, lhsHash) + out, err = fheMaxRun(environment, addr, addr, input2, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res = getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err = res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != lhs { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), lhs) + } + } +} + +func FheNeg(t *testing.T, fheUintType FheUintType, scalar bool) { + var pt, expected uint64 + switch fheUintType { + case FheUint8: + pt = 2 + expected = uint64(-uint8(pt)) + case FheUint16: + pt = 4283 + expected = uint64(-uint16(pt)) + case FheUint32: + pt = 1333337 + expected = uint64(-uint32(pt)) + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + ptHash := verifyCiphertextInTestMemory(environment, pt, depth, fheUintType).getHash() + + input := make([]byte, 0) + input = append(input, ptHash.Bytes()...) + out, err := fheNegRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func FheNot(t *testing.T, fheUintType FheUintType, scalar bool) { + var pt, expected uint64 + switch fheUintType { + case FheUint8: + pt = 2 + expected = uint64(^uint8(pt)) + case FheUint16: + pt = 4283 + expected = uint64(^uint16(pt)) + case FheUint32: + pt = 1333337 + expected = uint64(^uint32(pt)) + } + + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + ptHash := verifyCiphertextInTestMemory(environment, pt, depth, fheUintType).getHash() + + input := make([]byte, 0) + input = append(input, ptHash.Bytes()...) + out, err := fheNotRun(environment, addr, addr, input, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } + res := getVerifiedCiphertextFromEVM(environment, common.BytesToHash(out)) + if res == nil { + t.Fatalf("output ciphertext is not found in verifiedCiphertexts") + } + decrypted, err := res.ciphertext.decrypt() + if err != nil || decrypted.Uint64() != expected { + t.Fatalf("invalid decrypted result, decrypted %v != expected %v", decrypted.Uint64(), expected) + } +} + +func Decrypt(t *testing.T, fheUintType FheUintType) { + var value uint64 + switch fheUintType { + case FheUint8: + value = 2 + case FheUint16: + value = 4283 + case FheUint32: + value = 1333337 + } + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + hash := verifyCiphertextInTestMemory(environment, value, depth, fheUintType).getHash() + out, err := decryptRun(environment, addr, addr, hash.Bytes(), readOnly) + if err != nil { + t.Fatalf(err.Error()) + } else if len(out) != 32 { + t.Fatalf("decrypt expected output len of 32, got %v", len(out)) + } + result := big.Int{} + result.SetBytes(out) + if result.Uint64() != value { + t.Fatalf("decrypt result not equal to value, result %v != value %v", result.Uint64(), value) + } +} + +func FheRand(t *testing.T, fheUintType FheUintType) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + out, err := fheRandRun(environment, addr, addr, []byte{byte(fheUintType)}, readOnly) + if err != nil { + t.Fatalf(err.Error()) + } else if len(out) != 32 { + t.Fatalf("fheRand expected output len of 32, got %v", len(out)) + } + if len(environment.FhevmData().verifiedCiphertexts) != 1 { + t.Fatalf("fheRand expected 1 verified ciphertext") + } + + hash := common.BytesToHash(out) + _, err = environment.FhevmData().verifiedCiphertexts[hash].ciphertext.decrypt() + if err != nil { + t.Fatalf(err.Error()) + } +} + +func TestVerifyCiphertextInvalidType(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + invalidType := FheUintType(255) + compact := encryptAndSerializeCompact(0, FheUint32) + input := append(compact, byte(invalidType)) + _, err := verifyCiphertextRun(environment, addr, addr, input, readOnly) + if err == nil { + t.Fatalf("verifyCiphertext must have failed on invalid ciphertext type") + } +} + +func TestTrivialEncryptInvalidType(t *testing.T) { + // TODO: maybe trivialEncryptRun shouldn't panic but return an error? + defer func() { + if r := recover(); r == nil { + t.Fatalf("trivialEncrypt must have failed (panic) on invalid ciphertext type") + } + }() + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + invalidType := FheUintType(255) + input := make([]byte, 32) + input = append(input, byte(invalidType)) + trivialEncryptRun(environment, addr, addr, input, readOnly) +} + +func TestCastInvalidType(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + invalidType := FheUintType(255) + hash := verifyCiphertextInTestMemory(environment, 1, depth, FheUint8).getHash() + input := make([]byte, 0) + input = append(input, hash.Bytes()...) + input = append(input, byte(invalidType)) + _, err := castRun(environment, addr, addr, input, readOnly) + if err == nil { + t.Fatalf("cast must have failed on invalid ciphertext type") + } +} + +func TestVerifyCiphertextInvalidSize(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + ctType := FheUint32 + compact := encryptAndSerializeCompact(0, ctType) + input := append(compact[:len(compact)-1], byte(ctType)) + _, err := verifyCiphertextRun(environment, addr, addr, input, readOnly) + if err == nil { + t.Fatalf("verifyCiphertext must have failed on invalid ciphertext size") + } +} + +func TestVerifyCiphertext8(t *testing.T) { + VerifyCiphertext(t, FheUint8) +} + +func TestVerifyCiphertext16(t *testing.T) { + VerifyCiphertext(t, FheUint16) +} + +func TestVerifyCiphertext32(t *testing.T) { + VerifyCiphertext(t, FheUint32) +} + +func TestTrivialEncrypt8(t *testing.T) { + TrivialEncrypt(t, FheUint8) +} + +func TestTrivialEncrypt16(t *testing.T) { + TrivialEncrypt(t, FheUint16) +} + +func TestTrivialEncrypt32(t *testing.T) { + TrivialEncrypt(t, FheUint32) +} + +func TestVerifyCiphertext8BadType(t *testing.T) { + VerifyCiphertextBadType(t, FheUint8, FheUint16) + VerifyCiphertextBadType(t, FheUint8, FheUint32) +} + +func TestVerifyCiphertext16BadType(t *testing.T) { + VerifyCiphertextBadType(t, FheUint16, FheUint8) + VerifyCiphertextBadType(t, FheUint16, FheUint32) +} + +func TestVerifyCiphertext32BadType(t *testing.T) { + VerifyCiphertextBadType(t, FheUint32, FheUint8) + VerifyCiphertextBadType(t, FheUint32, FheUint16) +} + +func TestVerifyCiphertextBadCiphertext(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + _, err := verifyCiphertextRun(environment, addr, addr, make([]byte, 10), readOnly) + if err == nil { + t.Fatalf("verifyCiphertext must fail on bad ciphertext input") + } + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("verifyCiphertext mustn't have verified given ciphertext") + } +} + +func TestFheLibAdd8(t *testing.T) { + FheLibAdd(t, FheUint8, false) +} + +func TestFheLibSub8(t *testing.T) { + FheLibSub(t, FheUint8, false) +} + +func TestFheLibMul8(t *testing.T) { + FheLibMul(t, FheUint8, false) +} + +func TestFheLibLe8(t *testing.T) { + FheLibLe(t, FheUint8, false) +} + +func TestFheLibLt8(t *testing.T) { + FheLibLt(t, FheUint8, false) +} + +func TestFheLibEq8(t *testing.T) { + FheLibEq(t, FheUint8, false) +} + +func TestFheLibGe8(t *testing.T) { + FheLibGe(t, FheUint8, false) +} + +func TestFheLibGt8(t *testing.T) { + FheLibGt(t, FheUint8, false) +} + +func TestFheLibShl8(t *testing.T) { + FheLibShl(t, FheUint8, false) +} + +func TestFheLibShr8(t *testing.T) { + FheLibShr(t, FheUint8, false) +} + +func TestFheLibNe8(t *testing.T) { + FheLibNe(t, FheUint8, false) +} + +func TestFheLibMin8(t *testing.T) { + FheLibMin(t, FheUint8, false) +} + +func TestFheLibMax8(t *testing.T) { + FheLibMax(t, FheUint8, false) +} + +func TestFheLibNeg8(t *testing.T) { + FheLibNeg(t, FheUint8) +} + +func TestFheLibNot8(t *testing.T) { + FheLibNot(t, FheUint8) +} + +func TestFheLibDiv8(t *testing.T) { + FheLibDiv(t, FheUint8, true) +} + +func TestFheLibRem8(t *testing.T) { + FheLibRem(t, FheUint8, true) +} + +func TestFheLibBitAnd8(t *testing.T) { + FheLibBitAnd(t, FheUint8, false) +} + +func TestFheLibBitOr8(t *testing.T) { + FheLibBitOr(t, FheUint8, false) +} + +func TestFheLibBitXor8(t *testing.T) { + FheLibBitXor(t, FheUint8, false) +} + +func TestFheLibRand8(t *testing.T) { + FheLibRand(t, FheUint8) +} + +func TestFheLibTrivialEncrypt8(t *testing.T) { + LibTrivialEncrypt(t, FheUint8) +} + +func TestLibDecrypt8(t *testing.T) { + LibDecrypt(t, FheUint8) +} + +func TestFheAdd8(t *testing.T) { + FheAdd(t, FheUint8, false) +} + +func TestFheAdd16(t *testing.T) { + FheAdd(t, FheUint16, false) +} + +func TestFheAdd32(t *testing.T) { + FheAdd(t, FheUint32, false) +} + +func TestFheScalarAdd8(t *testing.T) { + FheAdd(t, FheUint8, true) +} + +func TestFheScalarAdd16(t *testing.T) { + FheAdd(t, FheUint16, true) +} + +func TestFheScalarAdd32(t *testing.T) { + FheAdd(t, FheUint32, true) +} + +func TestFheSub8(t *testing.T) { + FheSub(t, FheUint8, false) +} + +func TestFheSub16(t *testing.T) { + FheSub(t, FheUint16, false) +} + +func TestFheSub32(t *testing.T) { + FheSub(t, FheUint32, false) +} + +func TestFheScalarSub8(t *testing.T) { + FheSub(t, FheUint8, true) +} + +func TestFheScalarSub16(t *testing.T) { + FheSub(t, FheUint16, true) +} + +func TestFheScalarSub32(t *testing.T) { + FheSub(t, FheUint32, true) +} + +func TestFheMul8(t *testing.T) { + FheMul(t, FheUint8, false) +} + +func TestFheMul16(t *testing.T) { + FheMul(t, FheUint16, false) +} + +func TestFheMul32(t *testing.T) { + FheMul(t, FheUint32, false) +} + +func TestFheScalarMul8(t *testing.T) { + FheMul(t, FheUint8, true) +} + +func TestFheScalarMul16(t *testing.T) { + FheMul(t, FheUint16, true) +} + +func TestFheScalarMul32(t *testing.T) { + FheMul(t, FheUint32, true) +} + +func TestFheDiv8(t *testing.T) { + FheDiv(t, FheUint8, false) +} + +func TestFheDiv16(t *testing.T) { + FheDiv(t, FheUint16, false) +} + +func TestFheDiv32(t *testing.T) { + FheDiv(t, FheUint32, false) +} + +func TestFheScalarDiv8(t *testing.T) { + FheDiv(t, FheUint8, true) +} + +func TestFheScalarDiv16(t *testing.T) { + FheDiv(t, FheUint16, true) +} + +func TestFheScalarDiv32(t *testing.T) { + FheDiv(t, FheUint32, true) +} + +func TestFheRem8(t *testing.T) { + FheRem(t, FheUint8, false) +} + +func TestFheRem16(t *testing.T) { + FheRem(t, FheUint16, false) +} + +func TestFheRem32(t *testing.T) { + FheRem(t, FheUint32, false) +} + +func TestFheScalarRem8(t *testing.T) { + FheRem(t, FheUint8, true) +} + +func TestFheScalarRem16(t *testing.T) { + FheRem(t, FheUint16, true) +} + +func TestFheScalarRem32(t *testing.T) { + FheRem(t, FheUint32, true) +} + +func TestFheBitAnd8(t *testing.T) { + FheBitAnd(t, FheUint8, false) +} + +func TestFheBitAnd16(t *testing.T) { + FheBitAnd(t, FheUint16, false) +} + +func TestFheBitAnd32(t *testing.T) { + FheBitAnd(t, FheUint32, false) +} + +func TestFheScalarBitAnd8(t *testing.T) { + FheBitAnd(t, FheUint8, true) +} + +func TestFheScalarBitAnd16(t *testing.T) { + FheBitAnd(t, FheUint16, true) +} + +func TestFheScalarBitAnd32(t *testing.T) { + FheBitAnd(t, FheUint32, true) +} + +func TestFheBitOr8(t *testing.T) { + FheBitOr(t, FheUint8, false) +} + +func TestFheBitOr16(t *testing.T) { + FheBitOr(t, FheUint16, false) +} + +func TestFheBitOr32(t *testing.T) { + FheBitOr(t, FheUint32, false) +} + +func TestFheScalarBitOr8(t *testing.T) { + FheBitOr(t, FheUint8, true) +} + +func TestFheScalarBitOr16(t *testing.T) { + FheBitOr(t, FheUint16, true) +} + +func TestFheScalarBitOr32(t *testing.T) { + FheBitOr(t, FheUint32, true) +} + +func TestFheBitXor8(t *testing.T) { + FheBitXor(t, FheUint8, false) +} + +func TestFheBitXor16(t *testing.T) { + FheBitXor(t, FheUint16, false) +} + +func TestFheBitXor32(t *testing.T) { + FheBitXor(t, FheUint32, false) +} + +func TestFheScalarBitXor8(t *testing.T) { + FheBitXor(t, FheUint8, true) +} + +func TestFheScalarBitXor16(t *testing.T) { + FheBitXor(t, FheUint16, true) +} + +func TestFheScalarBitXor32(t *testing.T) { + FheBitXor(t, FheUint32, true) +} + +func TestFheShl8(t *testing.T) { + FheShl(t, FheUint8, false) +} + +func TestFheShl16(t *testing.T) { + FheShl(t, FheUint16, false) +} + +func TestFheShl32(t *testing.T) { + FheShl(t, FheUint32, false) +} + +func TestFheScalarShl8(t *testing.T) { + FheShl(t, FheUint8, true) +} + +func TestFheScalarShl16(t *testing.T) { + FheShl(t, FheUint16, true) +} + +func TestFheScalarShl32(t *testing.T) { + FheShl(t, FheUint32, true) +} + +func TestFheShr8(t *testing.T) { + FheShr(t, FheUint8, false) +} + +func TestFheShr16(t *testing.T) { + FheShr(t, FheUint16, false) +} + +func TestFheShr32(t *testing.T) { + FheShr(t, FheUint32, false) +} + +func TestFheScalarShr8(t *testing.T) { + FheShr(t, FheUint8, true) +} + +func TestFheScalarShr16(t *testing.T) { + FheShr(t, FheUint16, true) +} + +func TestFheScalarShr32(t *testing.T) { + FheShr(t, FheUint32, true) +} + +func TestFheEq8(t *testing.T) { + FheEq(t, FheUint8, false) +} + +func TestFheEq16(t *testing.T) { + FheEq(t, FheUint16, false) +} + +func TestFheEq32(t *testing.T) { + FheEq(t, FheUint32, false) +} + +func TestFheScalarEq8(t *testing.T) { + FheEq(t, FheUint8, true) +} + +func TestFheScalarEq16(t *testing.T) { + FheEq(t, FheUint16, true) +} + +func TestFheScalarEq32(t *testing.T) { + FheEq(t, FheUint32, true) +} + +func TestFheNe8(t *testing.T) { + FheNe(t, FheUint8, false) +} + +func TestFheNe16(t *testing.T) { + FheNe(t, FheUint16, false) +} + +func TestFheNe32(t *testing.T) { + FheNe(t, FheUint32, false) +} + +func TestFheScalarNe8(t *testing.T) { + FheNe(t, FheUint8, true) +} + +func TestFheScalarNe16(t *testing.T) { + FheNe(t, FheUint16, true) +} + +func TestFheScalarNe32(t *testing.T) { + FheNe(t, FheUint32, true) +} + +func TestFheGe8(t *testing.T) { + FheGe(t, FheUint8, false) +} + +func TestFheGe16(t *testing.T) { + FheGe(t, FheUint16, false) +} + +func TestFheGe32(t *testing.T) { + FheGe(t, FheUint32, false) +} + +func TestFheScalarGe8(t *testing.T) { + FheGe(t, FheUint8, true) +} + +func TestFheScalarGe16(t *testing.T) { + FheGe(t, FheUint16, true) +} + +func TestFheScalarGe32(t *testing.T) { + FheGe(t, FheUint32, true) +} + +func TestFheGt8(t *testing.T) { + FheGt(t, FheUint8, false) +} + +func TestFheGt16(t *testing.T) { + FheGt(t, FheUint16, false) +} + +func TestFheGt32(t *testing.T) { + FheGt(t, FheUint32, false) +} + +func TestFheScalarGt8(t *testing.T) { + FheGt(t, FheUint8, true) +} + +func TestFheScalarGt16(t *testing.T) { + FheGt(t, FheUint16, true) +} + +func TestFheScalarGt32(t *testing.T) { + FheGt(t, FheUint32, true) +} + +func TestFheLe8(t *testing.T) { + FheLe(t, FheUint8, false) +} + +func TestFheLe16(t *testing.T) { + FheLe(t, FheUint16, false) +} + +func TestFheLe32(t *testing.T) { + FheLe(t, FheUint32, false) +} + +func TestFheScalarLe8(t *testing.T) { + FheLe(t, FheUint8, true) +} + +func TestFheScalarLe16(t *testing.T) { + FheLe(t, FheUint16, true) +} + +func TestFheScalarLe32(t *testing.T) { + FheLe(t, FheUint32, true) +} + +func TestFheLt8(t *testing.T) { + FheLt(t, FheUint8, false) +} + +func TestFheLt16(t *testing.T) { + FheLt(t, FheUint16, false) +} + +func TestFheLt32(t *testing.T) { + FheLt(t, FheUint32, false) +} + +func TestFheScalarLt8(t *testing.T) { + FheLt(t, FheUint8, true) +} + +func TestFheScalarLt16(t *testing.T) { + FheLt(t, FheUint16, true) +} + +func TestFheScalarLt32(t *testing.T) { + FheLt(t, FheUint32, true) +} + +func TestFheMin8(t *testing.T) { + FheMin(t, FheUint8, false) +} + +func TestFheMin16(t *testing.T) { + FheMin(t, FheUint16, false) +} + +func TestFheMin32(t *testing.T) { + FheMin(t, FheUint32, false) +} + +func TestFheScalarMin8(t *testing.T) { + FheMin(t, FheUint8, true) +} + +func TestFheScalarMin16(t *testing.T) { + FheMin(t, FheUint16, true) +} + +func TestFheScalarMin32(t *testing.T) { + FheMin(t, FheUint32, true) +} + +func TestFheMax8(t *testing.T) { + FheMax(t, FheUint8, false) +} + +func TestFheMax16(t *testing.T) { + FheMax(t, FheUint16, false) +} + +func TestFheMax32(t *testing.T) { + FheMax(t, FheUint32, false) +} + +func TestFheNeg8(t *testing.T) { + FheNeg(t, FheUint8, false) +} + +func TestFheNeg16(t *testing.T) { + FheNeg(t, FheUint16, false) +} + +func TestFheNeg32(t *testing.T) { + FheNeg(t, FheUint32, false) +} + +func TestFheNot8(t *testing.T) { + FheNot(t, FheUint8, false) +} + +func TestFheNot16(t *testing.T) { + FheNot(t, FheUint16, false) +} + +func TestFheNot32(t *testing.T) { + FheNot(t, FheUint32, false) +} + +func TestFheScalarMax8(t *testing.T) { + FheMax(t, FheUint8, true) +} + +func TestFheScalarMax16(t *testing.T) { + FheMax(t, FheUint16, true) +} + +func TestFheScalarMax32(t *testing.T) { + FheMax(t, FheUint32, true) +} + +func TestDecrypt8(t *testing.T) { + Decrypt(t, FheUint8) +} + +func TestDecrypt16(t *testing.T) { + Decrypt(t, FheUint16) +} + +func TestDecrypt32(t *testing.T) { + Decrypt(t, FheUint32) +} + +func TestFheRand8(t *testing.T) { + FheRand(t, FheUint8) +} + +func TestFheRand16(t *testing.T) { + FheRand(t, FheUint16) +} + +func TestFheRand32(t *testing.T) { + FheRand(t, FheUint32) +} + +func TestUnknownCiphertextHandle(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + hash := verifyCiphertextInTestMemory(environment, 2, depth, FheUint8).getHash() + + ct := getVerifiedCiphertext(environment, hash) + if ct == nil { + t.Fatalf("expected that ciphertext is verified") + } + + // change the hash + hash[0]++ + ct = getVerifiedCiphertext(environment, hash) + if ct != nil { + t.Fatalf("expected that ciphertext is not verified") + } +} + +func TestCiphertextNotVerifiedWithoutReturn(t *testing.T) { + environment := newTestEVMEnvironment() + environment.depth = 1 + verifiedDepth := 2 + hash := verifyCiphertextInTestMemory(environment, 1, verifiedDepth, FheUint8).getHash() + + ct := getVerifiedCiphertext(environment, hash) + if ct != nil { + t.Fatalf("expected that ciphertext is not verified") + } +} + +func TestCiphertextNotAutomaticallyDelegated(t *testing.T) { + environment := newTestEVMEnvironment() + environment.depth = 3 + verifiedDepth := 2 + hash := verifyCiphertextInTestMemory(environment, 1, verifiedDepth, FheUint8).getHash() + + ct := getVerifiedCiphertext(environment, hash) + if ct != nil { + t.Fatalf("expected that ciphertext is not verified at depth (%d)", environment.depth) + } +} + +func TestCiphertextVerificationConditions(t *testing.T) { + environment := newTestEVMEnvironment() + verifiedDepth := 2 + hash := verifyCiphertextInTestMemory(environment, 1, verifiedDepth, FheUint8).getHash() + + environment.depth = verifiedDepth + ctPtr := getVerifiedCiphertext(environment, hash) + if ctPtr == nil { + t.Fatalf("expected that ciphertext is verified at verifiedDepth (%d)", verifiedDepth) + } + + environment.depth = verifiedDepth + 1 + ct := getVerifiedCiphertext(environment, hash) + if ct != nil { + t.Fatalf("expected that ciphertext is not verified at verifiedDepth + 1 (%d)", verifiedDepth+1) + } + + environment.depth = verifiedDepth - 1 + ct = getVerifiedCiphertext(environment, hash) + if ct != nil { + t.Fatalf("expected that ciphertext is not verified at verifiedDepth - 1 (%d)", verifiedDepth-1) + } +} + +func TestFheRandInvalidInput(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + _, err := fheRandRun(environment, addr, addr, []byte{}, readOnly) + if err == nil { + t.Fatalf("fheRand expected failure on invalid type") + } + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("fheRand expected 0 verified ciphertexts on invalid input") + } +} + +func TestFheRandInvalidType(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + addr := common.Address{} + readOnly := false + _, err := fheRandRun(environment, addr, addr, []byte{byte(254)}, readOnly) + if err == nil { + t.Fatalf("fheRand expected failure on invalid type") + } + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("fheRand expected 0 verified ciphertexts on invalid type") + } +} + +func TestFheRandEthCall(t *testing.T) { + depth := 1 + environment := newTestEVMEnvironment() + environment.depth = depth + environment.ethCall = true + addr := common.Address{} + readOnly := true + _, err := fheRandRun(environment, addr, addr, []byte{byte(FheUint8)}, readOnly) + if err == nil { + t.Fatalf("fheRand expected failure on EthCall") + } + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("fheRand expected 0 verified ciphertexts on EthCall") + } +} diff --git a/fhevm/instructions.go b/fhevm/instructions.go index 643c104..f2a08a1 100644 --- a/fhevm/instructions.go +++ b/fhevm/instructions.go @@ -13,7 +13,7 @@ import ( fhevm_crypto "github.com/zama-ai/fhevm-go/crypto" ) -var zero = uint256.NewInt(0).Bytes32() +var zero = common.BytesToHash(uint256.NewInt(0).Bytes()) func newInt(buf []byte) *uint256.Int { i := uint256.NewInt(0) diff --git a/fhevm/instructions_test.go b/fhevm/instructions_test.go new file mode 100644 index 0000000..efa2f23 --- /dev/null +++ b/fhevm/instructions_test.go @@ -0,0 +1,537 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package fhevm + +import ( + "bytes" + "math/big" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/holiman/uint256" + fhevm_crypto "github.com/zama-ai/fhevm-go/crypto" +) + +func init() { + // register errors from geth so that tests recognize them + RegisterErrors( + vm.ErrOutOfGas, + vm.ErrCodeStoreOutOfGas, + vm.ErrDepth, + vm.ErrInsufficientBalance, + vm.ErrContractAddressCollision, + vm.ErrExecutionReverted, + vm.ErrMaxInitCodeSizeExceeded, + vm.ErrMaxCodeSizeExceeded, + vm.ErrInvalidJump, + vm.ErrWriteProtection, + vm.ErrReturnDataOutOfBounds, + vm.ErrGasUintOverflow, + vm.ErrInvalidCode, + vm.ErrNonceUintOverflow, + nil, + nil, + nil, + ) +} + +func verifyCiphertextInTestMemory(environment EVMEnvironment, value uint64, depth int, t FheUintType) *tfheCiphertext { + // Simulate as if the ciphertext is compact and comes externally. + ser := encryptAndSerializeCompact(uint32(value), t) + ct := new(tfheCiphertext) + err := ct.deserializeCompact(ser, t) + if err != nil { + panic(err) + } + return verifyTfheCiphertextInTestMemory(environment, ct, depth) +} + +func verifyTfheCiphertextInTestMemory(environment EVMEnvironment, ct *tfheCiphertext, depth int) *tfheCiphertext { + verifiedCiphertext := importCiphertextToEVMAtDepth(environment, ct, depth) + return verifiedCiphertext.ciphertext +} + +// Implementation of some geth data structures used for testing + +var stackPool = sync.Pool{ + New: func() interface{} { + return &TestStack{data: make([]uint256.Int, 0, 16)} + }, +} + +type TestStack struct { + data []uint256.Int +} + +func newstack() *TestStack { + return stackPool.Get().(*TestStack) +} + +// Data returns the underlying uint256.Int array. +func (st *TestStack) Data() []uint256.Int { + return st.data +} + +func (st *TestStack) push(d *uint256.Int) { + // NOTE push limit (1024) is checked in baseCheck + st.data = append(st.data, *d) +} + +func (st *TestStack) pop() (ret uint256.Int) { + ret = st.data[len(st.data)-1] + st.data = st.data[:len(st.data)-1] + return +} + +func (st *TestStack) len() int { + return len(st.data) +} + +func (st *TestStack) peek() *uint256.Int { + return &st.data[st.len()-1] +} + +// Back returns the n'th item in stack +func (st *TestStack) Back(n int) *uint256.Int { + return &st.data[st.len()-n-1] +} + +func (st *TestStack) Peek() *uint256.Int { return st.peek() } + +func (st *TestStack) Pop() uint256.Int { return st.pop() } + +type TestScopeContext struct { + Memory *vm.Memory + Stack *TestStack + Contract *vm.Contract +} + +type TestScopeContextInterface interface { + ScopeContext + pushToStack(*uint256.Int) +} + +func (scope *TestScopeContext) GetContract() Contract { return scope.Contract } +func (scope *TestScopeContext) GetMemory() Memory { return scope.Memory } +func (scope *TestScopeContext) GetStack() Stack { return scope.Stack } +func (scope *TestScopeContext) pushToStack(v *uint256.Int) { scope.Stack.push(v) } + +type testContractAddress struct{} + +func (c testContractAddress) Address() common.Address { + return common.Address{} +} + +type testCallerAddress struct{} + +func (c testCallerAddress) Address() common.Address { + addr := common.Address{} + addr[0]++ + return addr +} + +func newTestScopeConext() TestScopeContextInterface { + c := new(TestScopeContext) + c.Memory = vm.NewMemory() + c.Memory.Resize(uint64(expandedFheCiphertextSize[FheUint8]) * 3) + c.Stack = newstack() + c.Contract = vm.NewContract(testCallerAddress{}, testContractAddress{}, big.NewInt(10), 100000) + return c +} + +func uint256FromBig(b *big.Int) *uint256.Int { + value, overflow := uint256.FromBig(b) + if overflow { + panic("overflow") + } + return value +} + +type MockEVMEnvironment struct { + fhevmData *FhevmData + depth int + stateDb *state.StateDB + commit bool + ethCall bool + readOnly bool +} + +func (environment *MockEVMEnvironment) GetState(addr common.Address, hash common.Hash) common.Hash { + return environment.stateDb.GetState(addr, hash) +} + +func (environment *MockEVMEnvironment) SetState(addr common.Address, key common.Hash, value common.Hash) { + environment.stateDb.SetState(addr, key, value) +} + +func (environment *MockEVMEnvironment) GetNonce(common.Address) uint64 { + return 0 +} + +func (environment *MockEVMEnvironment) AddBalance(addr common.Address, amount *big.Int) { + environment.stateDb.AddBalance(addr, amount) +} + +func (environment *MockEVMEnvironment) GetBalance(addr common.Address) *big.Int { + return environment.stateDb.GetBalance(addr) +} + +func (environment *MockEVMEnvironment) Suicide(addr common.Address) bool { + return environment.stateDb.Suicide(addr) +} + +func (environment *MockEVMEnvironment) GetDepth() int { + return environment.depth +} + +func (environment *MockEVMEnvironment) GetLogger() Logger { + return &DefaultLogger{} +} + +func (environment *MockEVMEnvironment) IsCommitting() bool { + return environment.commit +} + +func (environment *MockEVMEnvironment) IsEthCall() bool { + return environment.ethCall +} + +func (environment *MockEVMEnvironment) IsReadOnly() bool { + return environment.readOnly +} + +func (environment *MockEVMEnvironment) CreateContract(caller common.Address, code []byte, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { + return make([]byte, 0), common.Address{}, 0, nil +} + +func (environment *MockEVMEnvironment) CreateContract2(caller common.Address, code []byte, codeHash common.Hash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { + return make([]byte, 0), common.Address{}, 0, nil +} + +func (environment *MockEVMEnvironment) FhevmData() *FhevmData { + return environment.fhevmData +} + +func (environment *MockEVMEnvironment) FhevmParams() *FhevmParams { + return &FhevmParams{} +} + +func (environment *MockEVMEnvironment) EVMEnvironment() EVMEnvironment { + return environment +} + +func newTestEVMEnvironment() *MockEVMEnvironment { + fhevmData := NewFhevmData() + db := rawdb.NewMemoryDatabase() + state, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + return &MockEVMEnvironment{fhevmData: &fhevmData, stateDb: state, commit: true} +} + +func TestProtectedStorageSstoreSload(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + depth := 1 + environment.depth = depth + ct := verifyCiphertextInTestMemory(environment, 2, depth, FheUint32) + ctHash := ct.getHash() + scope := newTestScopeConext() + loc := uint256.NewInt(10) + value := uint256FromBig(ctHash.Big()) + + // Setup and call SSTORE - it requires a location and a value to set there. + scope.pushToStack(value) + scope.pushToStack(loc) + _, err := OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Clear the verified ciphertexts. + environment.FhevmData().verifiedCiphertexts = make(map[common.Hash]*verifiedCiphertext) + + // Setup and call SLOAD - it requires a location to load. + scope.pushToStack(loc) + _, err = OpSload(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Expect the ciphertext is verified after SLOAD. + ctAfterSload := getVerifiedCiphertextFromEVM(environment, ctHash) + if ctAfterSload == nil { + t.Fatalf("expected ciphertext is verified after sload") + } + if !bytes.Equal(ct.serialize(), ctAfterSload.ciphertext.serialize()) { + t.Fatalf("expected ciphertext after sload is the same as original") + } +} + +func TestProtectedStorageGarbageCollectionNoFlaggedLocation(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + depth := 1 + environment.depth = depth + ctHash := verifyCiphertextInTestMemory(environment, 2, depth, FheUint8).getHash() + scope := newTestScopeConext() + loc := uint256.NewInt(10) + locHash := common.BytesToHash(loc.Bytes()) + value := uint256FromBig(ctHash.Big()) + protectedStorage := fhevm_crypto.CreateProtectedStorageContractAddress(scope.GetContract().Address()) + + // Persist the ciphertext in protected storage. + scope.pushToStack(value) + scope.pushToStack(loc) + _, err := OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Set location flag to zero, such that garbage collection doesn't happen. + flagHandleLocation := crypto.Keccak256Hash(crypto.Keccak256Hash(locHash.Bytes()).Bytes()) + environment.SetState(protectedStorage, flagHandleLocation, zero) + + // Overwrite the ciphertext handle with 0. + scope.pushToStack(uint256.NewInt(0)) + scope.pushToStack(loc) + _, err = OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Verify that garbage collection hasn't happened. + metadata := ciphertextMetadata{} + metadataKey := crypto.Keccak256Hash(ctHash.Bytes()) + metadata.deserialize(environment.GetState(protectedStorage, metadataKey)) + slot := uint256FromBig(metadataKey.Big()) + slot = slot.AddUint64(slot, 1) + foundNonZero := false + for i := uint64(0); i < metadata.length; i++ { + res := environment.GetState(protectedStorage, common.BytesToHash(slot.Bytes())) + if !bytes.Equal(res.Bytes(), zero.Bytes()) { + foundNonZero = true + break + } + slot = slot.AddUint64(slot, i) + } + if !foundNonZero { + t.Fatalf("garbage collection must not have happened") + } +} + +func TestProtectedStorageGarbageCollection(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + depth := 1 + environment.depth = depth + ctHash := verifyCiphertextInTestMemory(environment, 2, depth, FheUint8).getHash() + scope := newTestScopeConext() + loc := uint256.NewInt(10) + locHash := common.BytesToHash(loc.Bytes()) + value := uint256FromBig(ctHash.Big()) + + // Persist the ciphertext in protected storage. + scope.pushToStack(value) + scope.pushToStack(loc) + _, err := OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Make sure ciphertext is persisted to protected storage. + protectedStorage := fhevm_crypto.CreateProtectedStorageContractAddress(scope.GetContract().Address()) + metadata := ciphertextMetadata{} + metadataKey := crypto.Keccak256Hash(ctHash.Bytes()) + metadata.deserialize(environment.GetState(protectedStorage, metadataKey)) + if metadata.refCount != 1 { + t.Fatalf("metadata.refcount of ciphertext is not 1") + } + if metadata.length != uint64(expandedFheCiphertextSize[FheUint8]) { + t.Fatalf("metadata.length (%v) != ciphertext len (%v)", metadata.length, uint64(expandedFheCiphertextSize[FheUint8])) + } + ciphertextLocationsToCheck := (metadata.length + 32 - 1) / 32 + startOfCiphertext := newInt(metadataKey.Bytes()) + startOfCiphertext.AddUint64(startOfCiphertext, 1) + ctIdx := startOfCiphertext + foundNonZero := false + for i := uint64(0); i < ciphertextLocationsToCheck; i++ { + c := environment.GetState(protectedStorage, common.BytesToHash(ctIdx.Bytes())) + u := uint256FromBig(c.Big()) + if !u.IsZero() { + foundNonZero = true + break + } + ctIdx.AddUint64(startOfCiphertext, 1) + } + if !foundNonZero { + t.Fatalf("ciphertext is not persisted to protected storage") + } + + // Check if the handle location is flagged in protected storage. + flagHandleLocation := crypto.Keccak256Hash(crypto.Keccak256Hash(locHash.Bytes()).Bytes()) + foundFlag := environment.GetState(protectedStorage, flagHandleLocation) + if !bytes.Equal(foundFlag.Bytes(), flag.Bytes()) { + t.Fatalf("location flag not persisted to protected storage") + } + + // Overwrite the ciphertext handle with 0. + scope.pushToStack(uint256.NewInt(0)) + scope.pushToStack(loc) + _, err = OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Make sure the metadata and the ciphertext are garbage collected from protected storage. + protectedStorageIdx := newInt(metadataKey.Bytes()) + foundNonZero = false + for i := uint64(0); i < ciphertextLocationsToCheck; i++ { + c := environment.GetState(protectedStorage, common.BytesToHash(protectedStorageIdx.Bytes())) + u := uint256FromBig(c.Big()) + if !u.IsZero() { + foundNonZero = true + break + } + ctIdx.AddUint64(startOfCiphertext, 1) + } + if foundNonZero { + t.Fatalf("ciphertext is not garbage collected from protected storage") + } + + // Make sure the flag location is zero. + foundFlag = environment.GetState(protectedStorage, flagHandleLocation) + if !bytes.Equal(foundFlag.Bytes(), zero.Bytes()) { + t.Fatalf("location flag is not set to zero on garbage collection") + } +} + +func TestProtectedStorageSloadDoesNotVerifyNonHandle(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + scope := newTestScopeConext() + loc := uint256.NewInt(10) + value := uint256.NewInt(42) + + scope.pushToStack(value) + scope.pushToStack(loc) + _, err := OpSstore(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + scope.pushToStack(loc) + _, err = OpSload(&pc, environment, scope) + if err != nil { + t.Fatalf(err.Error()) + } + + // Expect no verified ciphertexts. + if len(environment.FhevmData().verifiedCiphertexts) != 0 { + t.Fatalf("expected no verified ciphetexts") + } +} + +func TestOpReturnDelegation(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + depth := 2 + scope := newTestScopeConext() + ct := verifyCiphertextInTestMemory(environment, 2, depth, FheUint8) + ctHash := ct.getHash() + + offset := uint256.NewInt(0) + length := uint256.NewInt(32) + scope.pushToStack(length) + scope.pushToStack(offset) + scope.GetMemory().Set(offset.Uint64(), length.Uint64(), ctHash[:]) + environment.depth = depth + OpReturn(&pc, environment, scope) + environment.depth-- + ctAfterOp := getVerifiedCiphertextFromEVM(environment, ctHash) + if ctAfterOp == nil { + t.Fatalf("expected ciphertext is still verified after the return op") + } + if !bytes.Equal(ct.serialize(), ctAfterOp.ciphertext.serialize()) { + t.Fatalf("expected ciphertext after the return op is the same as original") + } +} + +func TestOpReturnUnverifyIfNotReturned(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + depth := 2 + scope := newTestScopeConext() + ctHash := verifyCiphertextInTestMemory(environment, 2, depth, FheUint8).getHash() + + offset := uint256.NewInt(0) + len := uint256.NewInt(32) + scope.pushToStack(len) + scope.pushToStack(offset) + // Set 0s as return. + scope.GetMemory().Set(offset.Uint64(), len.Uint64(), make([]byte, len.Uint64())) + environment.depth = depth + OpReturn(&pc, environment, scope) + environment.depth = depth - 1 + ct := getVerifiedCiphertextFromEVM(environment, ctHash) + if ct != nil { + t.Fatalf("expected ciphertext is not verified after the return op") + } +} + +func TestOpReturnDoesNotUnverifyIfNotVerified(t *testing.T) { + environment := newTestEVMEnvironment() + pc := uint64(0) + scope := newTestScopeConext() + ct := verifyCiphertextInTestMemory(environment, 2, 4, FheUint8) + ctHash := ct.getHash() + + // Return from depth 3 to depth 2. However, ct is not verified at 3 and, hence, cannot + // be passed from 3 to 2. However, we expect that ct remains verified at 4. + offset := uint256.NewInt(0) + len := uint256.NewInt(32) + scope.pushToStack(len) + scope.pushToStack(offset) + scope.GetMemory().Set(offset.Uint64(), len.Uint64(), ctHash[:]) + environment.depth = 3 + OpReturn(&pc, environment, scope) + environment.depth-- + + ctAt2 := getVerifiedCiphertextFromEVM(environment, ctHash) + if ctAt2 != nil { + t.Fatalf("expected ciphertext is not verified at 2") + } + environment.depth = 3 + ctAt3 := getVerifiedCiphertextFromEVM(environment, ctHash) + if ctAt3 != nil { + t.Fatalf("expected ciphertext is not verified at 3") + } + environment.depth = 4 + ctAt4 := getVerifiedCiphertextFromEVM(environment, ctHash) + if ctAt4 == nil { + t.Fatalf("expected ciphertext is still verified at 4") + } + if !bytes.Equal(ct.serialize(), ctAt4.ciphertext.serialize()) { + t.Fatalf("expected ciphertext after the return op is the same as original") + } + if ctAt4.verifiedDepths.count() != 1 || !ctAt4.verifiedDepths.has(environment.depth) { + t.Fatalf("expected ciphertext to be verified at depth 4") + } +} diff --git a/go.mod b/go.mod index cc6cc6e..98cc357 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,43 @@ require ( ) require ( + github.com/DataDog/zstd v1.5.2 // indirect + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect + github.com/VictoriaMetrics/fastcache v1.6.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/go-ole/go-ole v1.2.1 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect + golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/go.sum b/go.sum index 24cad07..f5ef0f5 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,438 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +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/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= +github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/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/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= 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/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +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/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= 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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= \ No newline at end of file +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=