Files
zeekay 5106e6b61a feat: BLS threshold + security hardening + ZapDB KMS-backing
Security (from red team review):
- Replay protection: request_id + timestamp freshness on sign API
- Ed25519 message auth re-enabled on all protocol messages
- DKG timeout (5min) + signing timeout (30s) with watchdog
- Dedup map TTL cleanup (10min expiry, 2min sweep)

BLS threshold signing:
- KeyTypeBLS + keygen/signing sessions
- TrustedDealer pattern for BLS DKG
- CBOR serialization for BLS config
- 8 tests

ZapDB KMS-backing:
- HSM PasswordProvider wired to ZapDB init
- Supports: AWS KMS, GCP KMS, Azure KV, env, file
- Default env for backward compat
- 19 tests

Also: sr25519 sessions, fixed SignWireMessage build break
2025-12-27 21:54:46 -08:00

55 lines
1.5 KiB
Go

package types
import (
"crypto/ed25519"
"crypto/sha256"
"fmt"
)
// Message represents a protocol message
type Message struct {
SessionID string `json:"session_id"`
SenderID string `json:"sender_id"`
SenderNodeID string `json:"sender_node_id,omitempty"` // Raw node ID for key lookup
RecipientIDs []string `json:"recipient_ids"`
Body []byte `json:"body"`
IsBroadcast bool `json:"is_broadcast"`
Signature []byte `json:"signature,omitempty"` // Ed25519 signature over signable fields
}
// SignableBytes returns a deterministic byte representation of the message
// fields that are covered by the signature. The signature field itself is
// excluded.
func (m *Message) SignableBytes() []byte {
h := sha256.New()
h.Write([]byte(m.SessionID))
h.Write([]byte(m.SenderID))
h.Write([]byte(m.SenderNodeID))
for _, r := range m.RecipientIDs {
h.Write([]byte(r))
}
h.Write(m.Body)
if m.IsBroadcast {
h.Write([]byte{1})
} else {
h.Write([]byte{0})
}
return h.Sum(nil)
}
// Sign signs the message with the given Ed25519 private key.
func (m *Message) Sign(privateKey ed25519.PrivateKey) {
m.Signature = ed25519.Sign(privateKey, m.SignableBytes())
}
// Verify checks the message signature against the given Ed25519 public key.
func (m *Message) Verify(publicKey ed25519.PublicKey) error {
if len(m.Signature) == 0 {
return fmt.Errorf("message has no signature")
}
if !ed25519.Verify(publicKey, m.SignableBytes(), m.Signature) {
return fmt.Errorf("invalid message signature from %s", m.SenderNodeID)
}
return nil
}