Skip to content

Instantly share code, notes, and snippets.

@afflom
Created August 23, 2025 05:49
Show Gist options
  • Save afflom/56d3a2d94795f793263de75a675c48d8 to your computer and use it in GitHub Desktop.
Save afflom/56d3a2d94795f793263de75a675c48d8 to your computer and use it in GitHub Desktop.
Coherent Data Protocol (CDP) Rust Spec
# path: cdp/Cargo.toml
[package]
name = "cdp"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0 OR MIT"
description = "Coherent Data Protocol (CDP) over the UOR/PrimeOS hologram with FFI-backed proofs"
repository = "https://example.com/uor/cdp"
readme = "README.md"
categories = ["encoding", "network-programming", "cryptography"]
keywords = ["UOR", "PrimeOS", "CDP", "hologram", "FFI"]

[features]
default = ["std", "ffi-uor"]
std = []
# Use the Rust wrapper crate `uorffi` (recommended)
ffi-uor = ["dep:uorffi"]
# Optional async integration layers
tokio = ["dep:tokio"]
quic = ["dep:quinn", "tokio"]

[dependencies]
anyhow = "1"
thiserror = "1"
zerocopy = "0.7"
bytes = "1"
serde = { version = "1", features = ["derive"], optional = true }
uorffi = { version = "0.1", optional = true, package = "uorffi" }
tokio = { version = "1", optional = true, features = ["rt-multi-thread", "macros", "io-util"] }
quinn = { version = "0.11", optional = true }

[dev-dependencies]
rand = "0.8"
hex = "0.4"
# path: cdp/README.md
# CDP — Coherent Data Protocol (Rust)

This crate implements the **Coherent Data Protocol (CDP)** on top of the UOR/PrimeOS hologram,
delegating all invariants and proofs to the Lean core via the **Rust FFI wrapper (`uorffi`)**.

## Design (normative; RFC 2119)

* CDP **MUST** segment payloads into windows of size `PAGES * BYTES`, where `PAGES = 48` and `BYTES = 256`.
  These constants **MUST** be taken from the FFI (`uorffi::pages()`, `uorffi::bytes()`).
* A window **MUST** be **closed** by the canonical closure routine provided by the FFI before hashing or transmission.
* For each window, implementations **MUST** compute per-page hashes and a Merkle **root** via the FFI.
* A **UOR-ID** **MUST** be constructed with the Merkle root and the layout order; receivers **MUST** verify it.
* CDP frames **MUST** fail-closed: any mismatch in closure, hash, root, or ID **MUST** be rejected.
* Protocol handshake consists of `HELLO`, `SELECT`, `ATTEST`, followed by `DATA` frames carrying the CEF record.
  (This crate provides a stable wire structure and encoder/decoder for these frames.)

## Public API surface

```rust
use cdp::{CdpConfig, CdpFrame, encode_segment, verify_frame};

See examples/pack.rs for a minimal pack/verify demonstration.

Optional transport

Enable --features quic to get a QUIC stream multiplexer with CDP framing. The transport is thin: it frames CDP messages and calls the same FFI-backed verifiers.

Safety & trust

All cryptographic/arithmetical invariants are executed by the Lean-proof-backed FFI via uorffi. This crate does not re-implement those checks; it only frames bytes on the wire.


```rust
// path: cdp/src/lib.rs
#![deny(missing_docs)]
//! CDP — Coherent Data Protocol over the UOR/PrimeOS hologram.
//!
//! This crate frames bytes into **coherent** windows and defers all invariants (closure, hashing,
//! Merkle root, UOR-ID, R96) to the Lean-backed FFI via the Rust wrapper `uorffi`.
//!
//! ## Quickstart
//! ```no_run
//! use cdp::{encode_segment, verify_frame, CdpConfig};
//! let cfg = CdpConfig::default();
//! let mut segment = [0u8; 12_288]; // fill with your data (<= 12_288)
//! let frame = encode_segment(&cfg, &segment).unwrap();
//! verify_frame(&cfg, &frame).unwrap();
//! ```

mod types;
mod wire;
mod ffi;        // the adapter over the `uorffi` crate
mod verify;
mod codec;

pub use types::{CdpError, CdpConfig, CdpFrame, CefRecord, HandshakeHello, HandshakeSelect, HandshakeAttest};
pub use verify::{encode_segment, verify_frame};
pub use codec::{encode_message, decode_message, Message};

#[cfg(feature = "quic")]
pub mod quic; // transport integrations (optional)
// path: cdp/src/types.rs
use thiserror::Error;
use zerocopy::{FromBytes, AsBytes};
use serde::{Serialize, Deserialize};

/// CDP configuration.
#[derive(Clone, Debug)]
pub struct CdpConfig {
    /// true => cycle-major (0), false => page-major (1)
    pub order_cycle_major: bool,
}

impl Default for CdpConfig {
    fn default() -> Self { Self { order_cycle_major: true } }
}

/// CDP error kinds.
#[derive(Debug, Error)]
pub enum CdpError {
    #[error("FFI error: {0}")]
    Ffi(String),
    #[error("Merkle root mismatch")]
    RootMismatch,
    #[error("Closure failure")]
    ClosureFailure,
    #[error("R96 checksum mismatch (expected {expected}, got {got})")]
    R96Mismatch { expected: u32, got: u32 },
    #[error("Malformed frame: {0}")]
    Malformed(&'static str),
}

/// Coherent Exchange Format (CEF) record (base profile).
#[repr(C)]
#[derive(Clone, Copy, FromBytes, AsBytes)]
pub struct CefRecord {
    /// Version (1)
    pub version: u8,
    /// Layout order: 0 = cycle-major, 1 = page-major
    pub order: u8,
    /// Total length in bytes (always 12288 for base profile)
    pub length_be: u16,
    /// 48 * 256 payload (closed)
    pub payload: [u8; 48 * 256],
    /// Page-closure witness (reserved; zero in base profile)
    pub pcw: [u8; 48],
    /// Leaf count (256)
    pub leaf_count_be: u32,
    /// Merkle root (SHA-256)
    pub root: [u8; 32],
}

impl Default for CefRecord {
    fn default() -> Self {
        Self {
            version: 1,
            order: 0,
            length_be: (48u16 * 256u16).to_be(),
            payload: [0; 48*256],
            pcw: [0; 48],
            leaf_count_be: (256u32).to_be(),
            root: [0; 32],
        }
    }
}

/// A complete CDP frame: UOR-ID + CEF + optional R96 checksum.
#[derive(Clone)]
pub struct CdpFrame {
    /// UOR-ID bytes (encoded by FFI)
    pub uor_id: Vec<u8>,
    /// CEF record
    pub cef: CefRecord,
    /// Optional integrity checksum over payload (sum of R96 classes mod 96)
    pub r96_sum: u32,
}

/// HELLO message (capabilities advertisement).
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct HandshakeHello {
    /// Protocol version (1)
    pub version: u8,
    /// Supported layout orders (bit 0: cycle-major, bit 1: page-major)
    pub layout_caps: u8,
}

/// SELECT message (parameter selection).
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct HandshakeSelect {
    /// Chosen layout order (0 or 1)
    pub order: u8,
}

/// ATTEST message (integrity attestation).
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct HandshakeAttest {
    /// Echoed Merkle root to be used for the next DATA frame (optional)
    pub next_root: Option<[u8; 32]>,
}
// path: cdp/src/wire.rs
//! Wire-level CDP message encoding.
//! Stable on-the-wire envelopes for HELLO/SELECT/ATTEST/DATA.

use bytes::{BytesMut, BufMut, Bytes};
use crate::types::*;

const MSG_HELLO: u8 = 0x01;
const MSG_SELECT: u8 = 0x02;
const MSG_ATTEST: u8 = 0x03;
const MSG_DATA: u8 = 0x04;

/// A framed CDP message.
#[derive(Clone)]
pub enum Message {
    /// HELLO {version, layout_caps}
    Hello(HandshakeHello),
    /// SELECT {order}
    Select(HandshakeSelect),
    /// ATTEST {next_root?}
    Attest(HandshakeAttest),
    /// DATA {UOR-ID, CEF, r96_sum}
    Data(CdpFrame),
}

pub fn encode_message(msg: &Message) -> Bytes {
    let mut out = BytesMut::new();
    match msg {
        Message::Hello(h) => {
            out.put_u8(MSG_HELLO);
            out.put_u8(h.version);
            out.put_u8(h.layout_caps);
        }
        Message::Select(s) => {
            out.put_u8(MSG_SELECT);
            out.put_u8(s.order);
        }
        Message::Attest(a) => {
            out.put_u8(MSG_ATTEST);
            match a.next_root {
                None => { out.put_u8(0); }
                Some(root) => { out.put_u8(1); out.extend_from_slice(&root); }
            }
        }
        Message::Data(f) => {
            out.put_u8(MSG_DATA);
            // UOR-ID (length-prefixed)
            out.put_u16(f.uor_id.len() as u16);
            out.extend_from_slice(&f.uor_id);
            // CEF
            out.extend_from_slice(f.cef.as_bytes());
            // r96 checksum (u8; modulo 96)
            out.put_u8((f.r96_sum % 96) as u8);
        }
    }
    out.freeze()
}

pub fn decode_message(mut bytes: Bytes) -> anyhow::Result<Message> {
    use anyhow::{ensure, bail};
    ensure!(bytes.len() >= 1, "empty frame");
    let tag = bytes[0];
    bytes.advance(1);

    match tag {
        MSG_HELLO => {
            anyhow::ensure!(bytes.len() >= 2, "HELLO too short");
            Ok(Message::Hello(HandshakeHello{ version: bytes[0], layout_caps: bytes[1] }))
        }
        MSG_SELECT => {
            anyhow::ensure!(bytes.len() >= 1, "SELECT too short");
            Ok(Message::Select(HandshakeSelect{ order: bytes[0] }))
        }
        MSG_ATTEST => {
            anyhow::ensure!(bytes.len() >= 1, "ATTEST too short");
            let flag = bytes[0]; bytes.advance(1);
            if flag == 0 {
                Ok(Message::Attest(HandshakeAttest{ next_root: None }))
            } else {
                anyhow::ensure!(bytes.len() >= 32, "ATTEST root missing");
                let mut root = [0u8; 32];
                root.copy_from_slice(&bytes[..32]);
                Ok(Message::Attest(HandshakeAttest{ next_root: Some(root) }))
            }
        }
        MSG_DATA => {
            use zerocopy::FromBytes;
            anyhow::ensure!(bytes.len() >= 2, "DATA too short");
            let id_len = u16::from_be_bytes([bytes[0], bytes[1]]) as usize;
            bytes.advance(2);
            anyhow::ensure!(bytes.len() >= id_len, "UOR-ID truncated");
            let uor_id = bytes.split_to(id_len).to_vec();

            anyhow::ensure!(bytes.len() >= core::mem::size_of::<CefRecord>(), "CEF truncated");
            let mut cef = CefRecord::default();
            let cef_bytes_len = core::mem::size_of::<CefRecord>();
            cef.as_bytes_mut().copy_from_slice(&bytes[..cef_bytes_len]);
            bytes.advance(cef_bytes_len);

            anyhow::ensure!(bytes.len() >= 1, "missing R96 sum");
            let r96_sum = bytes[0] as u32;

            Ok(Message::Data(CdpFrame{ uor_id, cef, r96_sum }))
        }
        _ => bail!("unknown tag: {tag:#x}"),
    }
}
// path: cdp/src/ffi.rs
//! Adapter over the Rust FFI wrapper crate (`uorffi`).
//!
//! All methods here are thin delegations. If you need to mock for tests,
//! implement `HoloCore` for your own struct.

use crate::types::CdpError;

/// Abstraction over the FFI to allow mocking in tests.
pub trait HoloCore: Clone + Send + Sync + 'static {
    fn pages(&self) -> u32;
    fn bytes(&self) -> u32;
    fn rclasses(&self) -> u32;
    fn r96(&self, b: u8) -> u8;

    /// Close both axes in-place; returns Ok on success.
    fn pad_close_48x256(&self, buf: &mut [u8; 48*256]) -> Result<(), CdpError>;

    /// Fill leaf hashes (256 * 32) and root (32) using canonical SHA-256.
    fn page_hashes_sha256(&self, payload_48x256: &[u8; 48*256], leaf_hashes_out: &mut [u8; 256*32]);

    fn merkle_root_sha256(&self, leaf_hashes: &[u8; 256*32], root_out: &mut [u8; 32]);

    /// Encode UOR-ID into `out`, returns used length.
    fn uor_id_encode(&self, order: u8, root32: &[u8; 32], w_alg: u8, cw: &[u8], out: &mut [u8]) -> Result<usize, CdpError>;
}

#[derive(Clone, Default)]
pub struct UorFfiCore;

#[cfg(feature = "ffi-uor")]
impl HoloCore for UorFfiCore {
    fn pages(&self) -> u32 { uorffi::pages() }
    fn bytes(&self) -> u32 { uorffi::bytes() }
    fn rclasses(&self) -> u32 { uorffi::rclasses() }
    fn r96(&self, b: u8) -> u8 { uorffi::r96(b) }

    fn pad_close_48x256(&self, buf: &mut [u8; 48*256]) -> Result<(), CdpError> {
        if uorffi::pad_close_48x256(buf.as_mut_ptr()) { Ok(()) } else { Err(CdpError::ClosureFailure) }
    }

    fn page_hashes_sha256(&self, payload: &[u8; 48*256], leaf_hashes_out: &mut [u8; 256*32]) {
        uorffi::page_hashes_sha256(payload.as_ptr(), leaf_hashes_out.as_mut_ptr());
    }

    fn merkle_root_sha256(&self, leaf_hashes: &[u8; 256*32], root_out: &mut [u8; 32]) {
        uorffi::merkle_root_sha256(leaf_hashes.as_ptr(), root_out.as_mut_ptr());
    }

    fn uor_id_encode(&self, order: u8, root32: &[u8; 32], w_alg: u8, cw: &[u8], out: &mut [u8]) -> Result<usize, CdpError> {
        let mut out_len: u16 = 0;
        let ok = uorffi::uor_id_encode(order, root32.as_ptr(), w_alg, if cw.is_empty() { core::ptr::null() } else { cw.as_ptr() }, cw.len() as u8, out.as_mut_ptr(), &mut out_len as *mut u16);
        if ok { Ok(out_len as usize) } else { Err(CdpError::Ffi("uor_id_encode".into())) }
    }
}

/// Simple R96 checksum helper (sum of classes mod 96).
pub(crate) fn r96_checksum<F: HoloCore>(ffi: &F, bytes: &[u8]) -> u32 {
    let mut acc: u32 = 0;
    for &b in bytes {
        acc = (acc + (ffi.r96(b) as u32)) % 96;
    }
    acc
}
// path: cdp/src/verify.rs
//! Encode/verify routines that call into the FFI.

use crate::{types::*, ffi::{HoloCore, UorFfiCore, r96_checksum}};

/// Encode a 12,288-byte segment into a CDP frame (UOR-ID + CEF + r96_sum).
///
/// *Closes* the payload via FFI, computes per-page hashes → Merkle root,
/// then builds UOR-ID and CEF. Fails-closed on any error.
///
/// The `segment` **MUST** be exactly `48*256` bytes.
pub fn encode_segment(cfg: &CdpConfig, segment: &[u8; 48*256]) -> Result<CdpFrame, CdpError> {
    encode_with::<UorFfiCore>(cfg, segment, &UorFfiCore::default())
}

/// Same as `encode_segment`, but allows a custom FFI core (mock/testing).
pub fn encode_with<F: HoloCore>(cfg: &CdpConfig, segment: &[u8; 48*256], core: &F) -> Result<CdpFrame, CdpError> {
    // Sanity: confirm FFI constants (fail fast if drift)
    if core.pages() != 48 || core.bytes() != 256 || core.rclasses() != 96 {
        return Err(CdpError::Ffi("dimension mismatch".into()));
    }

    // (1) Copy and close
    let mut payload = *segment;
    core.pad_close_48x256(&mut payload)?;

    // (2) Hash pages → leaf set (256 × 32)
    let mut leaves = [0u8; 256 * 32];
    core.page_hashes_sha256(&payload, &mut leaves);

    // (3) Merkle root
    let mut root = [0u8; 32];
    core.merkle_root_sha256(&leaves, &mut root);

    // (4) UOR-ID
    let order: u8 = if cfg.order_cycle_major { 0 } else { 1 };
    let mut id_buf = [0u8; 96];
    let used = core.uor_id_encode(order, &root, /*w_alg=*/1, &[], &mut id_buf)?;
    let uor_id = id_buf[..used].to_vec();

    // (5) CEF
    let mut cef = CefRecord::default();
    cef.order = order;
    cef.payload.copy_from_slice(&payload);
    cef.root.copy_from_slice(&root);

    // (6) Optional checksum
    let r96_sum = r96_checksum(core, &cef.payload);
    Ok(CdpFrame { uor_id, cef, r96_sum })
}

/// Verify a CDP frame (fail-closed).
///
/// Recomputes closure and Merkle root via FFI and compares to the frame.
/// Optionally verifies the R96 checksum (always-on in this reference impl).
pub fn verify_frame(cfg: &CdpConfig, frame: &CdpFrame) -> Result<(), CdpError> {
    verify_with::<UorFfiCore>(cfg, frame, &UorFfiCore::default())
}

/// Same as `verify_frame`, but allows a custom FFI core (mock/testing).
pub fn verify_with<F: HoloCore>(_cfg: &CdpConfig, frame: &CdpFrame, core: &F) -> Result<(), CdpError> {
    if core.pages() != 48 || core.bytes() != 256 || core.rclasses() != 96 {
        return Err(CdpError::Ffi("dimension mismatch".into()));
    }

    // Recompute root
    let mut leaves = [0u8; 256 * 32];
    core.page_hashes_sha256(&frame.cef.payload, &mut leaves);
    let mut root = [0u8; 32];
    core.merkle_root_sha256(&leaves, &mut root);
    if root != frame.cef.root {
        return Err(CdpError::RootMismatch);
    }

    // Re-run closure on a copy (must succeed without changing root)
    let mut tmp = frame.cef.payload;
    core.pad_close_48x256(&mut tmp)?;

    // Verify R96 checksum
    let got = r96_checksum(core, &frame.cef.payload);
    if got != (frame.r96_sum % 96) {
        return Err(CdpError::R96Mismatch { expected: frame.r96_sum % 96, got });
    }

    Ok(())
}
// path: cdp/src/codec.rs
//! Streaming codec helpers (stateless).

pub use crate::wire::{Message, encode_message, decode_message};
// path: cdp/src/quic.rs
//! Optional QUIC transport: frames CDP messages on a bidirectional stream.

use anyhow::Result;
use bytes::Bytes;
use quinn::{RecvStream, SendStream};
use crate::wire::{Message, encode_message, decode_message};

/// Send a CDP message over a QUIC stream with length-prefix framing.
pub async fn send(mut send: SendStream, msg: &Message) -> Result<()> {
    let bytes = encode_message(msg);
    let len = bytes.len() as u32;
    send.write_all(&len.to_be_bytes()).await?;
    send.write_all(&bytes).await?;
    send.flush().await?;
    Ok(())
}

/// Receive a CDP message over a QUIC stream with length-prefix framing.
pub async fn recv(mut recv: RecvStream) -> Result<Message> {
    use tokio::io::AsyncReadExt;
    let mut len_buf = [0u8; 4];
    recv.read_exact(&mut len_buf).await?;
    let len = u32::from_be_bytes(len_buf) as usize;
    let mut buf = vec![0u8; len];
    recv.read_exact(&mut buf).await?;
    decode_message(Bytes::from(buf)).map_err(Into::into)
}
// path: cdp/examples/pack.rs
//! Minimal example: pack + verify a single window.

use cdp::{CdpConfig, encode_segment, verify_frame};

fn main() -> anyhow::Result<()> {
    let cfg = CdpConfig::default();
    // In practice, fill this with your payload; it will be closed by FFI.
    let mut segment = [0u8; 48*256];
    for (i, b) in segment.iter_mut().enumerate() { *b = (i % 251) as u8; }

    let frame = encode_segment(&cfg, &segment)?;
    println!("UOR-ID ({} bytes)", frame.uor_id.len());
    println!("Root: {}", hex::encode(frame.cef.root));
    verify_frame(&cfg, &frame)?;
    println!("verify: OK");
    Ok(())
}
// path: cdp/tests/integration.rs
use cdp::{CdpConfig, encode_segment, verify_frame};

#[test]
fn pack_and_verify_roundtrip() {
    let cfg = CdpConfig::default();
    let mut segment = [0u8; 48*256];
    for (i, b) in segment.iter_mut().enumerate() { *b = (i % 251) as u8; }
    let frame = encode_segment(&cfg, &segment).expect("encode");
    verify_frame(&cfg, &frame).expect("verify");
    assert_eq!(frame.cef.version, 1);
    assert!(matches!(frame.cef.order, 0 | 1));
    assert_eq!(u16::from_be(frame.cef.length_be), 12_288);
    assert_eq!(u32::from_be(frame.cef.leaf_count_be), 256);
}
# path: cdp/.gitignore
/target
**/*.rs.bk
Cargo.lock

Notes on the FFI wrapper uorffi

This CDP crate expects a Rust wrapper crate uorffi exposing these functions:

// Expected `uorffi` API (thin wrappers over Lean-exported C symbols)
pub fn pages() -> u32;               // 48
pub fn bytes() -> u32;               // 256
pub fn rclasses() -> u32;            // 96
pub fn r96(b: u8) -> u8;             // classify byte into 0..95

pub fn pad_close_48x256(buf: *mut u8) -> bool; // true on success
pub fn page_hashes_sha256(payload: *const u8, leaf_hashes_out: *mut u8);
pub fn merkle_root_sha256(leaves: *const u8, root_out: *mut u8);

pub fn uor_id_encode(order: u8,
                     root32: *const u8,
                     w_alg: u8,
                     cw_ptr: *const u8,
                     cw_len: u8,
                     out_buf: *mut u8,
                     out_len: *mut u16) -> bool;

If your current wrapper only has part of these, you can still use this CDP crate by providing a small compatibility layer inside uorffi that forwards to the Lean exports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment