Skip to content

Commit

Permalink
refactor: SIgnItem moved to crypto and replaces all crypto.SignID calls
Browse files Browse the repository at this point in the history
  • Loading branch information
lklimek committed Dec 15, 2023
1 parent db4f012 commit bc793c4
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 169 deletions.
13 changes: 7 additions & 6 deletions abci/example/kvstore/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/dashpay/dashd-go/btcjson"

abci "github.com/dashpay/tenderdash/abci/types"
"github.com/dashpay/tenderdash/crypto"
"github.com/dashpay/tenderdash/crypto/encoding"
tmbytes "github.com/dashpay/tenderdash/libs/bytes"
types1 "github.com/dashpay/tenderdash/proto/tendermint/types"
Expand Down Expand Up @@ -50,7 +51,7 @@ func makeBlockSignItem(
req *abci.RequestFinalizeBlock,
quorumType btcjson.LLMQType,
quorumHash []byte,
) types.SignItem {
) crypto.SignItem {
reqID := types.BlockRequestID(req.Height, req.Round)
cv, err := req.ToCanonicalVote()
if err != nil {
Expand All @@ -60,19 +61,19 @@ func makeBlockSignItem(
if err != nil {
panic(fmt.Errorf("block sign item: %w", err))
}
return types.NewSignItem(quorumType, quorumHash, reqID, raw)
return crypto.NewSignItem(quorumType, quorumHash, reqID, raw)
}

func makeVoteExtensionSignItems(
req *abci.RequestFinalizeBlock,
quorumType btcjson.LLMQType,
quorumHash []byte,
) map[types1.VoteExtensionType][]types.SignItem {
items := make(map[types1.VoteExtensionType][]types.SignItem)
) map[types1.VoteExtensionType][]crypto.SignItem {
items := make(map[types1.VoteExtensionType][]crypto.SignItem)
protoExtensionsMap := types1.VoteExtensionsToMap(req.Commit.ThresholdVoteExtensions)
for t, exts := range protoExtensionsMap {
if items[t] == nil && len(exts) > 0 {
items[t] = make([]types.SignItem, len(exts))
items[t] = make([]crypto.SignItem, len(exts))
}
chainID := req.Block.Header.ChainID
for i, ext := range exts {
Expand All @@ -82,7 +83,7 @@ func makeVoteExtensionSignItems(
panic(fmt.Errorf("vote extension sign items: %w", err))
}

items[t][i] = types.NewSignItem(quorumType, quorumHash, reqID, raw)
items[t][i] = crypto.NewSignItem(quorumType, quorumHash, reqID, raw)
}
}
return items
Expand Down
99 changes: 95 additions & 4 deletions crypto/quorum.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,106 @@
package crypto

import (
"bytes"
"fmt"

bls "github.com/dashpay/bls-signatures/go-bindings"
"github.com/dashpay/dashd-go/btcjson"
"github.com/rs/zerolog"
)

// SignID returns signing session data that will be signed to get threshold signature share.
// SignItem represents signing session data (in field SignItem.ID) that will be signed to get threshold signature share.
// See DIP-0007
func SignID(llmqType btcjson.LLMQType, quorumHash QuorumHash, requestID []byte, messageHash []byte) []byte {
type SignItem struct {
ReqID []byte // Request ID for quorum signing
ID []byte // Signature ID
Raw []byte // Raw data to be signed
Hash []byte // Checksum of Raw
QuorumType btcjson.LLMQType // Quorum type for which this sign item is created
QuorumHash []byte // Quorum hash for which this sign item is created
}

// Validate validates prepared data for signing
func (i *SignItem) Validate() error {
if len(i.ReqID) != DefaultHashSize {
return fmt.Errorf("invalid request ID size: %X", i.ReqID)
}
if len(i.Hash) != DefaultHashSize {
return fmt.Errorf("invalid hash size: %X", i.ReqID)
}
if len(i.QuorumHash) != DefaultHashSize {
return fmt.Errorf("invalid quorum hash size: %X", i.ReqID)
}
if len(i.Raw) > 0 {
if !bytes.Equal(Checksum(i.Raw), i.Hash) {
return fmt.Errorf("invalid hash %X for raw data: %X", i.Hash, i.Raw)
}
}
return nil
}

func (i SignItem) MarshalZerologObject(e *zerolog.Event) {
e.Hex("signBytes", i.Raw)
e.Hex("signRequestID", i.ReqID)
e.Hex("signID", i.ID)
e.Hex("signHash", i.Hash)
}

// NewSignItem creates a new instance of SignItem with calculating a hash for a raw and creating signID
//
// Arguments:
// - quorumType: quorum type
// - quorumHash: quorum hash
// - reqID: sign request ID
// - raw: raw data to be signed; it will be hashed with crypto.Checksum()
func NewSignItem(quorumType btcjson.LLMQType, quorumHash, reqID, raw []byte) SignItem {
msgHash := Checksum(raw)
item := NewSignItemFromHash(quorumType, quorumHash, reqID, msgHash)
item.Raw = raw

return item
}

// Create a new sign item without raw value, using provided hash.
func NewSignItemFromHash(quorumType btcjson.LLMQType, quorumHash, reqID, msgHash []byte) SignItem {
item := SignItem{
ReqID: reqID,
Hash: msgHash,
QuorumType: quorumType,
QuorumHash: quorumHash,
Raw: nil, // Raw is empty, as we don't have it
}
item.UpdateID()

return item
}

func (i *SignItem) UpdateID() {
if err := i.Validate(); err != nil {
panic("invalid sign item: " + err.Error())
}
// FIXME: previously we had reversals, but this doesn't work with Core test vectors
// So
// quorumHash := tmbytes.Reverse(i.QuorumHash)
quorumHash := i.QuorumHash
// requestID := tmbytes.Reverse(i.ReqID)
requestID := i.ReqID
// messageHash := tmbytes.Reverse(i.Hash)
messageHash := i.Hash

llmqType := i.QuorumType

// if testing.Testing() {
// fmt.Printf("generating sign ID using bls.BuildSignHash for %d %X %X %X\n", llmqType, quorumHash, requestID, messageHash)
// out := append([]byte{byte(llmqType)}, quorumHash...)
// out = append(out, requestID...)
// out = append(out, messageHash...)

// fmt.Printf("data before sha256: %X\n", out)
// fmt.Printf("sha256(sha256(data)): %X\n", crypto.Checksum((crypto.Checksum(out))))
// }
var blsQuorumHash bls.Hash
copy(blsQuorumHash[:], quorumHash.Bytes())
copy(blsQuorumHash[:], quorumHash)

var blsRequestID bls.Hash
copy(blsRequestID[:], requestID)
Expand All @@ -22,5 +113,5 @@ func SignID(llmqType btcjson.LLMQType, quorumHash QuorumHash, requestID []byte,
signHash := make([]byte, 32)
copy(signHash, blsSignHash[:])

return signHash
i.ID = signHash
}
16 changes: 4 additions & 12 deletions dash/core/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,8 @@ func (mc *MockClient) QuorumSign(
if !mc.canSign {
return nil, errors.New("dash core mock client not set up for signing")
}
signID := crypto.NewSignItemFromHash(quorumType, quorumHash, requestID, messageHash).ID

signID := crypto.SignID(
quorumType,
tmbytes.Reverse(quorumHash),
tmbytes.Reverse(requestID),
tmbytes.Reverse(messageHash),
)
privateKey, err := mc.localPV.GetPrivateKey(context.Background(), quorumHash)
if err != nil {
panic(err)
Expand Down Expand Up @@ -190,12 +185,9 @@ func (mc *MockClient) QuorumVerify(
if err := quorumType.Validate(); err != nil {
return false, err
}
signID := crypto.SignID(
quorumType,
tmbytes.Reverse(quorumHash),
tmbytes.Reverse(requestID),
tmbytes.Reverse(messageHash),
)

signID := crypto.NewSignItemFromHash(quorumType, quorumHash, requestID, messageHash).ID

thresholdPublicKey, err := mc.localPV.GetThresholdPublicKey(context.Background(), quorumHash)
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion internal/consensus/vote_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (s *voteSigner) signVote(
if err != nil {
return nil, err
}

s.logger.Debug("signed Vote", "vote", vote, "signature", vote.BlockSignature.String())
return vote, nil
}

Expand Down
8 changes: 4 additions & 4 deletions internal/consensus/vote_signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,25 @@ func TestVoteSigner_signAddVote(t *testing.T) {
{
msgType: tmproto.PrevoteType,
blockID: blockID,
wantBlockSign: "8B52677D4D455125808EDEE715D2A999695A6701E477C1F44CEDCCE3FC62FB88698D0B6B3CA0429E17EDA9DBCEA932720C189E21F5A6FB31B2C244152F0CD7988598AD572E5D605164554C80880BDC130E23C9DBEF20CF315D05F8C13B6C92CC",
wantBlockSign: "80B628F02FE2047C7B98175CD8CF609775B95393C63D8EBC2F630D95121C28826C942F6511405D33484639C2906879110FDC293418C95862A60329FDDF0B210654559839B5ABFC11E50AFC4E498B0C9041118394DB04E52D0B28A92FC91DEABC",
},
{
msgType: tmproto.PrecommitType,
wantBlockSign: "97CCF337D8FCA05E600EAAF769D73BE9A0D1466CAE85374E9E0EF4C3DD1759131E1D2C8B9E8D8D28EBEF27074669D46C0820DF4DA337DFFA6B3EB5BEEA4B78CA8EA131ED584609D227025DB96990C732C2D04A693BC0402B8A19229ED32A51B8",
wantBlockSign: "8BEEE4EDA67394060C1A1D41797E998120B7BC217E7D36526DA76AE57616475FB1C4DCF08C522E76C75220104611F56800F1CF299ECD98FDB1C598471DC0D4048F8F5381B034270EB0B66E987D61B7DF555DFA92C6B5C9E6FAD608676130A726",
},
{
msgType: tmproto.PrecommitType,
blockID: blockID,
voteExtensions: nil,
mockFn: mockFn,
wantBlockSign: "9755FA9803D98C344CB16A43B782D2A93ED9A7E7E1C8437482F42781D5EF802EC82442C14C44429737A7355B1F9D87CB139EB2CF193A1CF7C812E38B99221ADF4DAA60CE16550ED6509A9C467A3D4492D77038505235796968465337A1E14B3E",
wantBlockSign: "B2C484BB07094AAB8EFAB187982F6A8E8172FBEBAE5B6EB6304E527ABAAB7D059D9A43DDDBA82A6D296AF30E67C28D250449A586E9A69C2577057E01FA290BB03C186982D4D45E6016935AD4B9A84EB0911B62A83E457E25CE44DC28516D0E0A",
},
{
msgType: tmproto.PrecommitType,
blockID: blockID,
voteExtensions: voteExtensions,
mockFn: mockFn,
wantBlockSign: "9755FA9803D98C344CB16A43B782D2A93ED9A7E7E1C8437482F42781D5EF802EC82442C14C44429737A7355B1F9D87CB139EB2CF193A1CF7C812E38B99221ADF4DAA60CE16550ED6509A9C467A3D4492D77038505235796968465337A1E14B3E",
wantBlockSign: "B2C484BB07094AAB8EFAB187982F6A8E8172FBEBAE5B6EB6304E527ABAAB7D059D9A43DDDBA82A6D296AF30E67C28D250449A586E9A69C2577057E01FA290BB03C186982D4D45E6016935AD4B9A84EB0911B62A83E457E25CE44DC28516D0E0A",
},
}
for i, tc := range testCases {
Expand Down
9 changes: 2 additions & 7 deletions privval/dash_consensus_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/dashpay/dashd-go/btcjson"

"github.com/dashpay/tenderdash/crypto"
tmcrypto "github.com/dashpay/tenderdash/crypto"
tmbytes "github.com/dashpay/tenderdash/libs/bytes"
)

type dashConsensusPrivateKey struct {
Expand Down Expand Up @@ -105,12 +105,7 @@ func (pub DashConsensusPublicKey) VerifySignature(msg []byte, sig []byte) bool {
return pub.VerifySignatureDigest(hash, sig)
}
func (pub DashConsensusPublicKey) VerifySignatureDigest(hash []byte, sig []byte) bool {
signID := tmcrypto.SignID(
pub.quorumType,
tmbytes.Reverse(pub.quorumHash),
tmbytes.Reverse(hash[:]),
tmbytes.Reverse(hash[:]),
)
signID := crypto.NewSignItemFromHash(pub.quorumType, pub.quorumHash, hash, hash).ID

return pub.PubKey.VerifySignatureDigest(signID, sig)
}
8 changes: 4 additions & 4 deletions privval/dash_core_signer_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (sc *DashCoreSignerClient) SignVote(
func (sc *DashCoreSignerClient) SignProposal(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash, proposalProto *tmproto.Proposal,
) (tmbytes.HexBytes, error) {
signItem := types.NewSignItem(
signItem := crypto.NewSignItem(
quorumType,
quorumHash,
types.ProposalRequestIDProto(proposalProto),
Expand All @@ -314,7 +314,7 @@ func (sc *DashCoreSignerClient) QuorumSign(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
) ([]byte, []byte, error) {
signItem := types.NewSignItemFromHash(quorumType, quorumHash, requestIDHash, msgHash)
signItem := crypto.NewSignItemFromHash(quorumType, quorumHash, requestIDHash, msgHash)

qs, err := sc.quorumSignAndVerify(ctx, quorumType, quorumHash, signItem)
if err != nil {
Expand Down Expand Up @@ -392,7 +392,7 @@ func (sc *DashCoreSignerClient) quorumSignAndVerify(
ctx context.Context,
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
signItem types.SignItem,
signItem crypto.SignItem,
) (*quorumSignResult, error) {
qs, err := sc.quorumSign(quorumType, quorumHash, signItem)
if err != nil {
Expand Down Expand Up @@ -420,7 +420,7 @@ func (sc *DashCoreSignerClient) quorumSignAndVerify(
func (sc *DashCoreSignerClient) quorumSign(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
signItem types.SignItem,
signItem crypto.SignItem,
) (*quorumSignResult, error) {
resp, err := sc.dashCoreRPCClient.QuorumSign(quorumType, signItem.ReqID, signItem.Hash, quorumHash)
if err != nil {
Expand Down
15 changes: 2 additions & 13 deletions test/e2e/pkg/mockcoreserver/core_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/dashpay/dashd-go/btcjson"

"github.com/dashpay/tenderdash/crypto"
tmbytes "github.com/dashpay/tenderdash/libs/bytes"
"github.com/dashpay/tenderdash/privval"
)

Expand Down Expand Up @@ -93,13 +92,8 @@ func (c *MockCoreServer) QuorumSign(ctx context.Context, cmd btcjson.QuorumCmd)
panic(err)
}
quorumHash := crypto.QuorumHash(quorumHashBytes)
signID := crypto.NewSignItemFromHash(*cmd.LLMQType, quorumHash, reqID, msgHash).ID

signID := crypto.SignID(
*cmd.LLMQType,
tmbytes.Reverse(quorumHash),
tmbytes.Reverse(reqID),
tmbytes.Reverse(msgHash),
)
privateKey, err := c.FilePV.GetPrivateKey(ctx, quorumHash)
if err != nil {
panic(err)
Expand Down Expand Up @@ -142,13 +136,8 @@ func (c *MockCoreServer) QuorumVerify(ctx context.Context, cmd btcjson.QuorumCmd
if err != nil {
panic(err)
}
signID := crypto.NewSignItemFromHash(*cmd.LLMQType, quorumHash, reqID, msgHash).ID

signID := crypto.SignID(
*cmd.LLMQType,
tmbytes.Reverse(quorumHash),
tmbytes.Reverse(reqID),
tmbytes.Reverse(msgHash),
)
thresholdPublicKey, err := c.FilePV.GetThresholdPublicKey(ctx, quorumHash)
if err != nil {
panic(err)
Expand Down
7 changes: 1 addition & 6 deletions types/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,7 @@ func ProposalBlockSignID(

proposalRequestID := ProposalRequestIDProto(p)

signID := crypto.SignID(
quorumType,
tmbytes.Reverse(quorumHash),
tmbytes.Reverse(proposalRequestID),
tmbytes.Reverse(proposalMessageHash[:]),
)
signID := crypto.NewSignItemFromHash(quorumType, quorumHash, proposalRequestID, proposalMessageHash[:]).ID

return signID
}
Expand Down
Loading

0 comments on commit bc793c4

Please sign in to comment.