Commit d9d1526b authored by caopingcp's avatar caopingcp Committed by vipwzw

use vrf in ticket

parent dc4039ad
......@@ -5,6 +5,8 @@
package ticket
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"math/big"
......@@ -18,6 +20,7 @@ import (
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/difficulty"
"github.com/33cn/chain33/common/log/log15"
vrf "github.com/33cn/chain33/common/vrf/p256"
"github.com/33cn/chain33/queue"
drivers "github.com/33cn/chain33/system/consensus"
driver "github.com/33cn/chain33/system/dapp"
......@@ -361,6 +364,44 @@ func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail
if current.Block.Size() > int(types.MaxBlockSize) {
return types.ErrBlockSize
}
//vrf verify
if types.IsDappFork(current.Block.Height, ty.TicketX, "ForkTicketVrf") {
LastTicketAction, err := client.getMinerTx(parent)
if err != nil {
return err
}
input := LastTicketAction.GetMiner().GetVrfHash()
if input == nil {
input = miner.PrivHash
}
if err = vrfVerify(miner.PubKey, input, miner.VrfProof, miner.VrfHash); err != nil {
return err
}
} else {
if len(miner.PubKey) != 0 || len(miner.VrfHash) != 0 || len(miner.VrfProof) != 0 {
tlog.Error("block error: not yet add vrf")
return ty.ErrNoVrf
}
}
return nil
}
func vrfVerify(pub []byte, input []byte, proof []byte, hash []byte) error {
vrfPub, err := vrf.ParseVrfPubKey(pub)
if err != nil {
tlog.Error("vrfVerify", "err", err)
return ty.ErrVrfVerify
}
vrfHash, err := vrfPub.ProofToHash(input, proof)
if err != nil {
tlog.Error("vrfVerify", "err", err)
return ty.ErrVrfVerify
}
tlog.Debug("vrf verify", "ProofToHash", fmt.Sprintf("(%x, %x): %x", input, proof, vrfHash), "hash", hex.EncodeToString(hash))
if !bytes.Equal(vrfHash[:], hash) {
tlog.Error("vrfVerify", "err", errors.New("invalid VRF hash"))
return ty.ErrVrfVerify
}
return nil
}
......@@ -573,11 +614,10 @@ func genPrivHash(priv crypto.PrivKey, tid string) ([]byte, error) {
var countNum int
countNum, err := strconv.Atoi(count)
if err != nil {
return privHash, err
return nil, err
}
privStr := fmt.Sprintf("%x:%d:%s", priv.Bytes(), countNum, seed)
privHash = common.Sha256([]byte(privStr))
}
return privHash, nil
}
......@@ -597,6 +637,23 @@ func (client *Client) addMinerTx(parent, block *types.Block, diff *big.Int, priv
return err
}
miner.PrivHash = privHash
//add vrf
if types.IsDappFork(block.Height, ty.TicketX, "ForkTicketVrf") {
LastTicketAction, err := client.getMinerTx(parent)
if err != nil {
return err
}
input := LastTicketAction.GetMiner().GetVrfHash()
if input == nil {
input = miner.PrivHash
}
vrfPriv, _, pubKey := vrf.GenVrfKey(priv)
vrfHash, vrfProof := vrfPriv.Evaluate(input)
miner.PubKey = pubKey
miner.VrfHash = vrfHash[:]
miner.VrfProof = vrfProof
}
ticketAction.Value = &ty.TicketAction_Miner{Miner: miner}
ticketAction.Ty = ty.TicketActionMiner
//构造transaction
......
......@@ -10,6 +10,7 @@ import (
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/crypto"
vrf "github.com/33cn/chain33/common/vrf/p256"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
......@@ -163,3 +164,36 @@ func Test_getNextRequiredDifficulty(t *testing.T) {
assert.Equal(t, bt, defaultModify)
assert.Equal(t, bits, types.GetP(0).PowLimitBits)
}
func Test_vrfVerify(t *testing.T) {
c, err := crypto.New(types.GetSignName("", types.SECP256K1))
assert.NoError(t, err)
priv, err := c.GenKey()
assert.NoError(t, err)
vpriv, _, pubKey := vrf.GenVrfKey(priv)
m1 := []byte("data1")
m2 := []byte("data2")
m3 := []byte("data2")
hash1, proof1 := vpriv.Evaluate(m1)
hash2, proof2 := vpriv.Evaluate(m2)
hash3, proof3 := vpriv.Evaluate(m3)
for _, tc := range []struct {
m []byte
hash [32]byte
proof []byte
err error
}{
{m1, hash1, proof1, nil},
{m2, hash2, proof2, nil},
{m3, hash3, proof3, nil},
{m3, hash3, proof2, nil},
{m3, hash3, proof1, ty.ErrVrfVerify},
{m3, hash1, proof3, ty.ErrVrfVerify},
} {
err := vrfVerify(pubKey, tc.m, tc.proof, tc.hash[:])
if got, want := err, tc.err; got != want {
t.Errorf("vrfVerify(%s, %x): %v, want %v", tc.m, tc.proof, got, want)
}
}
}
......@@ -44,6 +44,8 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag
var bits uint32
var ticketIds string
var privHashs []byte
var vrfHashs []byte
var vrfProofs []byte
for _, ticketAction := range txActions {
//tlog.Debug("GetRandNum", "modify", ticketAction.GetMiner().GetModify(), "bits", ticketAction.GetMiner().GetBits(), "ticketId", ticketAction.GetMiner().GetTicketId(), "PrivHash", ticketAction.GetMiner().GetPrivHash())
......@@ -51,9 +53,14 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag
bits += ticketAction.GetMiner().GetBits()
ticketIds += ticketAction.GetMiner().GetTicketId()
privHashs = append(privHashs, ticketAction.GetMiner().GetPrivHash()...)
vrfHashs = append(vrfHashs, ticketAction.GetMiner().GetVrfHash()...)
vrfProofs = append(vrfProofs, ticketAction.GetMiner().GetVrfProof()...)
}
newmodify := fmt.Sprintf("%s:%s:%d:%s", string(modifies), ticketIds, bits, string(privHashs))
if len(vrfHashs) != 0 {
newmodify = newmodify + ":" + fmt.Sprintf("%x:%x", vrfHashs, vrfProofs)
}
modify := common.Sha256([]byte(newmodify))
......
......@@ -41,6 +41,12 @@ message TicketMiner {
bytes modify = 4;
//挖到区块时公开
bytes privHash = 5;
//VRF公钥
bytes pubKey = 6;
//VRF计算得到的hash
bytes vrfHash = 7;
//VRF计算得到的proof
bytes vrfProof = 8;
}
message TicketMinerOld {
......
......@@ -25,4 +25,8 @@ var (
ErrModify = errors.New("ErrModify")
// ErrMinerTx err type
ErrMinerTx = errors.New("ErrMinerTx")
// ErrNoVrf err type
ErrNoVrf = errors.New("ErrNoVrf")
// ErrVrfVerify err type
ErrVrfVerify = errors.New("ErrVrfVerify")
)
......@@ -60,6 +60,7 @@ func init() {
types.RegistorExecutor(TicketX, NewType())
types.RegisterDappFork(TicketX, "Enable", 0)
types.RegisterDappFork(TicketX, "ForkTicketId", 1062000)
types.RegisterDappFork(TicketX, "ForkTicketVrf", 1750000)
}
// TicketType ticket exec type
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment