Skip to content

Latest commit

 

History

History
131 lines (102 loc) · 4.59 KB

File metadata and controls

131 lines (102 loc) · 4.59 KB

Getting started

This walks the three-step path from raw bytes to a κ-label, then shows how κ-labels compose with the framework's structural guarantees.

1. Pick a realization

Each realization handles a specific data format. The choice is fixed by what your data already is; pick the row that matches the format you have on the wire.

use uor_addr::json::address as json_address;
use uor_addr::sexp::address as sexp_address;
use uor_addr::xml::address as xml_address;
use uor_addr::asn1::address as asn1_address;
use uor_addr::ring::address as ring_address;
use uor_addr::codemodule::address as codemodule_address;

For schema-typed data (photo metadata, articles, signed-software attestations) prefer the schema-pinned descendants — they add admission predicates without changing the κ-label.

use uor_addr::schema::photo::address as photo_address;
use uor_addr::schema::document::address as document_address;
use uor_addr::schema::codemodule_signed::address as signed_address;

See realizations.md for the full decision matrix.

2. Mint a κ-label

The address function takes raw bytes and returns an outcome carrying the wire-format κ-label plus a Grounded<AddressLabel> witness for downstream verification.

let outcome = uor_addr::json::address(br#"{"foo": "bar"}"#).unwrap();
println!("{}", outcome.address);
// sha256:7a38bf81f383f69433ad6e900d35b3e2385593f76a7b7ab5d4355b8ba41ee24b

The κ-label is deterministic — feed the same bytes twice, get the same label. It's also invariant under the format's canonical-form rules:

// JSON: whitespace, key order, NFC vs NFD all collapse.
let a = uor_addr::json::address(br#"{"a":1,"b":2}"#).unwrap().address;
let b = uor_addr::json::address(br#"{ "b" : 2 , "a" : 1 }"#).unwrap().address;
assert_eq!(a, b);

But it distinguishes typed values that look similar but mean different things:

let int = uor_addr::json::address(b"42").unwrap().address;
let str = uor_addr::json::address(br#""42""#).unwrap().address;
assert_ne!(int, str);

3. Verify a κ-label without re-hashing

Every address() call also emits a Grounded<AddressLabel> witness. Downstream consumers replay it through prism_verify::certify_from_trace to re-derive a Certified<GroundingCertificate> — the verifier sees the trace, not the original input, and does not invoke SHA-256 again.

let outcome = uor_addr::json::address(br#"{"foo": "bar"}"#).unwrap();
let grounded = outcome.witness.grounded();
// grounded.output_bytes() == outcome.address.as_bytes()
// The trace replay path is exercised by `tests/replay.rs`.

Embedded / no_std

The crate is no_std + no_alloc by default — the κ-derivation pipeline never touches an allocator. Build for bare-metal Cortex-M4:

rustup target add thumbv7em-none-eabihf
cargo build -p uor-addr --no-default-features --target thumbv7em-none-eabihf

The alloc and std features are purely ergonomic — they enable Vec-returning convenience APIs and stdlib re-exports without changing any κ-label byte-for-byte (CB-A03 + CB-A04 in ../CONFORMANCE.md).

Consuming from non-Rust callers

Two FFI distribution targets ship the same κ-label byte-for-byte:

  • C / embeddeduor-addr-c emits a staticlib + cdylib plus a cbindgen-generated header. Each realization is exposed as one extern "C" function. Builds for hosted targets and for thumbv7em-none-eabihf (Cortex-M4 bare-metal, no allocator).

    #include "uor_addr.h"
    
    uint8_t  out[UOR_ADDR_LABEL_BYTES];
    size_t   written = 0;
    int32_t  rc = uor_addr_json(
        (const uint8_t *)"{\"foo\":\"bar\"}", 13,
        out, sizeof(out), &written);
    /* rc == UOR_ADDR_OK; out[..71] is the ASCII κ-label */
  • WASM Component Modeluor-addr-wasm is a wit-bindgen component declared by wit/uor-addr.wit. Build with cargo build -p uor-addr-wasm --target wasm32-wasip2 --release; consume the resulting .wasm from JS / Python / Go / .NET / Ruby / Java / C# via their respective wasmtime bindings.

Where to next?