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

use vrf in ticket

parent dc4039ad
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
package ticket package ticket
import ( import (
"bytes"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
...@@ -18,6 +20,7 @@ import ( ...@@ -18,6 +20,7 @@ import (
"github.com/33cn/chain33/common/crypto" "github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/difficulty" "github.com/33cn/chain33/common/difficulty"
"github.com/33cn/chain33/common/log/log15" "github.com/33cn/chain33/common/log/log15"
vrf "github.com/33cn/chain33/common/vrf/p256"
"github.com/33cn/chain33/queue" "github.com/33cn/chain33/queue"
drivers "github.com/33cn/chain33/system/consensus" drivers "github.com/33cn/chain33/system/consensus"
driver "github.com/33cn/chain33/system/dapp" driver "github.com/33cn/chain33/system/dapp"
...@@ -361,6 +364,44 @@ func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail ...@@ -361,6 +364,44 @@ func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail
if current.Block.Size() > int(types.MaxBlockSize) { if current.Block.Size() > int(types.MaxBlockSize) {
return types.ErrBlockSize 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 return nil
} }
...@@ -573,11 +614,10 @@ func genPrivHash(priv crypto.PrivKey, tid string) ([]byte, error) { ...@@ -573,11 +614,10 @@ func genPrivHash(priv crypto.PrivKey, tid string) ([]byte, error) {
var countNum int var countNum int
countNum, err := strconv.Atoi(count) countNum, err := strconv.Atoi(count)
if err != nil { if err != nil {
return privHash, err return nil, err
} }
privStr := fmt.Sprintf("%x:%d:%s", priv.Bytes(), countNum, seed) privStr := fmt.Sprintf("%x:%d:%s", priv.Bytes(), countNum, seed)
privHash = common.Sha256([]byte(privStr)) privHash = common.Sha256([]byte(privStr))
} }
return privHash, nil return privHash, nil
} }
...@@ -597,6 +637,23 @@ func (client *Client) addMinerTx(parent, block *types.Block, diff *big.Int, priv ...@@ -597,6 +637,23 @@ func (client *Client) addMinerTx(parent, block *types.Block, diff *big.Int, priv
return err return err
} }
miner.PrivHash = privHash 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.Value = &ty.TicketAction_Miner{Miner: miner}
ticketAction.Ty = ty.TicketActionMiner ticketAction.Ty = ty.TicketActionMiner
//构造transaction //构造transaction
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/crypto" "github.com/33cn/chain33/common/crypto"
vrf "github.com/33cn/chain33/common/vrf/p256"
"github.com/33cn/chain33/queue" "github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
...@@ -163,3 +164,36 @@ func Test_getNextRequiredDifficulty(t *testing.T) { ...@@ -163,3 +164,36 @@ func Test_getNextRequiredDifficulty(t *testing.T) {
assert.Equal(t, bt, defaultModify) assert.Equal(t, bt, defaultModify)
assert.Equal(t, bits, types.GetP(0).PowLimitBits) 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 ...@@ -44,6 +44,8 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag
var bits uint32 var bits uint32
var ticketIds string var ticketIds string
var privHashs []byte var privHashs []byte
var vrfHashs []byte
var vrfProofs []byte
for _, ticketAction := range txActions { for _, ticketAction := range txActions {
//tlog.Debug("GetRandNum", "modify", ticketAction.GetMiner().GetModify(), "bits", ticketAction.GetMiner().GetBits(), "ticketId", ticketAction.GetMiner().GetTicketId(), "PrivHash", ticketAction.GetMiner().GetPrivHash()) //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 ...@@ -51,9 +53,14 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag
bits += ticketAction.GetMiner().GetBits() bits += ticketAction.GetMiner().GetBits()
ticketIds += ticketAction.GetMiner().GetTicketId() ticketIds += ticketAction.GetMiner().GetTicketId()
privHashs = append(privHashs, ticketAction.GetMiner().GetPrivHash()...) 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)) 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)) modify := common.Sha256([]byte(newmodify))
......
...@@ -41,6 +41,12 @@ message TicketMiner { ...@@ -41,6 +41,12 @@ message TicketMiner {
bytes modify = 4; bytes modify = 4;
//挖到区块时公开 //挖到区块时公开
bytes privHash = 5; bytes privHash = 5;
//VRF公钥
bytes pubKey = 6;
//VRF计算得到的hash
bytes vrfHash = 7;
//VRF计算得到的proof
bytes vrfProof = 8;
} }
message TicketMinerOld { message TicketMinerOld {
......
...@@ -25,4 +25,8 @@ var ( ...@@ -25,4 +25,8 @@ var (
ErrModify = errors.New("ErrModify") ErrModify = errors.New("ErrModify")
// ErrMinerTx err type // ErrMinerTx err type
ErrMinerTx = errors.New("ErrMinerTx") ErrMinerTx = errors.New("ErrMinerTx")
// ErrNoVrf err type
ErrNoVrf = errors.New("ErrNoVrf")
// ErrVrfVerify err type
ErrVrfVerify = errors.New("ErrVrfVerify")
) )
...@@ -60,6 +60,7 @@ func init() { ...@@ -60,6 +60,7 @@ func init() {
types.RegistorExecutor(TicketX, NewType()) types.RegistorExecutor(TicketX, NewType())
types.RegisterDappFork(TicketX, "Enable", 0) types.RegisterDappFork(TicketX, "Enable", 0)
types.RegisterDappFork(TicketX, "ForkTicketId", 1062000) types.RegisterDappFork(TicketX, "ForkTicketId", 1062000)
types.RegisterDappFork(TicketX, "ForkTicketVrf", 1750000)
} }
// TicketType ticket exec type // 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