shadow_types.go raw

   1  package crypto
   2  
   3  import (
   4  	"git.mleku.dev/mleku/dendrite/pkg/ratio"
   5  	"git.mleku.dev/mleku/dendrite/pkg/state"
   6  )
   7  
   8  // ShadowElement wraps an encrypted hexagram token as a lattice element.
   9  // Each element carries phase-derived permutation and projection data
  10  // that entangles the message with the binary/decimal shadow channel.
  11  type ShadowElement struct {
  12  	Index      int            // position in the token stream
  13  	Encrypted  state.Hexagram // phase-rotated hexagram (6-bit)
  14  	ProjVertex uint8          // derived from phase denominator mod 8
  15  	ProjKey    uint8          // derived from |phase numerator| mod 8
  16  	ProjPath   uint16         // index in token stream
  17  	PermIdx    uint8          // S_3 index derived from phase
  18  	TypeTag    string         // constraint layer tag
  19  }
  20  
  21  func (e ShadowElement) Type() string            { return e.TypeTag }
  22  func (e ShadowElement) Value() any              { return e.Encrypted }
  23  func (e ShadowElement) Permutation() uint8      { return e.PermIdx }
  24  func (e ShadowElement) ProjectionVertex() uint8 { return e.ProjVertex }
  25  func (e ShadowElement) ProjectionKey() uint8    { return e.ProjKey }
  26  func (e ShadowElement) ProjectionPath() uint16  { return e.ProjPath }
  27  
  28  // ShadowCiphertext is a message encrypted via the binary/decimal shadow
  29  // channel. The plaintext is hexagram-encoded, phase-permuted, and
  30  // crystallized into a lattice.
  31  type ShadowCiphertext struct {
  32  	Sites      []SiteMark    // bonding pattern after grow + dissolve
  33  	Noise      []NoiseSample // dissolution events (error term)
  34  	Params     Params        // crypto parameters used
  35  	Basis      *Basis        // public key basis
  36  	Nonce      Hamadryad     // unique per message
  37  	EpochDec   int           // epoch decimal exponent
  38  	EpochBin   int           // epoch binary exponent
  39  	TokenCount int           // number of hexagram tokens
  40  	OrigLen    int           // original plaintext byte count
  41  }
  42  
  43  // ShadowCompressed is the output of shadow compression: Huffman-coded
  44  // hexagram stream with auxiliary data encoded in the permutation
  45  // pair shadow channel.
  46  type ShadowCompressed struct {
  47  	// Primary is the Huffman-coded hexagram bitstream.
  48  	Primary []byte
  49  
  50  	// Shadow is the packed permutation pair indices (6 bits each).
  51  	// Each index selects one of 36 S_3×S_3 pairs; deviation from
  52  	// the phase-determined "home" pair encodes auxiliary bits.
  53  	Shadow []byte
  54  
  55  	// FreqTable holds hexagram symbol frequencies for Huffman tree
  56  	// reconstruction. 64 entries (one per hexagram value).
  57  	FreqTable [64]uint32
  58  
  59  	// Epoch parameters for phase schedule reconstruction.
  60  	EpochDec int
  61  	EpochBin int
  62  
  63  	// OrigLen is the original data length in bytes.
  64  	OrigLen int
  65  
  66  	// TokenCount is the number of hexagram tokens.
  67  	TokenCount int
  68  
  69  	// ShadowPayloadLen is the length of auxiliary data embedded
  70  	// in the shadow channel.
  71  	ShadowPayloadLen int
  72  
  73  	// ContentHash is the Hamadryad hash of the original data
  74  	// for integrity verification.
  75  	ContentHash Hamadryad
  76  }
  77  
  78  // CompressRatio returns the compression ratio as an exact rational
  79  // (compressed size / original size).
  80  func (sc *ShadowCompressed) CompressRatio() ratio.Ratio {
  81  	if sc.OrigLen == 0 {
  82  		return ratio.Zero
  83  	}
  84  	compressed := int64(len(sc.Primary) + len(sc.Shadow) + shadowCompressedHeaderSize)
  85  	return ratio.New(compressed, int64(sc.OrigLen))
  86  }
  87  
  88  // shadowCompressedHeaderSize is the fixed overhead of the wire format.
  89  // Magic(4) + OrigLen(4) + TokenCount(4) + EpochDec(2) + EpochBin(2)
  90  // + PrimaryLen(4) + ShadowLen(4) + ShadowPayloadLen(4)
  91  // + FreqTable(256) + ContentHash(56) = 340 bytes.
  92  const shadowCompressedHeaderSize = 340
  93