Class CdirMessage

java.lang.Object
net.vincent.communidirect.common.proto.CdirMessage

public final class CdirMessage extends Object
Codec for the CDIR v1 message protocol.

Wire format (all integers big-endian)

  Offset  Size  Field
  ------  ----  -----------------------------------------------
       0     4  Magic            0x43 0x44 0x49 0x52  ("CDIR")
       4     1  Version          0x01
       5    64  Signature        Ed25519 sig over payload plaintext
      69    32  Sender PubKey    Raw 32-byte Ed25519 public key
     101   256  Sealed Sess. Key XOR-wrapped 32-byte session key, zero-padded
     357     4  Payload Length   Unsigned 32-bit big-endian int
     361   var  XORed Payload    Payload XOR'd with repeating session key
 

Session key wrapping

Because Ed25519 is a signing algorithm (not a KEM), the session key is wrapped using a key-derivation function over the recipient's public key:
   wrapKey  = SHA-256(recipientRawPubKey32)          // 32 bytes
   sealed   = XOR(sessionKey32, wrapKey)             // 32 bytes
   wire[0..31] = sealed; wire[32..255] = 0x00        // 256 bytes total
 
The recipient unseals by computing SHA-256(ownRawPubKey32) and XOR-ing it against the first 32 bytes of the field.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Total size of the fixed message header in bytes: 361 (4 + 1 + 64 + 32 + 256 + 4).
    static final int
    Four ASCII bytes "CDIR" interpreted as a big-endian int.
    final byte[]
    Decrypted (plaintext) payload bytes.
    final String
    Hex-encoded SHA-256 digest of the sender's raw public key – used as a human-readable identity label in stored message headers.
    final byte[]
    32-byte raw Ed25519 public key of the sender.
    static final byte
    Protocol version byte: 0x01 for CDIR v1.
  • Method Summary

    Modifier and Type
    Method
    Description
    decode(InputStream in, PrivateKey recipientPrivKey, byte[] recipientPubRaw)
    Reads one CDIR frame from in, verifies its signature, decrypts the payload and returns a populated CdirMessage.
    static void
    encode(byte[] payload, PrivateKey senderPrivKey, byte[] senderPubKeyRaw, byte[] recipientPubRaw, OutputStream out)
    Encodes a plaintext payload into a CDIR frame and writes it to out.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • MAGIC

      public static final int MAGIC
      Four ASCII bytes "CDIR" interpreted as a big-endian int.
      See Also:
    • VERSION

      public static final byte VERSION
      Protocol version byte: 0x01 for CDIR v1.
      See Also:
    • HEADER_SIZE

      public static final int HEADER_SIZE
      Total size of the fixed message header in bytes: 361 (4 + 1 + 64 + 32 + 256 + 4).
      See Also:
    • senderPubKeyRaw

      public final byte[] senderPubKeyRaw
      32-byte raw Ed25519 public key of the sender.
    • payload

      public final byte[] payload
      Decrypted (plaintext) payload bytes.
    • senderPubKeyHash

      public final String senderPubKeyHash
      Hex-encoded SHA-256 digest of the sender's raw public key – used as a human-readable identity label in stored message headers.
  • Method Details

    • encode

      public static void encode(byte[] payload, PrivateKey senderPrivKey, byte[] senderPubKeyRaw, byte[] recipientPubRaw, OutputStream out) throws Exception
      Encodes a plaintext payload into a CDIR frame and writes it to out.
      Parameters:
      payload - plaintext bytes to send
      senderPrivKey - sender's Ed25519 private key (for signing)
      senderPubKeyRaw - sender's 32-byte raw Ed25519 public key
      recipientPubRaw - recipient's 32-byte raw Ed25519 public key (used to wrap the session key)
      out - destination stream
      Throws:
      Exception - on any crypto or IO failure
    • decode

      public static CdirMessage decode(InputStream in, PrivateKey recipientPrivKey, byte[] recipientPubRaw) throws Exception
      Reads one CDIR frame from in, verifies its signature, decrypts the payload and returns a populated CdirMessage.
      Parameters:
      in - source stream (must be positioned at the first magic byte)
      recipientPrivKey - server's Ed25519 private key (unused for Ed25519 KEM – kept for future asymmetric upgrade)
      recipientPubRaw - server's own 32-byte raw Ed25519 public key (used to unseal the session key)
      Returns:
      decoded, signature-verified message
      Throws:
      IOException - on read errors
      SignatureException - if the Ed25519 signature does not verify
      Exception - on any other crypto or protocol error