feature/groth16
frozen 9 months ago
parent 81c8204427
commit 4f9fd3da7e
No known key found for this signature in database
GPG Key ID: 5391C63E79B03EDE
  1. 93
      core/vm/contracts.go
  2. 3
      core/vm/evm.go
  3. 11
      crypto/groth16/bn256/lib.go
  4. 1
      internal/params/config.go

@ -22,11 +22,14 @@ import (
"encoding/binary" "encoding/binary"
//Needed for SHA3-256 FIPS202 //Needed for SHA3-256 FIPS202
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io"
"math/big" "math/big"
"github.com/consensys/gnark/backend/groth16"
"github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/blake2b"
groth16bn256 "github.com/harmony-one/harmony/crypto/groth16/bn256"
"github.com/pkg/errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
@ -38,8 +41,6 @@ import (
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
"github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
gnark "github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/witness" "github.com/consensys/gnark/backend/witness"
//gnarkLog "github.com/consensys/gnark/logger" //gnarkLog "github.com/consensys/gnark/logger"
) )
@ -171,83 +172,79 @@ func (g groth16Verify) RequiredGas(input []byte) uint64 {
} }
func (g groth16Verify) Run(input []byte) ([]byte, error) { func (g groth16Verify) Run(input []byte) ([]byte, error) {
//TODO implement me buf := make([]byte, 2)
panic("implement me") r := bytes.NewReader(input)
_, err := io.ReadFull(r, buf)
if err != nil {
return nil, errors.WithMessage(err, "failed to read first input")
}
s := binary.BigEndian.Uint16(buf)
verifyingKey := make([]byte, s)
_, err = io.ReadFull(r, verifyingKey)
if err != nil {
return nil, errors.WithMessagef(err, "failed to read data for first input of size %d", s)
}
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, errors.WithMessage(err, "failed to read second input")
}
s = binary.BigEndian.Uint16(buf)
proof := make([]byte, s)
_, err = io.ReadFull(r, proof)
if err != nil {
return nil, errors.WithMessagef(err, "failed to read data for second input of size %d", s)
}
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, errors.WithMessage(err, "failed to read third input")
}
s = binary.BigEndian.Uint16(buf)
inputs := make([]byte, s)
_, err = io.ReadFull(r, inputs)
if err != nil {
return nil, errors.WithMessagef(err, "failed to read data for third input of size %d", s)
}
Groth16Verify(verifyingKey, proof, inputs, ecc.BN254)
} }
func Groth16Verify(verifyingKey []byte, proofBytes []byte, inputsBytes []byte, curve ecc.ID) (bool, error) { func Groth16Verify(verifyingKey []byte, proofBytes []byte, inputsBytes []byte, curve ecc.ID) (bool, error) {
var vk gnark.VerifyingKey var vk groth16.VerifyingKey
var proof gnark.Proof var proof groth16.Proof
switch curve { switch curve {
case ecc.BN254: case ecc.BN254:
bn256vk, err := FromBytesToVerifyingKey(verifyingKey) bn256vk, err := groth16bn256.FromBytesToVerifyingKey(verifyingKey)
if err != nil { if err != nil {
return false, err return false, err
} }
vk = bn256vk vk = bn256vk
bn256proof, err := bn256.FromBytesToProof(proofBytes) bn256proof, err := groth16bn256.FromBytesToProof(proofBytes)
if err != nil { if err != nil {
return false, err return false, err
} }
proof = bn256proof proof = bn256proof
default: default:
return false, errors.Errorf("unknown eliptic curve") return false, errors.New("unknown eliptic curve")
} }
var buf bytes.Buffer
buf.Grow(8 + 4 + len(inputsBytes))
// Add 8 bytes for correct reading
// Gnark witness has two addition number in the start
// These numbers aren't used for verification
buf.Write(make([]byte, 8))
err := binary.Write(&buf, binary.BigEndian, uint32(len(inputsBytes)/(fr.Limbs*sizeUint64)))
if err != nil {
return false, err
}
buf.Write(inputsBytes)
wit, err := witness.New(curve.ScalarField()) wit, err := witness.New(curve.ScalarField())
if err != nil { if err != nil {
return false, err return false, err
} }
err = wit.UnmarshalBinary(buf.Bytes()) err = wit.UnmarshalBinary(inputsBytes)
if err != nil { if err != nil {
return false, err return false, err
} }
err = gnark.Verify(proof, vk, wit) err = groth16.Verify(proof, vk, wit)
if err != nil { if err != nil {
return false, nil return false, nil
} }
return true, nil return true, nil
} }
func FromBytesToProof(proofBytes []byte) (gnark.Proof, error) {
var bproof BellmanProofBn256
proofBytes, err := changeFlagsInProofToGnarkType(proofBytes)
if err != nil {
return nil, err
}
_, err = bproof.ReadFrom(bytes.NewReader(proofBytes))
if err != nil {
return nil, err
}
var b bytes.Buffer
_, err = bproof.WriteTo(&b)
if err != nil {
return nil, err
}
proof := gnark.NewProof(ecc.BN254)
_, err = proof.ReadFrom(bytes.NewReader(b.Bytes()))
if err != nil {
return nil, err
}
return proof, nil
}
func init() { func init() {
// check that there is no overlap, and panic if there is // check that there is no overlap, and panic if there is
readOnlyContracts := PrecompiledContractsStaking readOnlyContracts := PrecompiledContractsStaking

@ -87,6 +87,9 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
precompiles = PrecompiledContractsStaking precompiles = PrecompiledContractsStaking
writeCapablePrecompiles = WriteCapablePrecompiledContractsStaking writeCapablePrecompiles = WriteCapablePrecompiledContractsStaking
} }
if evm.chainRules.IsGroth16Precompile {
precompiles = PrecompiledContractsGroth16
}
if evm.chainRules.IsCrossShardXferPrecompile { if evm.chainRules.IsCrossShardXferPrecompile {
writeCapablePrecompiles = WriteCapablePrecompiledContractsCrossXfer writeCapablePrecompiles = WriteCapablePrecompiledContractsCrossXfer
} }

@ -1,4 +1,4 @@
package bn254 package bn256
import ( import (
"bytes" "bytes"
@ -15,3 +15,12 @@ func FromBytesToVerifyingKey(verifyingKey []byte) (gnark.VerifyingKey, error) {
} }
return vk, nil return vk, nil
} }
func FromBytesToProof(proofBytes []byte) (gnark.Proof, error) {
proof := gnark.NewProof(ecc.BN254)
_, err := proof.ReadFrom(bytes.NewReader(proofBytes))
if err != nil {
return nil, err
}
return proof, nil
}

@ -879,6 +879,7 @@ type Rules struct {
// precompiles // precompiles
IsIstanbul, IsVRF, IsPrevVRF, IsSHA3, IsIstanbul, IsVRF, IsPrevVRF, IsSHA3,
IsStakingPrecompile, IsCrossShardXferPrecompile, IsStakingPrecompile, IsCrossShardXferPrecompile,
IsGroth16Precompile,
// eip-155 chain id fix // eip-155 chain id fix
IsChainIdFix bool IsChainIdFix bool
IsValidatorCodeFix bool IsValidatorCodeFix bool

Loading…
Cancel
Save