Files
corona/threshold/codec_dos_test.go
zeekayandHanzo Dev 2cf43a239b corona: comments state the contract the code holds
The frame walkers and the boundary checks around them explained themselves by
recounting what a malformed frame did before they existed, in one case with
enough detail to reconstruct it. A comment is read by whoever maintains the
code, and what they need is the rule: a count is worth only the bytes behind
it, membership is checked before shape because shape is what the kernels size
themselves from, a Poly carries its own counts and so is walked like the rest.

No behaviour changes; every line here is a comment.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-26 13:15:44 -07:00

121 lines
3.8 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package threshold
import (
"encoding/binary"
"testing"
)
// TestAPeerCannotEndTheProcessWithALength pins what a signature frame is held
// to: every count in it must be backed by bytes that are present. The lattice
// decoder sizes its allocations from those counts, so each frame is walked
// before it is decoded and one whose arithmetic does not close is refused.
func TestAPeerCannotEndTheProcessWithALength(t *testing.T) {
le := func(n uint64) []byte {
var b [8]byte
binary.LittleEndian.PutUint64(b[:], n)
return b[:]
}
lenPrefixed := func(body []byte) []byte {
var l [4]byte
binary.BigEndian.PutUint32(l[:], uint32(len(body)))
return append(l[:], body...)
}
// A vector naming polys, levels and coefficients, with no bytes behind them.
claim := func(polys, levels, n uint64) []byte {
return append(append(le(polys), le(levels)...), le(n)...)
}
// C is a single Poly, not a vector, so it carries only levels and
// coefficients.
polyClaim := func(levels, n uint64) []byte {
return append(le(levels), le(n)...)
}
sigFrame := func(c, z, delta []byte) []byte {
var out []byte
var m [4]byte
binary.BigEndian.PutUint32(m[:], wireMagicSig)
out = append(out, m[:]...)
var v [2]byte
binary.BigEndian.PutUint16(v[:], wireVersionV1)
out = append(out, v[:]...)
out = append(out, lenPrefixed(c)...)
out = append(out, lenPrefixed(z)...)
return append(out, lenPrefixed(delta)...)
}
honest := claim(1, 1, 0)
for _, tc := range []struct {
name string
frame []byte
}{
{"Z names 2^40 coefficients", sigFrame(honest, claim(1, 1, 1<<40), honest)},
{"Delta names 2^40 coefficients", sigFrame(honest, honest, claim(1, 1, 1<<40))},
{"Z names 2^40 polys", sigFrame(honest, claim(1<<40, 1, 1), honest)},
{"Z names 2^40 levels", sigFrame(honest, claim(1, 1<<40, 1), honest)},
{"C names 2^40 coefficients", sigFrame(polyClaim(1, 1<<40), honest, honest)},
{"C names 2^40 levels", sigFrame(polyClaim(1<<40, 1), honest, honest)},
} {
t.Run(tc.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("%d bytes from a peer reached the decoder: %v", len(tc.frame), r)
}
}()
var s Signature
if err := s.UnmarshalBinary(tc.frame); err == nil {
t.Fatal("a frame describing bytes that are not there was accepted")
}
})
}
}
// A group key's A is a matrix, so its rows and their contents are held to the
// same rule.
func TestAGroupKeysMatrixCannotEndTheProcess(t *testing.T) {
le := func(n uint64) []byte {
var b [8]byte
binary.LittleEndian.PutUint64(b[:], n)
return b[:]
}
lenPrefixed := func(body []byte) []byte {
var l [4]byte
binary.BigEndian.PutUint32(l[:], uint32(len(body)))
return append(l[:], body...)
}
keyFrame := func(a, b []byte) []byte {
var out []byte
var m [4]byte
binary.BigEndian.PutUint32(m[:], wireMagicGroupKey)
out = append(out, m[:]...)
var v [2]byte
binary.BigEndian.PutUint16(v[:], wireVersionV1)
out = append(out, v[:]...)
out = append(out, lenPrefixed(a)...)
return append(out, lenPrefixed(b)...)
}
honestVec := append(append(le(1), le(1)...), le(0)...)
for _, tc := range []struct {
name string
a []byte
}{
{"2^40 rows", le(1 << 40)},
{"one row of 2^40 polys", append(le(1), le(1<<40)...)},
{"one poly of 2^40 coefficients", append(append(le(1), le(1)...), append(le(1), le(1<<40)...)...)},
} {
t.Run(tc.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("a group key from a peer reached the decoder: %v", r)
}
}()
var gk GroupKey
if err := gk.UnmarshalBinary(keyFrame(tc.a, honestVec)); err == nil {
t.Fatal("a matrix describing bytes that are not there was accepted")
}
})
}
}