Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wire: add previous revealed secrets hashes to RS message #3239

Merged
merged 1 commit into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 62 additions & 7 deletions wire/msgmixsecrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type MsgMixSecrets struct {
Seed [32]byte
SlotReserveMsgs [][]byte
DCNetMsgs MixVect
SeenSecrets []chainhash.Hash

// hash records the hash of the message. It is a member of the
// message for convenience and performance, but is never automatically
Expand All @@ -43,6 +44,9 @@ func writeMixVect(op string, w io.Writer, pver uint32, vec MixVect) error {
if err != nil {
return err
}
if len(vec) == 0 {
return nil
}
err = WriteVarInt(w, pver, MixMsgSize)
if err != nil {
return err
Expand Down Expand Up @@ -138,6 +142,25 @@ func (msg *MsgMixSecrets) BtcDecode(r io.Reader, pver uint32) error {
}
msg.DCNetMsgs = dcnetMsgs

count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
if count > MaxMixPeers {
msg := fmt.Sprintf("too many previous referenced messages [count %v, max %v]",
count, MaxMixPeers)
return messageError(op, ErrTooManyPrevMixMsgs, msg)
}

seen := make([]chainhash.Hash, count)
for i := range seen {
err := readElement(r, &seen[i])
if err != nil {
return err
}
}
msg.SeenSecrets = seen

return nil
}

Expand Down Expand Up @@ -173,6 +196,17 @@ func (msg *MsgMixSecrets) Hash() chainhash.Hash {
return msg.hash
}

// Commitment returns a hash committing to the contents of the reveal secrets
// message without committing to any previous seen messages or the message
// signature. This is the hash that is referenced by peers' key exchange
// messages.
func (msg *MsgMixSecrets) Commitment(h hash.Hash) chainhash.Hash {
msgCopy := *msg
msgCopy.SeenSecrets = nil
msgCopy.WriteHash(h)
return msgCopy.hash
}

// WriteHash serializes the message to a hasher and records the sum in the
// message's Hash field.
//
Expand All @@ -196,6 +230,14 @@ func (msg *MsgMixSecrets) WriteHash(h hash.Hash) {
//
// This method never errors for invalid message construction.
func (msg *MsgMixSecrets) writeMessageNoSignature(op string, w io.Writer, pver uint32) error {
// Limit to max previous messages hashes.
count := len(msg.SeenSecrets)
if count > MaxMixPeers {
msg := fmt.Sprintf("too many previous referenced messages [count %v, max %v]",
count, MaxMixPeers)
return messageError(op, ErrTooManyPrevMixMsgs, msg)
}

err := writeElements(w, &msg.Identity, &msg.SessionID, msg.Run, &msg.Seed)
if err != nil {
return err
Expand All @@ -217,6 +259,17 @@ func (msg *MsgMixSecrets) writeMessageNoSignature(op string, w io.Writer, pver u
return err
}

err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for i := range msg.SeenSecrets {
err := writeElement(w, &msg.SeenSecrets[i])
if err != nil {
return err
}
}

return nil
}

Expand All @@ -242,7 +295,7 @@ func (msg *MsgMixSecrets) MaxPayloadLength(pver uint32) uint32 {
}

// See tests for this calculation
return 54444
return 70831
}

// Pub returns the message sender's public key identity.
Expand All @@ -255,13 +308,14 @@ func (msg *MsgMixSecrets) Sig() []byte {
return msg.Signature[:]
}

// PrevMsgs returns nil. Previous messages are not needed to perform blame
// assignment, because of the assumption that all previous messages must have
// been received for a blame stage to be necessary. Additionally, a
// commitment to the secrets message is included in the key exchange, and
// future message hashes are not available at that time.
// PrevMsgs returns previously revealed secrets messages by other peers. An
// honest peer who needs to report blame assignment does not need to reference
// any previous secrets messages, and a secrets message with other referenced
// secrets is necessary to begin blame assignment. Dishonest peers who
// initially reveal their secrets without blame assignment being necessary are
// themselves removed in future runs.
func (msg *MsgMixSecrets) PrevMsgs() []chainhash.Hash {
return nil
return msg.SeenSecrets
}

// Sid returns the session ID.
Expand All @@ -287,5 +341,6 @@ func NewMsgMixSecrets(identity [33]byte, sid [32]byte, run uint32,
Seed: seed,
SlotReserveMsgs: slotReserveMsgs,
DCNetMsgs: dcNetMsgs,
SeenSecrets: make([]chainhash.Hash, 0),
}
}
19 changes: 17 additions & 2 deletions wire/msgmixsecrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"github.com/davecgh/go-spew/spew"
"github.com/decred/dcrd/chaincfg/chainhash"
)

func newTestMixSecrets() *MsgMixSecrets {
Expand All @@ -34,7 +35,13 @@ func newTestMixSecrets() *MsgMixSecrets {
copy(m[b-0x89][:], repeat(b, 20))
}

seenRSs := make([]chainhash.Hash, 4)
for b := byte(0x8D); b < 0x91; b++ {
copy(seenRSs[b-0x8D][:], repeat(b, 32))
}

rs := NewMsgMixSecrets(id, sid, run, seed, sr, m)
rs.SeenSecrets = seenRSs
rs.Signature = sig

return rs
Expand Down Expand Up @@ -67,12 +74,18 @@ func TestMsgMixSecretsWire(t *testing.T) {
expected = append(expected, repeat(0x87, 32)...)
expected = append(expected, 0x20)
expected = append(expected, repeat(0x88, 32)...)
// Four slot reservation mixed messages (repeating 20 bytes of 0x89, 0x8a, 0x8b, 0x8c)
// Four xor dc-net mixed messages (repeating 20 bytes of 0x89, 0x8a, 0x8b, 0x8c)
expected = append(expected, 0x04, 0x14)
expected = append(expected, repeat(0x89, 20)...)
expected = append(expected, repeat(0x8a, 20)...)
expected = append(expected, repeat(0x8b, 20)...)
expected = append(expected, repeat(0x8c, 20)...)
// Four seen RSs (repeating 32 bytes of 0x8d, 0x8e, 0x8f, 0x90)
expected = append(expected, 0x04)
expected = append(expected, repeat(0x8d, 32)...)
expected = append(expected, repeat(0x8e, 32)...)
expected = append(expected, repeat(0x8f, 32)...)
expected = append(expected, repeat(0x90, 32)...)

expectedSerializationEqual(t, buf.Bytes(), expected)

Expand Down Expand Up @@ -168,7 +181,9 @@ func TestMsgMixSecretsMaxPayloadLength(t *testing.T) {
MaxMixMcount*varBytesLen(MaxMixFieldValLen) + // Unpadded SR values
uint32(VarIntSerializeSize(MaxMixMcount)) + // DC-net message count
uint32(VarIntSerializeSize(MixMsgSize)) + // DC-net message size
MaxMixMcount*MixMsgSize // DC-net messages
MaxMixMcount*MixMsgSize + // DC-net messages
uint32(VarIntSerializeSize(MaxMixPeers)) + // RS count
32*MaxMixPeers // RS hashes

tests := []struct {
name string
Expand Down
Loading