chunked

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: AGPL-3.0 Imports: 2 Imported by: 0

Documentation

Overview

Package chunked implements the SPQR chunked-transport erasure code: a GF(2^16) Reed-Solomon-style fountain code (gf.go + polynomial.go) that ships a message as a stream of fixed 32-byte chunks reconstructible from any sufficient subset. It is a byte-exact pure-Go port of SparsePostQuantumRatchet v1.5.1 src/encoding/.

Index

Constants

View Source
const (
	// ChunkSize is the fixed byte length of an encoded chunk payload.
	ChunkSize = 32
	// NumPolys is the number of GF(2^16) polynomials the message is spread
	// across (= ChunkSize / 2, one big-endian u16 per polynomial per chunk).
	NumPolys = ChunkSize / 2 // 16
)

Variables

View Source
var ErrOddLength = errors.New("spqr/encoding: message length must be even")

ErrOddLength is returned when a message or declared length is not a multiple of 2 (the byte width of a GF(2^16) value). The upstream encoder/decoder require even lengths.

View Source
var ErrSerializationInvalid = errors.New("spqr/encoding: invalid serialized encoder/decoder")

ErrSerializationInvalid is returned when an Encoder/Decoder proto has a shape the codec cannot parse (wrong number of polynomial entries, a point list that is not a whole number of points, or both pts and polys populated). Mirrors the reference PolynomialError::SerializationInvalid.

Functions

func DecoderToProto

func DecoderToProto(d *Decoder) *proto.PolynomialDecoder

DecoderToProto serializes a Decoder to its PolynomialDecoder proto, mirroring PolyDecoder::into_pb. It always emits NumPolys (16) point lists, polys=16, and is_complete=false (the latch the reference never sets).

func EncoderToProto

func EncoderToProto(e *Encoder) *proto.PolynomialEncoder

EncoderToProto serializes an Encoder to its PolynomialEncoder proto. It mirrors PolyEncoder::into_pb: a not-yet-switched encoder emits its stored data points (Points state) in pts; a switched encoder emits its interpolated polynomial coefficients (Polys state) in polys. Exactly one of pts/polys is populated, each with NumPolys (16) entries.

Types

type Chunk

type Chunk struct {
	Index uint16
	Data  [ChunkSize]byte
}

Chunk is one encoded fragment: a 16-bit index and a fixed 32-byte payload of 16 big-endian GF(2^16) values.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder reassembles a message from received Chunks. It needs pointsNeeded total points (= messageLen/2), distributed across the 16 polynomials.

func DecoderFromProto

func DecoderFromProto(pb *proto.PolynomialDecoder) (*Decoder, error)

DecoderFromProto reconstructs a Decoder from a PolynomialDecoder proto, mirroring PolyDecoder::from_pb. pts must have exactly NumPolys (16) entries, each a whole number of 4-byte points.

func NewDecoder

func NewDecoder(msgLen int) (*Decoder, error)

NewDecoder builds a decoder for a message of msgLen bytes (must be even).

func (*Decoder) AddChunk

func (d *Decoder) AddChunk(c *Chunk)

AddChunk folds a received chunk's 16 points into the decoder state. A point is kept only if its index is small enough to help decode without interpolation, or if the polynomial does not yet have enough points — matching the upstream add_chunk retention rule.

func (*Decoder) DecodedMessage

func (d *Decoder) DecodedMessage() []byte

DecodedMessage attempts to reconstruct the message. It returns nil if not yet enough points have been received. The returned slice is pointsNeeded*2 bytes, each value big-endian.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder produces a stream of Chunks from a message. It lazily switches from returning stored data points (for indices within the original data) to evaluating interpolated polynomials (for indices beyond it), matching the upstream PolyEncoder.

func EncoderFromProto

func EncoderFromProto(pb *proto.PolynomialEncoder) (*Encoder, error)

EncoderFromProto reconstructs an Encoder from a PolynomialEncoder proto, mirroring PolyEncoder::from_pb. A non-empty pts decodes to the Points state (and polys must be empty); otherwise polys (which must have 16 entries) decodes to the Polys state. Any other shape is a serialization error.

func NewEncoder

func NewEncoder(msg []byte) (*Encoder, error)

NewEncoder builds an encoder for msg. msg length must be even.

func (*Encoder) ChunkAt

func (e *Encoder) ChunkAt(idx uint16) Chunk

ChunkAt returns the chunk at the given index: 16 big-endian GF(2^16) values, one from each polynomial, evaluated at x = idx.

func (*Encoder) NextChunk

func (e *Encoder) NextChunk() Chunk

NextChunk returns the next chunk in sequence (index 0, 1, 2, …).

type GF16

type GF16 struct {
	Value uint16
}

GF16 is an element of GF(2^16). Addition is XOR; multiplication is carryless multiply reduced mod gfPoly.

func NewGF16

func NewGF16(v uint16) GF16

NewGF16 wraps a raw 16-bit value as a field element.

func (GF16) Add

func (a GF16) Add(b GF16) GF16

Add returns a + b in GF(2^16), which is bitwise XOR.

func (GF16) Div

func (a GF16) Div(b GF16) GF16

Div returns a / b in GF(2^16) = a * b^(2^16-2) (Fermat inverse). Dividing by zero yields zero (matching the upstream square-and-multiply, which maps 0→0).

func (GF16) Mul

func (a GF16) Mul(b GF16) GF16

Mul returns a * b in GF(2^16): the carryless product reduced mod gfPoly.

func (GF16) Sub

func (a GF16) Sub(b GF16) GF16

Sub returns a - b in GF(2^16); in characteristic 2 subtraction equals addition (XOR).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL