Skip to main content

uor_addr_c/
lib.rs

1//! **`uor-addr-c` — C ABI bindings for `uor-addr`**.
2//!
3//! Exposes each UOR-ADDR realization through a stable `extern "C"`
4//! entry point. The crate is `no_std` and `no_alloc` (mirrors
5//! `uor-addr`'s defaults); the staticlib / cdylib outputs are
6//! consumable from embedded C/C++ toolchains plus any language with
7//! a C FFI (Python `cffi`, Go `cgo`, Ruby `FFI`, .NET P/Invoke).
8//!
9//! # API shape
10//!
11//! Every realization exposes one entry point of the form
12//!
13//! ```c
14//! int32_t uor_addr_<realization>(
15//!     const uint8_t *input,
16//!     size_t input_len,
17//!     uint8_t *out_label,
18//!     size_t out_label_len,
19//!     size_t *out_written);
20//! ```
21//!
22//! - `input` / `input_len` — caller-owned input byte sequence.
23//! - `out_label` / `out_label_len` — caller-owned output buffer; must
24//!   be at least [`UOR_ADDR_LABEL_BYTES`] = 71 bytes.
25//! - `out_written` — written with the number of bytes the function
26//!   emitted (always 71 on success). May be `NULL` (the count is
27//!   then discarded; the buffer is still filled).
28//!
29//! Return value is one of:
30//!
31//! - `UOR_ADDR_OK` (`0`) — success.
32//! - `UOR_ADDR_ERR_NULL_POINTER` (`-1`) — invalid pointer.
33//! - `UOR_ADDR_ERR_BUFFER_TOO_SMALL` (`-2`) — output buffer too small.
34//! - `UOR_ADDR_ERR_INVALID_INPUT` (`-3`) — input rejected by parser.
35//! - `UOR_ADDR_ERR_TOO_LARGE` (`-4`) — **reserved**; never returned under
36//!   ADR-060 (inputs are unbounded). Retained for error-code stability.
37//! - `UOR_ADDR_ERR_PIPELINE` (`-5`) — substrate-level failure.
38
39#![cfg_attr(not(feature = "std"), no_std)]
40#![forbid(unsafe_op_in_unsafe_fn)]
41
42use core::slice;
43
44use uor_addr::{asn1, codemodule, ring, sexp, AddressOutcome, ADDRESS_LABEL_BYTES};
45// JSON / XML / schema / CBOR canonicalization needs `alloc` (object-key /
46// attribute / map-key sorting), so their C entry points — and these
47// imports — are `alloc`-gated under ADR-060.
48#[cfg(feature = "alloc")]
49use uor_addr::{cbor, composition, json, schema, xml, KappaLabel};
50
51/// Wire-format κ-label byte width under the default σ-axis (sha256) —
52/// `len("sha256:") + 64 = 71`.
53#[no_mangle]
54pub static UOR_ADDR_LABEL_BYTES: usize = ADDRESS_LABEL_BYTES;
55
56/// Widest κ-label byte width across the admissible σ-axes (keccak256 →
57/// `len("keccak256:") + 64 = 74`). A `*_with_hash` output buffer sized to
58/// this fits every algorithm.
59#[no_mangle]
60pub static UOR_ADDR_MAX_LABEL_BYTES: usize = uor_addr::MAX_LABEL_BYTES;
61
62/// σ-axis selector for the `*_with_hash` entry points: SHA-256 (default).
63pub const UOR_ADDR_HASH_SHA256: u8 = 0;
64/// σ-axis selector: BLAKE3.
65pub const UOR_ADDR_HASH_BLAKE3: u8 = 1;
66/// σ-axis selector: SHA3-256 (FIPS 202).
67pub const UOR_ADDR_HASH_SHA3_256: u8 = 2;
68/// σ-axis selector: Keccak-256 (pre-FIPS padding).
69pub const UOR_ADDR_HASH_KECCAK256: u8 = 3;
70/// σ-axis selector: SHA-512 (FIPS 180-4; 64-byte digest → 135-byte label).
71pub const UOR_ADDR_HASH_SHA512: u8 = 4;
72
73/// Success.
74pub const UOR_ADDR_OK: i32 = 0;
75/// `input == NULL && input_len > 0`, or `out_label == NULL`.
76pub const UOR_ADDR_ERR_NULL_POINTER: i32 = -1;
77/// `out_label_len < UOR_ADDR_LABEL_BYTES`.
78pub const UOR_ADDR_ERR_BUFFER_TOO_SMALL: i32 = -2;
79/// Input failed the realization's host-boundary parser.
80pub const UOR_ADDR_ERR_INVALID_INPUT: i32 = -3;
81/// **Reserved** — never returned under ADR-060 (inputs are unbounded;
82/// the per-realization size/count caps were removed). Retained so
83/// existing `-4` handlers in downstream C consumers keep compiling.
84pub const UOR_ADDR_ERR_TOO_LARGE: i32 = -4;
85/// Defensive — substrate-level pipeline failure.
86pub const UOR_ADDR_ERR_PIPELINE: i32 = -5;
87/// Unknown σ-axis selector passed to a `*_with_hash` entry point (not one
88/// of the `UOR_ADDR_HASH_*` constants).
89pub const UOR_ADDR_ERR_UNKNOWN_HASH: i32 = -6;
90/// A composition operand's σ-axis does not match the operation's axis
91/// (CA-3 σ-axis homogeneity), or — for the binary product — the two
92/// operands carry different axes.
93pub const UOR_ADDR_ERR_SIGMA_AXIS_MISMATCH: i32 = -7;
94
95/// Map a [`composition::CompositionFailure`] to a C status code.
96#[cfg(feature = "alloc")]
97fn compose_code(e: composition::CompositionFailure) -> i32 {
98    match e {
99        composition::CompositionFailure::MalformedOperand => UOR_ADDR_ERR_INVALID_INPUT,
100        composition::CompositionFailure::OperandSigmaAxisMismatch { .. } => {
101            UOR_ADDR_ERR_SIGMA_AXIS_MISMATCH
102        }
103        composition::CompositionFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
104    }
105}
106
107/// Marshal a successful `AddressOutcome` into the caller's output
108/// buffer. Returns the appropriate error code on buffer overflow / null
109/// pointer.
110///
111/// # Safety
112///
113/// `out_label` must be writable for at least `out_label_len` bytes;
114/// `out_written` if non-null must point to a writable `usize`.
115unsafe fn write_outcome<const N: usize, const FP: usize>(
116    outcome: AddressOutcome<N, FP>,
117    out_label: *mut u8,
118    out_label_len: usize,
119    out_written: *mut usize,
120) -> i32 {
121    if out_label.is_null() {
122        return UOR_ADDR_ERR_NULL_POINTER;
123    }
124    let bytes = outcome.address.as_bytes();
125    if out_label_len < bytes.len() {
126        return UOR_ADDR_ERR_BUFFER_TOO_SMALL;
127    }
128    unsafe {
129        core::ptr::copy_nonoverlapping(bytes.as_ptr(), out_label, bytes.len());
130        if !out_written.is_null() {
131            *out_written = bytes.len();
132        }
133    }
134    UOR_ADDR_OK
135}
136
137/// Borrow the caller's `input` slice safely.
138///
139/// # Safety
140///
141/// `input` must be null (with `input_len == 0`) or readable for
142/// `input_len` bytes.
143unsafe fn borrow_input<'a>(input: *const u8, input_len: usize) -> Result<&'a [u8], i32> {
144    if input_len == 0 {
145        return Ok(&[]);
146    }
147    if input.is_null() {
148        return Err(UOR_ADDR_ERR_NULL_POINTER);
149    }
150    Ok(unsafe { slice::from_raw_parts(input, input_len) })
151}
152
153// ═══ Per-realization C entry points (generated uniformly) ═══════════
154
155/// Map a realization's `AddressFailure` to a C status code.
156trait CErr {
157    fn c_code(&self) -> i32;
158}
159
160#[cfg(feature = "alloc")]
161impl CErr for json::AddressFailure {
162    fn c_code(&self) -> i32 {
163        match self {
164            json::AddressFailure::InvalidJson => UOR_ADDR_ERR_INVALID_INPUT,
165            json::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
166        }
167    }
168}
169
170impl CErr for sexp::AddressFailure {
171    fn c_code(&self) -> i32 {
172        match self {
173            sexp::AddressFailure::InvalidSExpr => UOR_ADDR_ERR_INVALID_INPUT,
174            sexp::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
175        }
176    }
177}
178
179#[cfg(feature = "alloc")]
180impl CErr for xml::AddressFailure {
181    fn c_code(&self) -> i32 {
182        match self {
183            xml::AddressFailure::InvalidXml => UOR_ADDR_ERR_INVALID_INPUT,
184            xml::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
185        }
186    }
187}
188
189impl CErr for asn1::AddressFailure {
190    fn c_code(&self) -> i32 {
191        match self {
192            asn1::AddressFailure::InvalidDer => UOR_ADDR_ERR_INVALID_INPUT,
193            asn1::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
194        }
195    }
196}
197
198impl CErr for ring::AddressFailure {
199    fn c_code(&self) -> i32 {
200        match self {
201            ring::AddressFailure::InvalidRingElement => UOR_ADDR_ERR_INVALID_INPUT,
202            ring::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
203        }
204    }
205}
206
207impl CErr for codemodule::AddressFailure {
208    fn c_code(&self) -> i32 {
209        match self {
210            codemodule::AddressFailure::InvalidAst => UOR_ADDR_ERR_INVALID_INPUT,
211            codemodule::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
212        }
213    }
214}
215
216#[cfg(feature = "alloc")]
217impl CErr for cbor::AddressFailure {
218    fn c_code(&self) -> i32 {
219        match self {
220            cbor::AddressFailure::InvalidCbor => UOR_ADDR_ERR_INVALID_INPUT,
221            cbor::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
222        }
223    }
224}
225
226#[cfg(feature = "alloc")]
227impl CErr for schema::photo::AddressFailure {
228    fn c_code(&self) -> i32 {
229        match self {
230            schema::photo::AddressFailure::SchemaViolation => UOR_ADDR_ERR_INVALID_INPUT,
231            schema::photo::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
232        }
233    }
234}
235
236#[cfg(feature = "alloc")]
237impl CErr for schema::document::AddressFailure {
238    fn c_code(&self) -> i32 {
239        match self {
240            schema::document::AddressFailure::SchemaViolation => UOR_ADDR_ERR_INVALID_INPUT,
241            schema::document::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
242        }
243    }
244}
245
246#[cfg(feature = "alloc")]
247impl CErr for schema::codemodule_signed::AddressFailure {
248    fn c_code(&self) -> i32 {
249        match self {
250            schema::codemodule_signed::AddressFailure::SchemaViolation => {
251                UOR_ADDR_ERR_INVALID_INPUT
252            }
253            schema::codemodule_signed::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
254        }
255    }
256}
257
258#[cfg(feature = "gguf")]
259impl CErr for uor_addr::gguf::AddressFailure {
260    fn c_code(&self) -> i32 {
261        match self {
262            uor_addr::gguf::AddressFailure::InvalidGguf => UOR_ADDR_ERR_INVALID_INPUT,
263            uor_addr::gguf::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
264        }
265    }
266}
267
268#[cfg(feature = "onnx")]
269impl CErr for uor_addr::onnx::AddressFailure {
270    fn c_code(&self) -> i32 {
271        match self {
272            uor_addr::onnx::AddressFailure::InvalidOnnx => UOR_ADDR_ERR_INVALID_INPUT,
273            uor_addr::onnx::AddressFailure::PipelineFailure => UOR_ADDR_ERR_PIPELINE,
274        }
275    }
276}
277
278/// `json` realization — default σ-axis (SHA-256).
279///
280/// # Safety
281///
282/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
283/// - `out_label` is writable for at least `out_label_len` bytes.
284/// - `out_written` if non-null points to a writable `size_t`.
285#[cfg(feature = "alloc")]
286#[no_mangle]
287pub unsafe extern "C" fn uor_addr_json(
288    input: *const u8,
289    input_len: usize,
290    out_label: *mut u8,
291    out_label_len: usize,
292    out_written: *mut usize,
293) -> i32 {
294    let s = match unsafe { borrow_input(input, input_len) } {
295        Ok(s) => s,
296        Err(code) => return code,
297    };
298    match json::address(s) {
299        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
300        Err(e) => e.c_code(),
301    }
302}
303
304/// `json` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
305/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
306///
307/// # Safety
308///
309/// As [`uor_addr_json`].
310#[cfg(feature = "alloc")]
311#[no_mangle]
312pub unsafe extern "C" fn uor_addr_json_with_hash(
313    algo: u8,
314    input: *const u8,
315    input_len: usize,
316    out_label: *mut u8,
317    out_label_len: usize,
318    out_written: *mut usize,
319) -> i32 {
320    let s = match unsafe { borrow_input(input, input_len) } {
321        Ok(s) => s,
322        Err(code) => return code,
323    };
324    match algo {
325        UOR_ADDR_HASH_SHA256 => match json::address(s) {
326            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
327            Err(e) => e.c_code(),
328        },
329        UOR_ADDR_HASH_BLAKE3 => match json::address_blake3(s) {
330            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
331            Err(e) => e.c_code(),
332        },
333        UOR_ADDR_HASH_SHA3_256 => match json::address_sha3_256(s) {
334            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
335            Err(e) => e.c_code(),
336        },
337        UOR_ADDR_HASH_KECCAK256 => match json::address_keccak256(s) {
338            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
339            Err(e) => e.c_code(),
340        },
341        UOR_ADDR_HASH_SHA512 => match json::address_sha512(s) {
342            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
343            Err(e) => e.c_code(),
344        },
345        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
346    }
347}
348
349/// `sexp` realization — default σ-axis (SHA-256).
350///
351/// # Safety
352///
353/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
354/// - `out_label` is writable for at least `out_label_len` bytes.
355/// - `out_written` if non-null points to a writable `size_t`.
356#[no_mangle]
357pub unsafe extern "C" fn uor_addr_sexp(
358    input: *const u8,
359    input_len: usize,
360    out_label: *mut u8,
361    out_label_len: usize,
362    out_written: *mut usize,
363) -> i32 {
364    let s = match unsafe { borrow_input(input, input_len) } {
365        Ok(s) => s,
366        Err(code) => return code,
367    };
368    match sexp::address(s) {
369        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
370        Err(e) => e.c_code(),
371    }
372}
373
374/// `sexp` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
375/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
376///
377/// # Safety
378///
379/// As [`uor_addr_sexp`].
380#[no_mangle]
381pub unsafe extern "C" fn uor_addr_sexp_with_hash(
382    algo: u8,
383    input: *const u8,
384    input_len: usize,
385    out_label: *mut u8,
386    out_label_len: usize,
387    out_written: *mut usize,
388) -> i32 {
389    let s = match unsafe { borrow_input(input, input_len) } {
390        Ok(s) => s,
391        Err(code) => return code,
392    };
393    match algo {
394        UOR_ADDR_HASH_SHA256 => match sexp::address(s) {
395            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
396            Err(e) => e.c_code(),
397        },
398        UOR_ADDR_HASH_BLAKE3 => match sexp::address_blake3(s) {
399            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
400            Err(e) => e.c_code(),
401        },
402        UOR_ADDR_HASH_SHA3_256 => match sexp::address_sha3_256(s) {
403            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
404            Err(e) => e.c_code(),
405        },
406        UOR_ADDR_HASH_KECCAK256 => match sexp::address_keccak256(s) {
407            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
408            Err(e) => e.c_code(),
409        },
410        UOR_ADDR_HASH_SHA512 => match sexp::address_sha512(s) {
411            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
412            Err(e) => e.c_code(),
413        },
414        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
415    }
416}
417
418/// `xml` realization — default σ-axis (SHA-256).
419///
420/// # Safety
421///
422/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
423/// - `out_label` is writable for at least `out_label_len` bytes.
424/// - `out_written` if non-null points to a writable `size_t`.
425#[cfg(feature = "alloc")]
426#[no_mangle]
427pub unsafe extern "C" fn uor_addr_xml(
428    input: *const u8,
429    input_len: usize,
430    out_label: *mut u8,
431    out_label_len: usize,
432    out_written: *mut usize,
433) -> i32 {
434    let s = match unsafe { borrow_input(input, input_len) } {
435        Ok(s) => s,
436        Err(code) => return code,
437    };
438    match xml::address(s) {
439        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
440        Err(e) => e.c_code(),
441    }
442}
443
444/// `xml` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
445/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
446///
447/// # Safety
448///
449/// As [`uor_addr_xml`].
450#[cfg(feature = "alloc")]
451#[no_mangle]
452pub unsafe extern "C" fn uor_addr_xml_with_hash(
453    algo: u8,
454    input: *const u8,
455    input_len: usize,
456    out_label: *mut u8,
457    out_label_len: usize,
458    out_written: *mut usize,
459) -> i32 {
460    let s = match unsafe { borrow_input(input, input_len) } {
461        Ok(s) => s,
462        Err(code) => return code,
463    };
464    match algo {
465        UOR_ADDR_HASH_SHA256 => match xml::address(s) {
466            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
467            Err(e) => e.c_code(),
468        },
469        UOR_ADDR_HASH_BLAKE3 => match xml::address_blake3(s) {
470            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
471            Err(e) => e.c_code(),
472        },
473        UOR_ADDR_HASH_SHA3_256 => match xml::address_sha3_256(s) {
474            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
475            Err(e) => e.c_code(),
476        },
477        UOR_ADDR_HASH_KECCAK256 => match xml::address_keccak256(s) {
478            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
479            Err(e) => e.c_code(),
480        },
481        UOR_ADDR_HASH_SHA512 => match xml::address_sha512(s) {
482            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
483            Err(e) => e.c_code(),
484        },
485        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
486    }
487}
488
489/// `asn1` realization — default σ-axis (SHA-256).
490///
491/// # Safety
492///
493/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
494/// - `out_label` is writable for at least `out_label_len` bytes.
495/// - `out_written` if non-null points to a writable `size_t`.
496#[no_mangle]
497pub unsafe extern "C" fn uor_addr_asn1(
498    input: *const u8,
499    input_len: usize,
500    out_label: *mut u8,
501    out_label_len: usize,
502    out_written: *mut usize,
503) -> i32 {
504    let s = match unsafe { borrow_input(input, input_len) } {
505        Ok(s) => s,
506        Err(code) => return code,
507    };
508    match asn1::address(s) {
509        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
510        Err(e) => e.c_code(),
511    }
512}
513
514/// `asn1` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
515/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
516///
517/// # Safety
518///
519/// As [`uor_addr_asn1`].
520#[no_mangle]
521pub unsafe extern "C" fn uor_addr_asn1_with_hash(
522    algo: u8,
523    input: *const u8,
524    input_len: usize,
525    out_label: *mut u8,
526    out_label_len: usize,
527    out_written: *mut usize,
528) -> i32 {
529    let s = match unsafe { borrow_input(input, input_len) } {
530        Ok(s) => s,
531        Err(code) => return code,
532    };
533    match algo {
534        UOR_ADDR_HASH_SHA256 => match asn1::address(s) {
535            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
536            Err(e) => e.c_code(),
537        },
538        UOR_ADDR_HASH_BLAKE3 => match asn1::address_blake3(s) {
539            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
540            Err(e) => e.c_code(),
541        },
542        UOR_ADDR_HASH_SHA3_256 => match asn1::address_sha3_256(s) {
543            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
544            Err(e) => e.c_code(),
545        },
546        UOR_ADDR_HASH_KECCAK256 => match asn1::address_keccak256(s) {
547            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
548            Err(e) => e.c_code(),
549        },
550        UOR_ADDR_HASH_SHA512 => match asn1::address_sha512(s) {
551            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
552            Err(e) => e.c_code(),
553        },
554        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
555    }
556}
557
558/// `ring` realization — default σ-axis (SHA-256).
559///
560/// # Safety
561///
562/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
563/// - `out_label` is writable for at least `out_label_len` bytes.
564/// - `out_written` if non-null points to a writable `size_t`.
565#[no_mangle]
566pub unsafe extern "C" fn uor_addr_ring(
567    input: *const u8,
568    input_len: usize,
569    out_label: *mut u8,
570    out_label_len: usize,
571    out_written: *mut usize,
572) -> i32 {
573    let s = match unsafe { borrow_input(input, input_len) } {
574        Ok(s) => s,
575        Err(code) => return code,
576    };
577    match ring::address(s) {
578        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
579        Err(e) => e.c_code(),
580    }
581}
582
583/// `ring` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
584/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
585///
586/// # Safety
587///
588/// As [`uor_addr_ring`].
589#[no_mangle]
590pub unsafe extern "C" fn uor_addr_ring_with_hash(
591    algo: u8,
592    input: *const u8,
593    input_len: usize,
594    out_label: *mut u8,
595    out_label_len: usize,
596    out_written: *mut usize,
597) -> i32 {
598    let s = match unsafe { borrow_input(input, input_len) } {
599        Ok(s) => s,
600        Err(code) => return code,
601    };
602    match algo {
603        UOR_ADDR_HASH_SHA256 => match ring::address(s) {
604            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
605            Err(e) => e.c_code(),
606        },
607        UOR_ADDR_HASH_BLAKE3 => match ring::address_blake3(s) {
608            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
609            Err(e) => e.c_code(),
610        },
611        UOR_ADDR_HASH_SHA3_256 => match ring::address_sha3_256(s) {
612            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
613            Err(e) => e.c_code(),
614        },
615        UOR_ADDR_HASH_KECCAK256 => match ring::address_keccak256(s) {
616            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
617            Err(e) => e.c_code(),
618        },
619        UOR_ADDR_HASH_SHA512 => match ring::address_sha512(s) {
620            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
621            Err(e) => e.c_code(),
622        },
623        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
624    }
625}
626
627/// `codemodule` realization — default σ-axis (SHA-256).
628///
629/// # Safety
630///
631/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
632/// - `out_label` is writable for at least `out_label_len` bytes.
633/// - `out_written` if non-null points to a writable `size_t`.
634#[no_mangle]
635pub unsafe extern "C" fn uor_addr_codemodule(
636    input: *const u8,
637    input_len: usize,
638    out_label: *mut u8,
639    out_label_len: usize,
640    out_written: *mut usize,
641) -> i32 {
642    let s = match unsafe { borrow_input(input, input_len) } {
643        Ok(s) => s,
644        Err(code) => return code,
645    };
646    match codemodule::address(s) {
647        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
648        Err(e) => e.c_code(),
649    }
650}
651
652/// `codemodule` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
653/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
654///
655/// # Safety
656///
657/// As [`uor_addr_codemodule`].
658#[no_mangle]
659pub unsafe extern "C" fn uor_addr_codemodule_with_hash(
660    algo: u8,
661    input: *const u8,
662    input_len: usize,
663    out_label: *mut u8,
664    out_label_len: usize,
665    out_written: *mut usize,
666) -> i32 {
667    let s = match unsafe { borrow_input(input, input_len) } {
668        Ok(s) => s,
669        Err(code) => return code,
670    };
671    match algo {
672        UOR_ADDR_HASH_SHA256 => match codemodule::address(s) {
673            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
674            Err(e) => e.c_code(),
675        },
676        UOR_ADDR_HASH_BLAKE3 => match codemodule::address_blake3(s) {
677            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
678            Err(e) => e.c_code(),
679        },
680        UOR_ADDR_HASH_SHA3_256 => match codemodule::address_sha3_256(s) {
681            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
682            Err(e) => e.c_code(),
683        },
684        UOR_ADDR_HASH_KECCAK256 => match codemodule::address_keccak256(s) {
685            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
686            Err(e) => e.c_code(),
687        },
688        UOR_ADDR_HASH_SHA512 => match codemodule::address_sha512(s) {
689            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
690            Err(e) => e.c_code(),
691        },
692        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
693    }
694}
695
696/// `cbor` realization — default σ-axis (SHA-256).
697///
698/// # Safety
699///
700/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
701/// - `out_label` is writable for at least `out_label_len` bytes.
702/// - `out_written` if non-null points to a writable `size_t`.
703#[cfg(feature = "alloc")]
704#[no_mangle]
705pub unsafe extern "C" fn uor_addr_cbor(
706    input: *const u8,
707    input_len: usize,
708    out_label: *mut u8,
709    out_label_len: usize,
710    out_written: *mut usize,
711) -> i32 {
712    let s = match unsafe { borrow_input(input, input_len) } {
713        Ok(s) => s,
714        Err(code) => return code,
715    };
716    match cbor::address(s) {
717        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
718        Err(e) => e.c_code(),
719    }
720}
721
722/// `cbor` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
723/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
724///
725/// # Safety
726///
727/// As [`uor_addr_cbor`].
728#[cfg(feature = "alloc")]
729#[no_mangle]
730pub unsafe extern "C" fn uor_addr_cbor_with_hash(
731    algo: u8,
732    input: *const u8,
733    input_len: usize,
734    out_label: *mut u8,
735    out_label_len: usize,
736    out_written: *mut usize,
737) -> i32 {
738    let s = match unsafe { borrow_input(input, input_len) } {
739        Ok(s) => s,
740        Err(code) => return code,
741    };
742    match algo {
743        UOR_ADDR_HASH_SHA256 => match cbor::address(s) {
744            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
745            Err(e) => e.c_code(),
746        },
747        UOR_ADDR_HASH_BLAKE3 => match cbor::address_blake3(s) {
748            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
749            Err(e) => e.c_code(),
750        },
751        UOR_ADDR_HASH_SHA3_256 => match cbor::address_sha3_256(s) {
752            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
753            Err(e) => e.c_code(),
754        },
755        UOR_ADDR_HASH_KECCAK256 => match cbor::address_keccak256(s) {
756            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
757            Err(e) => e.c_code(),
758        },
759        UOR_ADDR_HASH_SHA512 => match cbor::address_sha512(s) {
760            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
761            Err(e) => e.c_code(),
762        },
763        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
764    }
765}
766
767/// `schema_photo` realization — default σ-axis (SHA-256).
768///
769/// # Safety
770///
771/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
772/// - `out_label` is writable for at least `out_label_len` bytes.
773/// - `out_written` if non-null points to a writable `size_t`.
774#[cfg(feature = "alloc")]
775#[no_mangle]
776pub unsafe extern "C" fn uor_addr_schema_photo(
777    input: *const u8,
778    input_len: usize,
779    out_label: *mut u8,
780    out_label_len: usize,
781    out_written: *mut usize,
782) -> i32 {
783    let s = match unsafe { borrow_input(input, input_len) } {
784        Ok(s) => s,
785        Err(code) => return code,
786    };
787    match schema::photo::address(s) {
788        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
789        Err(e) => e.c_code(),
790    }
791}
792
793/// `schema_photo` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
794/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
795///
796/// # Safety
797///
798/// As [`uor_addr_schema_photo`].
799#[cfg(feature = "alloc")]
800#[no_mangle]
801pub unsafe extern "C" fn uor_addr_schema_photo_with_hash(
802    algo: u8,
803    input: *const u8,
804    input_len: usize,
805    out_label: *mut u8,
806    out_label_len: usize,
807    out_written: *mut usize,
808) -> i32 {
809    let s = match unsafe { borrow_input(input, input_len) } {
810        Ok(s) => s,
811        Err(code) => return code,
812    };
813    match algo {
814        UOR_ADDR_HASH_SHA256 => match schema::photo::address(s) {
815            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
816            Err(e) => e.c_code(),
817        },
818        UOR_ADDR_HASH_BLAKE3 => match schema::photo::address_blake3(s) {
819            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
820            Err(e) => e.c_code(),
821        },
822        UOR_ADDR_HASH_SHA3_256 => match schema::photo::address_sha3_256(s) {
823            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
824            Err(e) => e.c_code(),
825        },
826        UOR_ADDR_HASH_KECCAK256 => match schema::photo::address_keccak256(s) {
827            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
828            Err(e) => e.c_code(),
829        },
830        UOR_ADDR_HASH_SHA512 => match schema::photo::address_sha512(s) {
831            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
832            Err(e) => e.c_code(),
833        },
834        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
835    }
836}
837
838/// `schema_document` realization — default σ-axis (SHA-256).
839///
840/// # Safety
841///
842/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
843/// - `out_label` is writable for at least `out_label_len` bytes.
844/// - `out_written` if non-null points to a writable `size_t`.
845#[cfg(feature = "alloc")]
846#[no_mangle]
847pub unsafe extern "C" fn uor_addr_schema_document(
848    input: *const u8,
849    input_len: usize,
850    out_label: *mut u8,
851    out_label_len: usize,
852    out_written: *mut usize,
853) -> i32 {
854    let s = match unsafe { borrow_input(input, input_len) } {
855        Ok(s) => s,
856        Err(code) => return code,
857    };
858    match schema::document::address(s) {
859        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
860        Err(e) => e.c_code(),
861    }
862}
863
864/// `schema_document` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
865/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
866///
867/// # Safety
868///
869/// As [`uor_addr_schema_document`].
870#[cfg(feature = "alloc")]
871#[no_mangle]
872pub unsafe extern "C" fn uor_addr_schema_document_with_hash(
873    algo: u8,
874    input: *const u8,
875    input_len: usize,
876    out_label: *mut u8,
877    out_label_len: usize,
878    out_written: *mut usize,
879) -> i32 {
880    let s = match unsafe { borrow_input(input, input_len) } {
881        Ok(s) => s,
882        Err(code) => return code,
883    };
884    match algo {
885        UOR_ADDR_HASH_SHA256 => match schema::document::address(s) {
886            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
887            Err(e) => e.c_code(),
888        },
889        UOR_ADDR_HASH_BLAKE3 => match schema::document::address_blake3(s) {
890            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
891            Err(e) => e.c_code(),
892        },
893        UOR_ADDR_HASH_SHA3_256 => match schema::document::address_sha3_256(s) {
894            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
895            Err(e) => e.c_code(),
896        },
897        UOR_ADDR_HASH_KECCAK256 => match schema::document::address_keccak256(s) {
898            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
899            Err(e) => e.c_code(),
900        },
901        UOR_ADDR_HASH_SHA512 => match schema::document::address_sha512(s) {
902            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
903            Err(e) => e.c_code(),
904        },
905        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
906    }
907}
908
909/// `schema_codemodule_signed` realization — default σ-axis (SHA-256).
910///
911/// # Safety
912///
913/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
914/// - `out_label` is writable for at least `out_label_len` bytes.
915/// - `out_written` if non-null points to a writable `size_t`.
916#[cfg(feature = "alloc")]
917#[no_mangle]
918pub unsafe extern "C" fn uor_addr_schema_codemodule_signed(
919    input: *const u8,
920    input_len: usize,
921    out_label: *mut u8,
922    out_label_len: usize,
923    out_written: *mut usize,
924) -> i32 {
925    let s = match unsafe { borrow_input(input, input_len) } {
926        Ok(s) => s,
927        Err(code) => return code,
928    };
929    match schema::codemodule_signed::address(s) {
930        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
931        Err(e) => e.c_code(),
932    }
933}
934
935/// `schema_codemodule_signed` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
936/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
937///
938/// # Safety
939///
940/// As [`uor_addr_schema_codemodule_signed`].
941#[cfg(feature = "alloc")]
942#[no_mangle]
943pub unsafe extern "C" fn uor_addr_schema_codemodule_signed_with_hash(
944    algo: u8,
945    input: *const u8,
946    input_len: usize,
947    out_label: *mut u8,
948    out_label_len: usize,
949    out_written: *mut usize,
950) -> i32 {
951    let s = match unsafe { borrow_input(input, input_len) } {
952        Ok(s) => s,
953        Err(code) => return code,
954    };
955    match algo {
956        UOR_ADDR_HASH_SHA256 => match schema::codemodule_signed::address(s) {
957            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
958            Err(e) => e.c_code(),
959        },
960        UOR_ADDR_HASH_BLAKE3 => match schema::codemodule_signed::address_blake3(s) {
961            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
962            Err(e) => e.c_code(),
963        },
964        UOR_ADDR_HASH_SHA3_256 => match schema::codemodule_signed::address_sha3_256(s) {
965            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
966            Err(e) => e.c_code(),
967        },
968        UOR_ADDR_HASH_KECCAK256 => match schema::codemodule_signed::address_keccak256(s) {
969            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
970            Err(e) => e.c_code(),
971        },
972        UOR_ADDR_HASH_SHA512 => match schema::codemodule_signed::address_sha512(s) {
973            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
974            Err(e) => e.c_code(),
975        },
976        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
977    }
978}
979
980/// `gguf` realization — default σ-axis (SHA-256).
981///
982/// # Safety
983///
984/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
985/// - `out_label` is writable for at least `out_label_len` bytes.
986/// - `out_written` if non-null points to a writable `size_t`.
987#[cfg(feature = "gguf")]
988#[no_mangle]
989pub unsafe extern "C" fn uor_addr_gguf(
990    input: *const u8,
991    input_len: usize,
992    out_label: *mut u8,
993    out_label_len: usize,
994    out_written: *mut usize,
995) -> i32 {
996    let s = match unsafe { borrow_input(input, input_len) } {
997        Ok(s) => s,
998        Err(code) => return code,
999    };
1000    match uor_addr::gguf::address(s) {
1001        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1002        Err(e) => e.c_code(),
1003    }
1004}
1005
1006/// `gguf` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
1007/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
1008///
1009/// # Safety
1010///
1011/// As [`uor_addr_gguf`].
1012#[cfg(feature = "gguf")]
1013#[no_mangle]
1014pub unsafe extern "C" fn uor_addr_gguf_with_hash(
1015    algo: u8,
1016    input: *const u8,
1017    input_len: usize,
1018    out_label: *mut u8,
1019    out_label_len: usize,
1020    out_written: *mut usize,
1021) -> i32 {
1022    let s = match unsafe { borrow_input(input, input_len) } {
1023        Ok(s) => s,
1024        Err(code) => return code,
1025    };
1026    match algo {
1027        UOR_ADDR_HASH_SHA256 => match uor_addr::gguf::address(s) {
1028            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1029            Err(e) => e.c_code(),
1030        },
1031        UOR_ADDR_HASH_BLAKE3 => match uor_addr::gguf::address_blake3(s) {
1032            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1033            Err(e) => e.c_code(),
1034        },
1035        UOR_ADDR_HASH_SHA3_256 => match uor_addr::gguf::address_sha3_256(s) {
1036            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1037            Err(e) => e.c_code(),
1038        },
1039        UOR_ADDR_HASH_KECCAK256 => match uor_addr::gguf::address_keccak256(s) {
1040            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1041            Err(e) => e.c_code(),
1042        },
1043        UOR_ADDR_HASH_SHA512 => match uor_addr::gguf::address_sha512(s) {
1044            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1045            Err(e) => e.c_code(),
1046        },
1047        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1048    }
1049}
1050
1051/// `onnx` realization — default σ-axis (SHA-256).
1052///
1053/// # Safety
1054///
1055/// - `input` is null (with `input_len == 0`) or readable for `input_len` bytes.
1056/// - `out_label` is writable for at least `out_label_len` bytes.
1057/// - `out_written` if non-null points to a writable `size_t`.
1058#[cfg(feature = "onnx")]
1059#[no_mangle]
1060pub unsafe extern "C" fn uor_addr_onnx(
1061    input: *const u8,
1062    input_len: usize,
1063    out_label: *mut u8,
1064    out_label_len: usize,
1065    out_written: *mut usize,
1066) -> i32 {
1067    let s = match unsafe { borrow_input(input, input_len) } {
1068        Ok(s) => s,
1069        Err(code) => return code,
1070    };
1071    match uor_addr::onnx::address(s) {
1072        Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1073        Err(e) => e.c_code(),
1074    }
1075}
1076
1077/// `onnx` realization under a caller-selected σ-axis (`UOR_ADDR_HASH_*`).
1078/// `out_label` must be writable for at least `UOR_ADDR_MAX_LABEL_BYTES`.
1079///
1080/// # Safety
1081///
1082/// As [`uor_addr_onnx`].
1083#[cfg(feature = "onnx")]
1084#[no_mangle]
1085pub unsafe extern "C" fn uor_addr_onnx_with_hash(
1086    algo: u8,
1087    input: *const u8,
1088    input_len: usize,
1089    out_label: *mut u8,
1090    out_label_len: usize,
1091    out_written: *mut usize,
1092) -> i32 {
1093    let s = match unsafe { borrow_input(input, input_len) } {
1094        Ok(s) => s,
1095        Err(code) => return code,
1096    };
1097    match algo {
1098        UOR_ADDR_HASH_SHA256 => match uor_addr::onnx::address(s) {
1099            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1100            Err(e) => e.c_code(),
1101        },
1102        UOR_ADDR_HASH_BLAKE3 => match uor_addr::onnx::address_blake3(s) {
1103            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1104            Err(e) => e.c_code(),
1105        },
1106        UOR_ADDR_HASH_SHA3_256 => match uor_addr::onnx::address_sha3_256(s) {
1107            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1108            Err(e) => e.c_code(),
1109        },
1110        UOR_ADDR_HASH_KECCAK256 => match uor_addr::onnx::address_keccak256(s) {
1111            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1112            Err(e) => e.c_code(),
1113        },
1114        UOR_ADDR_HASH_SHA512 => match uor_addr::onnx::address_sha512(s) {
1115            Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
1116            Err(e) => e.c_code(),
1117        },
1118        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1119    }
1120}
1121
1122// ─── Grounded witness (TC-05 cross-language replay) ────────────────
1123
1124/// `verify()` failed: empty trace. **Reserved** — the live verify path maps
1125/// every failure to `UOR_ADDR_ERR_PIPELINE`; retained for ABI stability.
1126pub const UOR_ADDR_ERR_VERIFY_EMPTY_TRACE: i32 = -10;
1127/// **Reserved** (see above).
1128pub const UOR_ADDR_ERR_VERIFY_OUT_OF_ORDER_EVENT: i32 = -11;
1129/// **Reserved** (see above).
1130pub const UOR_ADDR_ERR_VERIFY_ZERO_TARGET: i32 = -12;
1131/// **Reserved** (see above).
1132pub const UOR_ADDR_ERR_VERIFY_NON_CONTIGUOUS_STEPS: i32 = -13;
1133/// **Reserved** (see above).
1134pub const UOR_ADDR_ERR_VERIFY_CAPACITY_EXCEEDED: i32 = -14;
1135
1136#[cfg(feature = "alloc")]
1137extern crate alloc;
1138#[cfg(feature = "alloc")]
1139use alloc::boxed::Box;
1140
1141/// Width-erased owned outcome — one opaque `UorAddrGrounded` handle carries
1142/// a κ-label of any admissible σ-axis width (71 / 73 / 74 for the 32-byte
1143/// fingerprint axes, 135 for sha512's 64-byte fingerprint).
1144#[cfg(feature = "alloc")]
1145pub(crate) enum AnyOutcome {
1146    W71(AddressOutcome<71>),
1147    W73(AddressOutcome<73>),
1148    W74(AddressOutcome<74>),
1149    W512(AddressOutcome<135, 64>),
1150}
1151
1152#[cfg(feature = "alloc")]
1153impl AnyOutcome {
1154    fn label_bytes(&self) -> &[u8] {
1155        match self {
1156            Self::W71(o) => o.address.as_bytes(),
1157            Self::W73(o) => o.address.as_bytes(),
1158            Self::W74(o) => o.address.as_bytes(),
1159            Self::W512(o) => o.address.as_bytes(),
1160        }
1161    }
1162    fn fingerprint(&self) -> &[u8] {
1163        match self {
1164            Self::W71(o) => o.witness.content_fingerprint(),
1165            Self::W73(o) => o.witness.content_fingerprint(),
1166            Self::W74(o) => o.witness.content_fingerprint(),
1167            Self::W512(o) => o.witness.content_fingerprint(),
1168        }
1169    }
1170    fn verify(&self) -> Result<(), uor_addr::VerifyError> {
1171        match self {
1172            Self::W71(o) => o.witness.verify().map(|_| ()),
1173            Self::W73(o) => o.witness.verify().map(|_| ()),
1174            Self::W74(o) => o.witness.verify().map(|_| ()),
1175            Self::W512(o) => o.witness.verify().map(|_| ()),
1176        }
1177    }
1178}
1179
1180/// Opaque, foreign-managed witness handle. Construct via any
1181/// `uor_addr_*_with_witness[_hash]` function; release with
1182/// `uor_addr_grounded_free`.
1183#[cfg(feature = "alloc")]
1184#[repr(C)]
1185pub struct UorAddrGrounded {
1186    pub(crate) outcome: AnyOutcome,
1187}
1188
1189/// Box an `AnyOutcome` into a heap `UorAddrGrounded` and hand back the ptr.
1190///
1191/// # Safety
1192///
1193/// `out_handle` must be a valid writable `*mut UorAddrGrounded` pointer.
1194#[cfg(feature = "alloc")]
1195unsafe fn write_grounded_any(outcome: AnyOutcome, out_handle: *mut *mut UorAddrGrounded) -> i32 {
1196    if out_handle.is_null() {
1197        return UOR_ADDR_ERR_NULL_POINTER;
1198    }
1199    let ptr = Box::into_raw(Box::new(UorAddrGrounded { outcome }));
1200    unsafe {
1201        *out_handle = ptr;
1202    }
1203    UOR_ADDR_OK
1204}
1205
1206/// Free a Grounded handle. Null is a no-op; each handle is freed once.
1207///
1208/// # Safety
1209///
1210/// `handle` is null or a pointer from a `*_with_witness[_hash]` call.
1211#[cfg(feature = "alloc")]
1212#[no_mangle]
1213pub unsafe extern "C" fn uor_addr_grounded_free(handle: *mut UorAddrGrounded) {
1214    if handle.is_null() {
1215        return;
1216    }
1217    unsafe {
1218        drop(Box::from_raw(handle));
1219    }
1220}
1221
1222/// Read the κ-label this Grounded carries into `out_label` (its width
1223/// depends on the σ-axis; size `out_label` to `UOR_ADDR_MAX_LABEL_BYTES`).
1224///
1225/// # Safety
1226///
1227/// - `handle` is a live handle from a `*_with_witness[_hash]` call.
1228/// - `out_label` writable for `out_label_len` bytes; `out_written` if
1229///   non-null writable.
1230#[cfg(feature = "alloc")]
1231#[no_mangle]
1232pub unsafe extern "C" fn uor_addr_grounded_kappa_label(
1233    handle: *const UorAddrGrounded,
1234    out_label: *mut u8,
1235    out_label_len: usize,
1236    out_written: *mut usize,
1237) -> i32 {
1238    if handle.is_null() || out_label.is_null() {
1239        return UOR_ADDR_ERR_NULL_POINTER;
1240    }
1241    let g = unsafe { &*handle };
1242    let bytes = g.outcome.label_bytes();
1243    if out_label_len < bytes.len() {
1244        return UOR_ADDR_ERR_BUFFER_TOO_SMALL;
1245    }
1246    unsafe {
1247        core::ptr::copy_nonoverlapping(bytes.as_ptr(), out_label, bytes.len());
1248        if !out_written.is_null() {
1249            *out_written = bytes.len();
1250        }
1251    }
1252    UOR_ADDR_OK
1253}
1254
1255/// Read the σ-projection content fingerprint into `out_digest` (32 bytes
1256/// for the `Hasher<32>` axes, 64 for sha512). Size `out_digest` to 64.
1257///
1258/// # Safety
1259///
1260/// As [`uor_addr_grounded_kappa_label`].
1261#[cfg(feature = "alloc")]
1262#[no_mangle]
1263pub unsafe extern "C" fn uor_addr_grounded_content_fingerprint(
1264    handle: *const UorAddrGrounded,
1265    out_digest: *mut u8,
1266    out_digest_len: usize,
1267    out_written: *mut usize,
1268) -> i32 {
1269    if handle.is_null() || out_digest.is_null() {
1270        return UOR_ADDR_ERR_NULL_POINTER;
1271    }
1272    let g = unsafe { &*handle };
1273    let fp = g.outcome.fingerprint();
1274    if out_digest_len < fp.len() {
1275        return UOR_ADDR_ERR_BUFFER_TOO_SMALL;
1276    }
1277    unsafe {
1278        core::ptr::copy_nonoverlapping(fp.as_ptr(), out_digest, fp.len());
1279        if !out_written.is_null() {
1280            *out_written = fp.len();
1281        }
1282    }
1283    UOR_ADDR_OK
1284}
1285
1286/// Verify the witness by re-certifying its replay trace (no σ-axis
1287/// re-invocation) and write the recovered κ-label into `out_label`.
1288///
1289/// # Safety
1290///
1291/// As [`uor_addr_grounded_kappa_label`].
1292#[cfg(feature = "alloc")]
1293#[no_mangle]
1294pub unsafe extern "C" fn uor_addr_grounded_verify(
1295    handle: *const UorAddrGrounded,
1296    out_label: *mut u8,
1297    out_label_len: usize,
1298    out_written: *mut usize,
1299) -> i32 {
1300    if handle.is_null() || out_label.is_null() {
1301        return UOR_ADDR_ERR_NULL_POINTER;
1302    }
1303    let g = unsafe { &*handle };
1304    let bytes = g.outcome.label_bytes();
1305    if out_label_len < bytes.len() {
1306        return UOR_ADDR_ERR_BUFFER_TOO_SMALL;
1307    }
1308    match g.outcome.verify() {
1309        Ok(()) => unsafe {
1310            core::ptr::copy_nonoverlapping(bytes.as_ptr(), out_label, bytes.len());
1311            if !out_written.is_null() {
1312                *out_written = bytes.len();
1313            }
1314            UOR_ADDR_OK
1315        },
1316        Err(_) => UOR_ADDR_ERR_PIPELINE,
1317    }
1318}
1319
1320/// `json` realization — SHA-256 verifiable witness handle.
1321///
1322/// # Safety
1323///
1324/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1325/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1326#[cfg(feature = "alloc")]
1327#[no_mangle]
1328pub unsafe extern "C" fn uor_addr_json_with_witness(
1329    input: *const u8,
1330    input_len: usize,
1331    out_handle: *mut *mut UorAddrGrounded,
1332) -> i32 {
1333    let s = match unsafe { borrow_input(input, input_len) } {
1334        Ok(s) => s,
1335        Err(code) => return code,
1336    };
1337    match json::address(s) {
1338        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1339        Err(e) => e.c_code(),
1340    }
1341}
1342
1343/// `json` realization — verifiable witness handle under a caller-selected
1344/// σ-axis (`UOR_ADDR_HASH_*`).
1345///
1346/// # Safety
1347///
1348/// As [`uor_addr_json_with_witness`].
1349#[cfg(feature = "alloc")]
1350#[no_mangle]
1351pub unsafe extern "C" fn uor_addr_json_with_witness_hash(
1352    algo: u8,
1353    input: *const u8,
1354    input_len: usize,
1355    out_handle: *mut *mut UorAddrGrounded,
1356) -> i32 {
1357    let s = match unsafe { borrow_input(input, input_len) } {
1358        Ok(s) => s,
1359        Err(code) => return code,
1360    };
1361    match algo {
1362        UOR_ADDR_HASH_SHA256 => match json::address(s) {
1363            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1364            Err(e) => e.c_code(),
1365        },
1366        UOR_ADDR_HASH_BLAKE3 => match json::address_blake3(s) {
1367            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1368            Err(e) => e.c_code(),
1369        },
1370        UOR_ADDR_HASH_SHA3_256 => match json::address_sha3_256(s) {
1371            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1372            Err(e) => e.c_code(),
1373        },
1374        UOR_ADDR_HASH_KECCAK256 => match json::address_keccak256(s) {
1375            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1376            Err(e) => e.c_code(),
1377        },
1378        UOR_ADDR_HASH_SHA512 => match json::address_sha512(s) {
1379            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1380            Err(e) => e.c_code(),
1381        },
1382        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1383    }
1384}
1385
1386/// `sexp` realization — SHA-256 verifiable witness handle.
1387///
1388/// # Safety
1389///
1390/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1391/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1392#[cfg(feature = "alloc")]
1393#[no_mangle]
1394pub unsafe extern "C" fn uor_addr_sexp_with_witness(
1395    input: *const u8,
1396    input_len: usize,
1397    out_handle: *mut *mut UorAddrGrounded,
1398) -> i32 {
1399    let s = match unsafe { borrow_input(input, input_len) } {
1400        Ok(s) => s,
1401        Err(code) => return code,
1402    };
1403    match sexp::address(s) {
1404        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1405        Err(e) => e.c_code(),
1406    }
1407}
1408
1409/// `sexp` realization — verifiable witness handle under a caller-selected
1410/// σ-axis (`UOR_ADDR_HASH_*`).
1411///
1412/// # Safety
1413///
1414/// As [`uor_addr_sexp_with_witness`].
1415#[cfg(feature = "alloc")]
1416#[no_mangle]
1417pub unsafe extern "C" fn uor_addr_sexp_with_witness_hash(
1418    algo: u8,
1419    input: *const u8,
1420    input_len: usize,
1421    out_handle: *mut *mut UorAddrGrounded,
1422) -> i32 {
1423    let s = match unsafe { borrow_input(input, input_len) } {
1424        Ok(s) => s,
1425        Err(code) => return code,
1426    };
1427    match algo {
1428        UOR_ADDR_HASH_SHA256 => match sexp::address(s) {
1429            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1430            Err(e) => e.c_code(),
1431        },
1432        UOR_ADDR_HASH_BLAKE3 => match sexp::address_blake3(s) {
1433            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1434            Err(e) => e.c_code(),
1435        },
1436        UOR_ADDR_HASH_SHA3_256 => match sexp::address_sha3_256(s) {
1437            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1438            Err(e) => e.c_code(),
1439        },
1440        UOR_ADDR_HASH_KECCAK256 => match sexp::address_keccak256(s) {
1441            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1442            Err(e) => e.c_code(),
1443        },
1444        UOR_ADDR_HASH_SHA512 => match sexp::address_sha512(s) {
1445            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1446            Err(e) => e.c_code(),
1447        },
1448        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1449    }
1450}
1451
1452/// `xml` realization — SHA-256 verifiable witness handle.
1453///
1454/// # Safety
1455///
1456/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1457/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1458#[cfg(feature = "alloc")]
1459#[no_mangle]
1460pub unsafe extern "C" fn uor_addr_xml_with_witness(
1461    input: *const u8,
1462    input_len: usize,
1463    out_handle: *mut *mut UorAddrGrounded,
1464) -> i32 {
1465    let s = match unsafe { borrow_input(input, input_len) } {
1466        Ok(s) => s,
1467        Err(code) => return code,
1468    };
1469    match xml::address(s) {
1470        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1471        Err(e) => e.c_code(),
1472    }
1473}
1474
1475/// `xml` realization — verifiable witness handle under a caller-selected
1476/// σ-axis (`UOR_ADDR_HASH_*`).
1477///
1478/// # Safety
1479///
1480/// As [`uor_addr_xml_with_witness`].
1481#[cfg(feature = "alloc")]
1482#[no_mangle]
1483pub unsafe extern "C" fn uor_addr_xml_with_witness_hash(
1484    algo: u8,
1485    input: *const u8,
1486    input_len: usize,
1487    out_handle: *mut *mut UorAddrGrounded,
1488) -> i32 {
1489    let s = match unsafe { borrow_input(input, input_len) } {
1490        Ok(s) => s,
1491        Err(code) => return code,
1492    };
1493    match algo {
1494        UOR_ADDR_HASH_SHA256 => match xml::address(s) {
1495            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1496            Err(e) => e.c_code(),
1497        },
1498        UOR_ADDR_HASH_BLAKE3 => match xml::address_blake3(s) {
1499            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1500            Err(e) => e.c_code(),
1501        },
1502        UOR_ADDR_HASH_SHA3_256 => match xml::address_sha3_256(s) {
1503            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1504            Err(e) => e.c_code(),
1505        },
1506        UOR_ADDR_HASH_KECCAK256 => match xml::address_keccak256(s) {
1507            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1508            Err(e) => e.c_code(),
1509        },
1510        UOR_ADDR_HASH_SHA512 => match xml::address_sha512(s) {
1511            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1512            Err(e) => e.c_code(),
1513        },
1514        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1515    }
1516}
1517
1518/// `asn1` realization — SHA-256 verifiable witness handle.
1519///
1520/// # Safety
1521///
1522/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1523/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1524#[cfg(feature = "alloc")]
1525#[no_mangle]
1526pub unsafe extern "C" fn uor_addr_asn1_with_witness(
1527    input: *const u8,
1528    input_len: usize,
1529    out_handle: *mut *mut UorAddrGrounded,
1530) -> i32 {
1531    let s = match unsafe { borrow_input(input, input_len) } {
1532        Ok(s) => s,
1533        Err(code) => return code,
1534    };
1535    match asn1::address(s) {
1536        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1537        Err(e) => e.c_code(),
1538    }
1539}
1540
1541/// `asn1` realization — verifiable witness handle under a caller-selected
1542/// σ-axis (`UOR_ADDR_HASH_*`).
1543///
1544/// # Safety
1545///
1546/// As [`uor_addr_asn1_with_witness`].
1547#[cfg(feature = "alloc")]
1548#[no_mangle]
1549pub unsafe extern "C" fn uor_addr_asn1_with_witness_hash(
1550    algo: u8,
1551    input: *const u8,
1552    input_len: usize,
1553    out_handle: *mut *mut UorAddrGrounded,
1554) -> i32 {
1555    let s = match unsafe { borrow_input(input, input_len) } {
1556        Ok(s) => s,
1557        Err(code) => return code,
1558    };
1559    match algo {
1560        UOR_ADDR_HASH_SHA256 => match asn1::address(s) {
1561            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1562            Err(e) => e.c_code(),
1563        },
1564        UOR_ADDR_HASH_BLAKE3 => match asn1::address_blake3(s) {
1565            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1566            Err(e) => e.c_code(),
1567        },
1568        UOR_ADDR_HASH_SHA3_256 => match asn1::address_sha3_256(s) {
1569            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1570            Err(e) => e.c_code(),
1571        },
1572        UOR_ADDR_HASH_KECCAK256 => match asn1::address_keccak256(s) {
1573            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1574            Err(e) => e.c_code(),
1575        },
1576        UOR_ADDR_HASH_SHA512 => match asn1::address_sha512(s) {
1577            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1578            Err(e) => e.c_code(),
1579        },
1580        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1581    }
1582}
1583
1584/// `ring` realization — SHA-256 verifiable witness handle.
1585///
1586/// # Safety
1587///
1588/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1589/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1590#[cfg(feature = "alloc")]
1591#[no_mangle]
1592pub unsafe extern "C" fn uor_addr_ring_with_witness(
1593    input: *const u8,
1594    input_len: usize,
1595    out_handle: *mut *mut UorAddrGrounded,
1596) -> i32 {
1597    let s = match unsafe { borrow_input(input, input_len) } {
1598        Ok(s) => s,
1599        Err(code) => return code,
1600    };
1601    match ring::address(s) {
1602        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1603        Err(e) => e.c_code(),
1604    }
1605}
1606
1607/// `ring` realization — verifiable witness handle under a caller-selected
1608/// σ-axis (`UOR_ADDR_HASH_*`).
1609///
1610/// # Safety
1611///
1612/// As [`uor_addr_ring_with_witness`].
1613#[cfg(feature = "alloc")]
1614#[no_mangle]
1615pub unsafe extern "C" fn uor_addr_ring_with_witness_hash(
1616    algo: u8,
1617    input: *const u8,
1618    input_len: usize,
1619    out_handle: *mut *mut UorAddrGrounded,
1620) -> i32 {
1621    let s = match unsafe { borrow_input(input, input_len) } {
1622        Ok(s) => s,
1623        Err(code) => return code,
1624    };
1625    match algo {
1626        UOR_ADDR_HASH_SHA256 => match ring::address(s) {
1627            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1628            Err(e) => e.c_code(),
1629        },
1630        UOR_ADDR_HASH_BLAKE3 => match ring::address_blake3(s) {
1631            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1632            Err(e) => e.c_code(),
1633        },
1634        UOR_ADDR_HASH_SHA3_256 => match ring::address_sha3_256(s) {
1635            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1636            Err(e) => e.c_code(),
1637        },
1638        UOR_ADDR_HASH_KECCAK256 => match ring::address_keccak256(s) {
1639            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1640            Err(e) => e.c_code(),
1641        },
1642        UOR_ADDR_HASH_SHA512 => match ring::address_sha512(s) {
1643            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1644            Err(e) => e.c_code(),
1645        },
1646        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1647    }
1648}
1649
1650/// `codemodule` realization — SHA-256 verifiable witness handle.
1651///
1652/// # Safety
1653///
1654/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1655/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1656#[cfg(feature = "alloc")]
1657#[no_mangle]
1658pub unsafe extern "C" fn uor_addr_codemodule_with_witness(
1659    input: *const u8,
1660    input_len: usize,
1661    out_handle: *mut *mut UorAddrGrounded,
1662) -> i32 {
1663    let s = match unsafe { borrow_input(input, input_len) } {
1664        Ok(s) => s,
1665        Err(code) => return code,
1666    };
1667    match codemodule::address(s) {
1668        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1669        Err(e) => e.c_code(),
1670    }
1671}
1672
1673/// `codemodule` realization — verifiable witness handle under a caller-selected
1674/// σ-axis (`UOR_ADDR_HASH_*`).
1675///
1676/// # Safety
1677///
1678/// As [`uor_addr_codemodule_with_witness`].
1679#[cfg(feature = "alloc")]
1680#[no_mangle]
1681pub unsafe extern "C" fn uor_addr_codemodule_with_witness_hash(
1682    algo: u8,
1683    input: *const u8,
1684    input_len: usize,
1685    out_handle: *mut *mut UorAddrGrounded,
1686) -> i32 {
1687    let s = match unsafe { borrow_input(input, input_len) } {
1688        Ok(s) => s,
1689        Err(code) => return code,
1690    };
1691    match algo {
1692        UOR_ADDR_HASH_SHA256 => match codemodule::address(s) {
1693            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1694            Err(e) => e.c_code(),
1695        },
1696        UOR_ADDR_HASH_BLAKE3 => match codemodule::address_blake3(s) {
1697            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1698            Err(e) => e.c_code(),
1699        },
1700        UOR_ADDR_HASH_SHA3_256 => match codemodule::address_sha3_256(s) {
1701            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1702            Err(e) => e.c_code(),
1703        },
1704        UOR_ADDR_HASH_KECCAK256 => match codemodule::address_keccak256(s) {
1705            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1706            Err(e) => e.c_code(),
1707        },
1708        UOR_ADDR_HASH_SHA512 => match codemodule::address_sha512(s) {
1709            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1710            Err(e) => e.c_code(),
1711        },
1712        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1713    }
1714}
1715
1716/// `cbor` realization — SHA-256 verifiable witness handle.
1717///
1718/// # Safety
1719///
1720/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1721/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1722#[cfg(feature = "alloc")]
1723#[no_mangle]
1724pub unsafe extern "C" fn uor_addr_cbor_with_witness(
1725    input: *const u8,
1726    input_len: usize,
1727    out_handle: *mut *mut UorAddrGrounded,
1728) -> i32 {
1729    let s = match unsafe { borrow_input(input, input_len) } {
1730        Ok(s) => s,
1731        Err(code) => return code,
1732    };
1733    match cbor::address(s) {
1734        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1735        Err(e) => e.c_code(),
1736    }
1737}
1738
1739/// `cbor` realization — verifiable witness handle under a caller-selected
1740/// σ-axis (`UOR_ADDR_HASH_*`).
1741///
1742/// # Safety
1743///
1744/// As [`uor_addr_cbor_with_witness`].
1745#[cfg(feature = "alloc")]
1746#[no_mangle]
1747pub unsafe extern "C" fn uor_addr_cbor_with_witness_hash(
1748    algo: u8,
1749    input: *const u8,
1750    input_len: usize,
1751    out_handle: *mut *mut UorAddrGrounded,
1752) -> i32 {
1753    let s = match unsafe { borrow_input(input, input_len) } {
1754        Ok(s) => s,
1755        Err(code) => return code,
1756    };
1757    match algo {
1758        UOR_ADDR_HASH_SHA256 => match cbor::address(s) {
1759            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1760            Err(e) => e.c_code(),
1761        },
1762        UOR_ADDR_HASH_BLAKE3 => match cbor::address_blake3(s) {
1763            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1764            Err(e) => e.c_code(),
1765        },
1766        UOR_ADDR_HASH_SHA3_256 => match cbor::address_sha3_256(s) {
1767            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1768            Err(e) => e.c_code(),
1769        },
1770        UOR_ADDR_HASH_KECCAK256 => match cbor::address_keccak256(s) {
1771            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1772            Err(e) => e.c_code(),
1773        },
1774        UOR_ADDR_HASH_SHA512 => match cbor::address_sha512(s) {
1775            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1776            Err(e) => e.c_code(),
1777        },
1778        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1779    }
1780}
1781
1782/// `schema_photo` realization — SHA-256 verifiable witness handle.
1783///
1784/// # Safety
1785///
1786/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1787/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1788#[cfg(feature = "alloc")]
1789#[no_mangle]
1790pub unsafe extern "C" fn uor_addr_schema_photo_with_witness(
1791    input: *const u8,
1792    input_len: usize,
1793    out_handle: *mut *mut UorAddrGrounded,
1794) -> i32 {
1795    let s = match unsafe { borrow_input(input, input_len) } {
1796        Ok(s) => s,
1797        Err(code) => return code,
1798    };
1799    match schema::photo::address(s) {
1800        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1801        Err(e) => e.c_code(),
1802    }
1803}
1804
1805/// `schema_photo` realization — verifiable witness handle under a caller-selected
1806/// σ-axis (`UOR_ADDR_HASH_*`).
1807///
1808/// # Safety
1809///
1810/// As [`uor_addr_schema_photo_with_witness`].
1811#[cfg(feature = "alloc")]
1812#[no_mangle]
1813pub unsafe extern "C" fn uor_addr_schema_photo_with_witness_hash(
1814    algo: u8,
1815    input: *const u8,
1816    input_len: usize,
1817    out_handle: *mut *mut UorAddrGrounded,
1818) -> i32 {
1819    let s = match unsafe { borrow_input(input, input_len) } {
1820        Ok(s) => s,
1821        Err(code) => return code,
1822    };
1823    match algo {
1824        UOR_ADDR_HASH_SHA256 => match schema::photo::address(s) {
1825            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1826            Err(e) => e.c_code(),
1827        },
1828        UOR_ADDR_HASH_BLAKE3 => match schema::photo::address_blake3(s) {
1829            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1830            Err(e) => e.c_code(),
1831        },
1832        UOR_ADDR_HASH_SHA3_256 => match schema::photo::address_sha3_256(s) {
1833            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1834            Err(e) => e.c_code(),
1835        },
1836        UOR_ADDR_HASH_KECCAK256 => match schema::photo::address_keccak256(s) {
1837            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1838            Err(e) => e.c_code(),
1839        },
1840        UOR_ADDR_HASH_SHA512 => match schema::photo::address_sha512(s) {
1841            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1842            Err(e) => e.c_code(),
1843        },
1844        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1845    }
1846}
1847
1848/// `schema_document` realization — SHA-256 verifiable witness handle.
1849///
1850/// # Safety
1851///
1852/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1853/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1854#[cfg(feature = "alloc")]
1855#[no_mangle]
1856pub unsafe extern "C" fn uor_addr_schema_document_with_witness(
1857    input: *const u8,
1858    input_len: usize,
1859    out_handle: *mut *mut UorAddrGrounded,
1860) -> i32 {
1861    let s = match unsafe { borrow_input(input, input_len) } {
1862        Ok(s) => s,
1863        Err(code) => return code,
1864    };
1865    match schema::document::address(s) {
1866        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1867        Err(e) => e.c_code(),
1868    }
1869}
1870
1871/// `schema_document` realization — verifiable witness handle under a caller-selected
1872/// σ-axis (`UOR_ADDR_HASH_*`).
1873///
1874/// # Safety
1875///
1876/// As [`uor_addr_schema_document_with_witness`].
1877#[cfg(feature = "alloc")]
1878#[no_mangle]
1879pub unsafe extern "C" fn uor_addr_schema_document_with_witness_hash(
1880    algo: u8,
1881    input: *const u8,
1882    input_len: usize,
1883    out_handle: *mut *mut UorAddrGrounded,
1884) -> i32 {
1885    let s = match unsafe { borrow_input(input, input_len) } {
1886        Ok(s) => s,
1887        Err(code) => return code,
1888    };
1889    match algo {
1890        UOR_ADDR_HASH_SHA256 => match schema::document::address(s) {
1891            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1892            Err(e) => e.c_code(),
1893        },
1894        UOR_ADDR_HASH_BLAKE3 => match schema::document::address_blake3(s) {
1895            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1896            Err(e) => e.c_code(),
1897        },
1898        UOR_ADDR_HASH_SHA3_256 => match schema::document::address_sha3_256(s) {
1899            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1900            Err(e) => e.c_code(),
1901        },
1902        UOR_ADDR_HASH_KECCAK256 => match schema::document::address_keccak256(s) {
1903            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1904            Err(e) => e.c_code(),
1905        },
1906        UOR_ADDR_HASH_SHA512 => match schema::document::address_sha512(s) {
1907            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1908            Err(e) => e.c_code(),
1909        },
1910        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1911    }
1912}
1913
1914/// `schema_codemodule_signed` realization — SHA-256 verifiable witness handle.
1915///
1916/// # Safety
1917///
1918/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1919/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1920#[cfg(feature = "alloc")]
1921#[no_mangle]
1922pub unsafe extern "C" fn uor_addr_schema_codemodule_signed_with_witness(
1923    input: *const u8,
1924    input_len: usize,
1925    out_handle: *mut *mut UorAddrGrounded,
1926) -> i32 {
1927    let s = match unsafe { borrow_input(input, input_len) } {
1928        Ok(s) => s,
1929        Err(code) => return code,
1930    };
1931    match schema::codemodule_signed::address(s) {
1932        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1933        Err(e) => e.c_code(),
1934    }
1935}
1936
1937/// `schema_codemodule_signed` realization — verifiable witness handle under a caller-selected
1938/// σ-axis (`UOR_ADDR_HASH_*`).
1939///
1940/// # Safety
1941///
1942/// As [`uor_addr_schema_codemodule_signed_with_witness`].
1943#[cfg(feature = "alloc")]
1944#[no_mangle]
1945pub unsafe extern "C" fn uor_addr_schema_codemodule_signed_with_witness_hash(
1946    algo: u8,
1947    input: *const u8,
1948    input_len: usize,
1949    out_handle: *mut *mut UorAddrGrounded,
1950) -> i32 {
1951    let s = match unsafe { borrow_input(input, input_len) } {
1952        Ok(s) => s,
1953        Err(code) => return code,
1954    };
1955    match algo {
1956        UOR_ADDR_HASH_SHA256 => match schema::codemodule_signed::address(s) {
1957            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1958            Err(e) => e.c_code(),
1959        },
1960        UOR_ADDR_HASH_BLAKE3 => match schema::codemodule_signed::address_blake3(s) {
1961            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1962            Err(e) => e.c_code(),
1963        },
1964        UOR_ADDR_HASH_SHA3_256 => match schema::codemodule_signed::address_sha3_256(s) {
1965            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
1966            Err(e) => e.c_code(),
1967        },
1968        UOR_ADDR_HASH_KECCAK256 => match schema::codemodule_signed::address_keccak256(s) {
1969            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
1970            Err(e) => e.c_code(),
1971        },
1972        UOR_ADDR_HASH_SHA512 => match schema::codemodule_signed::address_sha512(s) {
1973            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
1974            Err(e) => e.c_code(),
1975        },
1976        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
1977    }
1978}
1979
1980/// `gguf` realization — SHA-256 verifiable witness handle.
1981///
1982/// # Safety
1983///
1984/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
1985/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
1986#[cfg(feature = "gguf")]
1987#[no_mangle]
1988pub unsafe extern "C" fn uor_addr_gguf_with_witness(
1989    input: *const u8,
1990    input_len: usize,
1991    out_handle: *mut *mut UorAddrGrounded,
1992) -> i32 {
1993    let s = match unsafe { borrow_input(input, input_len) } {
1994        Ok(s) => s,
1995        Err(code) => return code,
1996    };
1997    match uor_addr::gguf::address(s) {
1998        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
1999        Err(e) => e.c_code(),
2000    }
2001}
2002
2003/// `gguf` realization — verifiable witness handle under a caller-selected
2004/// σ-axis (`UOR_ADDR_HASH_*`).
2005///
2006/// # Safety
2007///
2008/// As [`uor_addr_gguf_with_witness`].
2009#[cfg(feature = "gguf")]
2010#[no_mangle]
2011pub unsafe extern "C" fn uor_addr_gguf_with_witness_hash(
2012    algo: u8,
2013    input: *const u8,
2014    input_len: usize,
2015    out_handle: *mut *mut UorAddrGrounded,
2016) -> i32 {
2017    let s = match unsafe { borrow_input(input, input_len) } {
2018        Ok(s) => s,
2019        Err(code) => return code,
2020    };
2021    match algo {
2022        UOR_ADDR_HASH_SHA256 => match uor_addr::gguf::address(s) {
2023            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2024            Err(e) => e.c_code(),
2025        },
2026        UOR_ADDR_HASH_BLAKE3 => match uor_addr::gguf::address_blake3(s) {
2027            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2028            Err(e) => e.c_code(),
2029        },
2030        UOR_ADDR_HASH_SHA3_256 => match uor_addr::gguf::address_sha3_256(s) {
2031            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2032            Err(e) => e.c_code(),
2033        },
2034        UOR_ADDR_HASH_KECCAK256 => match uor_addr::gguf::address_keccak256(s) {
2035            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2036            Err(e) => e.c_code(),
2037        },
2038        UOR_ADDR_HASH_SHA512 => match uor_addr::gguf::address_sha512(s) {
2039            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2040            Err(e) => e.c_code(),
2041        },
2042        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2043    }
2044}
2045
2046/// `onnx` realization — SHA-256 verifiable witness handle.
2047///
2048/// # Safety
2049///
2050/// - `input` null (with `input_len == 0`) or readable for `input_len` bytes.
2051/// - `out_handle` is a valid writable `*mut UorAddrGrounded`.
2052#[cfg(feature = "onnx")]
2053#[no_mangle]
2054pub unsafe extern "C" fn uor_addr_onnx_with_witness(
2055    input: *const u8,
2056    input_len: usize,
2057    out_handle: *mut *mut UorAddrGrounded,
2058) -> i32 {
2059    let s = match unsafe { borrow_input(input, input_len) } {
2060        Ok(s) => s,
2061        Err(code) => return code,
2062    };
2063    match uor_addr::onnx::address(s) {
2064        Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2065        Err(e) => e.c_code(),
2066    }
2067}
2068
2069/// `onnx` realization — verifiable witness handle under a caller-selected
2070/// σ-axis (`UOR_ADDR_HASH_*`).
2071///
2072/// # Safety
2073///
2074/// As [`uor_addr_onnx_with_witness`].
2075#[cfg(feature = "onnx")]
2076#[no_mangle]
2077pub unsafe extern "C" fn uor_addr_onnx_with_witness_hash(
2078    algo: u8,
2079    input: *const u8,
2080    input_len: usize,
2081    out_handle: *mut *mut UorAddrGrounded,
2082) -> i32 {
2083    let s = match unsafe { borrow_input(input, input_len) } {
2084        Ok(s) => s,
2085        Err(code) => return code,
2086    };
2087    match algo {
2088        UOR_ADDR_HASH_SHA256 => match uor_addr::onnx::address(s) {
2089            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2090            Err(e) => e.c_code(),
2091        },
2092        UOR_ADDR_HASH_BLAKE3 => match uor_addr::onnx::address_blake3(s) {
2093            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2094            Err(e) => e.c_code(),
2095        },
2096        UOR_ADDR_HASH_SHA3_256 => match uor_addr::onnx::address_sha3_256(s) {
2097            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2098            Err(e) => e.c_code(),
2099        },
2100        UOR_ADDR_HASH_KECCAK256 => match uor_addr::onnx::address_keccak256(s) {
2101            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2102            Err(e) => e.c_code(),
2103        },
2104        UOR_ADDR_HASH_SHA512 => match uor_addr::onnx::address_sha512(s) {
2105            Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2106            Err(e) => e.c_code(),
2107        },
2108        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2109    }
2110}
2111
2112// ═══ κ-label composition (ADR-061) C entry points ══════════════════
2113//
2114// Operands are κ-label byte strings; `algo` (a `UOR_ADDR_HASH_*` selector)
2115// fixes the operand width and the composed axis. Each op offers a label
2116// entry point and a witness entry point. CS-G2 is binary; the rest unary.
2117
2118/// CS-G2 composition (label). `algo` selects the σ-axis (operand
2119/// width + composed axis); `out_label` must be writable for at least
2120/// `UOR_ADDR_MAX_LABEL_BYTES` bytes.
2121///
2122/// # Safety
2123///
2124/// Operand pointers are null (with len 0) or readable for their lengths;
2125/// `out_label` writable for `out_label_len`; `out_written` if non-null
2126/// writable.
2127#[cfg(feature = "alloc")]
2128#[no_mangle]
2129pub unsafe extern "C" fn uor_addr_compose_g2(
2130    algo: u8,
2131    left: *const u8,
2132    left_len: usize,
2133    right: *const u8,
2134    right_len: usize,
2135    out_label: *mut u8,
2136    out_label_len: usize,
2137    out_written: *mut usize,
2138) -> i32 {
2139    let l = match unsafe { borrow_input(left, left_len) } {
2140        Ok(s) => s,
2141        Err(c) => return c,
2142    };
2143    let r = match unsafe { borrow_input(right, right_len) } {
2144        Ok(s) => s,
2145        Err(c) => return c,
2146    };
2147    match algo {
2148        UOR_ADDR_HASH_SHA256 => match (
2149            KappaLabel::<71>::from_bytes(l),
2150            KappaLabel::<71>::from_bytes(r),
2151        ) {
2152            (Ok(la), Ok(ra)) => match composition::compose_g2_product(&la, &ra) {
2153                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2154                Err(e) => compose_code(e),
2155            },
2156            _ => UOR_ADDR_ERR_INVALID_INPUT,
2157        },
2158        UOR_ADDR_HASH_BLAKE3 => match (
2159            KappaLabel::<71>::from_bytes(l),
2160            KappaLabel::<71>::from_bytes(r),
2161        ) {
2162            (Ok(la), Ok(ra)) => match composition::compose_g2_product_blake3(&la, &ra) {
2163                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2164                Err(e) => compose_code(e),
2165            },
2166            _ => UOR_ADDR_ERR_INVALID_INPUT,
2167        },
2168        UOR_ADDR_HASH_SHA3_256 => match (
2169            KappaLabel::<73>::from_bytes(l),
2170            KappaLabel::<73>::from_bytes(r),
2171        ) {
2172            (Ok(la), Ok(ra)) => match composition::compose_g2_product_sha3_256(&la, &ra) {
2173                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2174                Err(e) => compose_code(e),
2175            },
2176            _ => UOR_ADDR_ERR_INVALID_INPUT,
2177        },
2178        UOR_ADDR_HASH_KECCAK256 => match (
2179            KappaLabel::<74>::from_bytes(l),
2180            KappaLabel::<74>::from_bytes(r),
2181        ) {
2182            (Ok(la), Ok(ra)) => match composition::compose_g2_product_keccak256(&la, &ra) {
2183                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2184                Err(e) => compose_code(e),
2185            },
2186            _ => UOR_ADDR_ERR_INVALID_INPUT,
2187        },
2188        UOR_ADDR_HASH_SHA512 => match (
2189            KappaLabel::<135>::from_bytes(l),
2190            KappaLabel::<135>::from_bytes(r),
2191        ) {
2192            (Ok(la), Ok(ra)) => match composition::compose_g2_product_sha512(&la, &ra) {
2193                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2194                Err(e) => compose_code(e),
2195            },
2196            _ => UOR_ADDR_ERR_INVALID_INPUT,
2197        },
2198        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2199    }
2200}
2201
2202/// CS-G2 composition (verifiable witness handle). See
2203/// [`uor_addr_compose_g2`].
2204///
2205/// # Safety
2206///
2207/// As [`uor_addr_compose_g2`]; `out_handle` is a valid writable
2208/// `*mut UorAddrGrounded`.
2209#[cfg(feature = "alloc")]
2210#[no_mangle]
2211pub unsafe extern "C" fn uor_addr_compose_g2_with_witness(
2212    algo: u8,
2213    left: *const u8,
2214    left_len: usize,
2215    right: *const u8,
2216    right_len: usize,
2217    out_handle: *mut *mut UorAddrGrounded,
2218) -> i32 {
2219    let l = match unsafe { borrow_input(left, left_len) } {
2220        Ok(s) => s,
2221        Err(c) => return c,
2222    };
2223    let r = match unsafe { borrow_input(right, right_len) } {
2224        Ok(s) => s,
2225        Err(c) => return c,
2226    };
2227    match algo {
2228        UOR_ADDR_HASH_SHA256 => match (
2229            KappaLabel::<71>::from_bytes(l),
2230            KappaLabel::<71>::from_bytes(r),
2231        ) {
2232            (Ok(la), Ok(ra)) => match composition::compose_g2_product(&la, &ra) {
2233                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2234                Err(e) => compose_code(e),
2235            },
2236            _ => UOR_ADDR_ERR_INVALID_INPUT,
2237        },
2238        UOR_ADDR_HASH_BLAKE3 => match (
2239            KappaLabel::<71>::from_bytes(l),
2240            KappaLabel::<71>::from_bytes(r),
2241        ) {
2242            (Ok(la), Ok(ra)) => match composition::compose_g2_product_blake3(&la, &ra) {
2243                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2244                Err(e) => compose_code(e),
2245            },
2246            _ => UOR_ADDR_ERR_INVALID_INPUT,
2247        },
2248        UOR_ADDR_HASH_SHA3_256 => match (
2249            KappaLabel::<73>::from_bytes(l),
2250            KappaLabel::<73>::from_bytes(r),
2251        ) {
2252            (Ok(la), Ok(ra)) => match composition::compose_g2_product_sha3_256(&la, &ra) {
2253                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2254                Err(e) => compose_code(e),
2255            },
2256            _ => UOR_ADDR_ERR_INVALID_INPUT,
2257        },
2258        UOR_ADDR_HASH_KECCAK256 => match (
2259            KappaLabel::<74>::from_bytes(l),
2260            KappaLabel::<74>::from_bytes(r),
2261        ) {
2262            (Ok(la), Ok(ra)) => match composition::compose_g2_product_keccak256(&la, &ra) {
2263                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2264                Err(e) => compose_code(e),
2265            },
2266            _ => UOR_ADDR_ERR_INVALID_INPUT,
2267        },
2268        UOR_ADDR_HASH_SHA512 => match (
2269            KappaLabel::<135>::from_bytes(l),
2270            KappaLabel::<135>::from_bytes(r),
2271        ) {
2272            (Ok(la), Ok(ra)) => match composition::compose_g2_product_sha512(&la, &ra) {
2273                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2274                Err(e) => compose_code(e),
2275            },
2276            _ => UOR_ADDR_ERR_INVALID_INPUT,
2277        },
2278        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2279    }
2280}
2281
2282/// CS-F4 composition (label). `algo` selects the σ-axis (operand
2283/// width + composed axis); `out_label` must be writable for at least
2284/// `UOR_ADDR_MAX_LABEL_BYTES` bytes.
2285///
2286/// # Safety
2287///
2288/// Operand pointers are null (with len 0) or readable for their lengths;
2289/// `out_label` writable for `out_label_len`; `out_written` if non-null
2290/// writable.
2291#[cfg(feature = "alloc")]
2292#[no_mangle]
2293pub unsafe extern "C" fn uor_addr_compose_f4(
2294    algo: u8,
2295    operand: *const u8,
2296    operand_len: usize,
2297    out_label: *mut u8,
2298    out_label_len: usize,
2299    out_written: *mut usize,
2300) -> i32 {
2301    let s = match unsafe { borrow_input(operand, operand_len) } {
2302        Ok(s) => s,
2303        Err(c) => return c,
2304    };
2305    match algo {
2306        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2307            Ok(l) => match composition::compose_f4_quotient(&l) {
2308                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2309                Err(e) => compose_code(e),
2310            },
2311            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2312        },
2313        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2314            Ok(l) => match composition::compose_f4_quotient_blake3(&l) {
2315                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2316                Err(e) => compose_code(e),
2317            },
2318            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2319        },
2320        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2321            Ok(l) => match composition::compose_f4_quotient_sha3_256(&l) {
2322                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2323                Err(e) => compose_code(e),
2324            },
2325            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2326        },
2327        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2328            Ok(l) => match composition::compose_f4_quotient_keccak256(&l) {
2329                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2330                Err(e) => compose_code(e),
2331            },
2332            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2333        },
2334        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2335            Ok(l) => match composition::compose_f4_quotient_sha512(&l) {
2336                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2337                Err(e) => compose_code(e),
2338            },
2339            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2340        },
2341        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2342    }
2343}
2344
2345/// CS-F4 composition (verifiable witness handle). See
2346/// [`uor_addr_compose_f4`].
2347///
2348/// # Safety
2349///
2350/// As [`uor_addr_compose_f4`]; `out_handle` is a valid writable
2351/// `*mut UorAddrGrounded`.
2352#[cfg(feature = "alloc")]
2353#[no_mangle]
2354pub unsafe extern "C" fn uor_addr_compose_f4_with_witness(
2355    algo: u8,
2356    operand: *const u8,
2357    operand_len: usize,
2358    out_handle: *mut *mut UorAddrGrounded,
2359) -> i32 {
2360    let s = match unsafe { borrow_input(operand, operand_len) } {
2361        Ok(s) => s,
2362        Err(c) => return c,
2363    };
2364    match algo {
2365        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2366            Ok(l) => match composition::compose_f4_quotient(&l) {
2367                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2368                Err(e) => compose_code(e),
2369            },
2370            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2371        },
2372        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2373            Ok(l) => match composition::compose_f4_quotient_blake3(&l) {
2374                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2375                Err(e) => compose_code(e),
2376            },
2377            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2378        },
2379        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2380            Ok(l) => match composition::compose_f4_quotient_sha3_256(&l) {
2381                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2382                Err(e) => compose_code(e),
2383            },
2384            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2385        },
2386        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2387            Ok(l) => match composition::compose_f4_quotient_keccak256(&l) {
2388                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2389                Err(e) => compose_code(e),
2390            },
2391            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2392        },
2393        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2394            Ok(l) => match composition::compose_f4_quotient_sha512(&l) {
2395                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2396                Err(e) => compose_code(e),
2397            },
2398            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2399        },
2400        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2401    }
2402}
2403
2404/// CS-E6 composition (label). `algo` selects the σ-axis (operand
2405/// width + composed axis); `out_label` must be writable for at least
2406/// `UOR_ADDR_MAX_LABEL_BYTES` bytes.
2407///
2408/// # Safety
2409///
2410/// Operand pointers are null (with len 0) or readable for their lengths;
2411/// `out_label` writable for `out_label_len`; `out_written` if non-null
2412/// writable.
2413#[cfg(feature = "alloc")]
2414#[no_mangle]
2415pub unsafe extern "C" fn uor_addr_compose_e6(
2416    algo: u8,
2417    operand: *const u8,
2418    operand_len: usize,
2419    out_label: *mut u8,
2420    out_label_len: usize,
2421    out_written: *mut usize,
2422) -> i32 {
2423    let s = match unsafe { borrow_input(operand, operand_len) } {
2424        Ok(s) => s,
2425        Err(c) => return c,
2426    };
2427    match algo {
2428        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2429            Ok(l) => match composition::compose_e6_filtration(&l) {
2430                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2431                Err(e) => compose_code(e),
2432            },
2433            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2434        },
2435        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2436            Ok(l) => match composition::compose_e6_filtration_blake3(&l) {
2437                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2438                Err(e) => compose_code(e),
2439            },
2440            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2441        },
2442        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2443            Ok(l) => match composition::compose_e6_filtration_sha3_256(&l) {
2444                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2445                Err(e) => compose_code(e),
2446            },
2447            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2448        },
2449        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2450            Ok(l) => match composition::compose_e6_filtration_keccak256(&l) {
2451                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2452                Err(e) => compose_code(e),
2453            },
2454            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2455        },
2456        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2457            Ok(l) => match composition::compose_e6_filtration_sha512(&l) {
2458                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2459                Err(e) => compose_code(e),
2460            },
2461            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2462        },
2463        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2464    }
2465}
2466
2467/// CS-E6 composition (verifiable witness handle). See
2468/// [`uor_addr_compose_e6`].
2469///
2470/// # Safety
2471///
2472/// As [`uor_addr_compose_e6`]; `out_handle` is a valid writable
2473/// `*mut UorAddrGrounded`.
2474#[cfg(feature = "alloc")]
2475#[no_mangle]
2476pub unsafe extern "C" fn uor_addr_compose_e6_with_witness(
2477    algo: u8,
2478    operand: *const u8,
2479    operand_len: usize,
2480    out_handle: *mut *mut UorAddrGrounded,
2481) -> i32 {
2482    let s = match unsafe { borrow_input(operand, operand_len) } {
2483        Ok(s) => s,
2484        Err(c) => return c,
2485    };
2486    match algo {
2487        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2488            Ok(l) => match composition::compose_e6_filtration(&l) {
2489                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2490                Err(e) => compose_code(e),
2491            },
2492            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2493        },
2494        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2495            Ok(l) => match composition::compose_e6_filtration_blake3(&l) {
2496                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2497                Err(e) => compose_code(e),
2498            },
2499            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2500        },
2501        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2502            Ok(l) => match composition::compose_e6_filtration_sha3_256(&l) {
2503                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2504                Err(e) => compose_code(e),
2505            },
2506            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2507        },
2508        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2509            Ok(l) => match composition::compose_e6_filtration_keccak256(&l) {
2510                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2511                Err(e) => compose_code(e),
2512            },
2513            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2514        },
2515        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2516            Ok(l) => match composition::compose_e6_filtration_sha512(&l) {
2517                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2518                Err(e) => compose_code(e),
2519            },
2520            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2521        },
2522        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2523    }
2524}
2525
2526/// CS-E7 composition (label). `algo` selects the σ-axis (operand
2527/// width + composed axis); `out_label` must be writable for at least
2528/// `UOR_ADDR_MAX_LABEL_BYTES` bytes.
2529///
2530/// # Safety
2531///
2532/// Operand pointers are null (with len 0) or readable for their lengths;
2533/// `out_label` writable for `out_label_len`; `out_written` if non-null
2534/// writable.
2535#[cfg(feature = "alloc")]
2536#[no_mangle]
2537pub unsafe extern "C" fn uor_addr_compose_e7(
2538    algo: u8,
2539    operand: *const u8,
2540    operand_len: usize,
2541    out_label: *mut u8,
2542    out_label_len: usize,
2543    out_written: *mut usize,
2544) -> i32 {
2545    let s = match unsafe { borrow_input(operand, operand_len) } {
2546        Ok(s) => s,
2547        Err(c) => return c,
2548    };
2549    match algo {
2550        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2551            Ok(l) => match composition::compose_e7_augmentation(&l) {
2552                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2553                Err(e) => compose_code(e),
2554            },
2555            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2556        },
2557        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2558            Ok(l) => match composition::compose_e7_augmentation_blake3(&l) {
2559                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2560                Err(e) => compose_code(e),
2561            },
2562            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2563        },
2564        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2565            Ok(l) => match composition::compose_e7_augmentation_sha3_256(&l) {
2566                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2567                Err(e) => compose_code(e),
2568            },
2569            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2570        },
2571        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2572            Ok(l) => match composition::compose_e7_augmentation_keccak256(&l) {
2573                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2574                Err(e) => compose_code(e),
2575            },
2576            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2577        },
2578        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2579            Ok(l) => match composition::compose_e7_augmentation_sha512(&l) {
2580                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2581                Err(e) => compose_code(e),
2582            },
2583            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2584        },
2585        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2586    }
2587}
2588
2589/// CS-E7 composition (verifiable witness handle). See
2590/// [`uor_addr_compose_e7`].
2591///
2592/// # Safety
2593///
2594/// As [`uor_addr_compose_e7`]; `out_handle` is a valid writable
2595/// `*mut UorAddrGrounded`.
2596#[cfg(feature = "alloc")]
2597#[no_mangle]
2598pub unsafe extern "C" fn uor_addr_compose_e7_with_witness(
2599    algo: u8,
2600    operand: *const u8,
2601    operand_len: usize,
2602    out_handle: *mut *mut UorAddrGrounded,
2603) -> i32 {
2604    let s = match unsafe { borrow_input(operand, operand_len) } {
2605        Ok(s) => s,
2606        Err(c) => return c,
2607    };
2608    match algo {
2609        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2610            Ok(l) => match composition::compose_e7_augmentation(&l) {
2611                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2612                Err(e) => compose_code(e),
2613            },
2614            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2615        },
2616        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2617            Ok(l) => match composition::compose_e7_augmentation_blake3(&l) {
2618                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2619                Err(e) => compose_code(e),
2620            },
2621            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2622        },
2623        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2624            Ok(l) => match composition::compose_e7_augmentation_sha3_256(&l) {
2625                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2626                Err(e) => compose_code(e),
2627            },
2628            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2629        },
2630        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2631            Ok(l) => match composition::compose_e7_augmentation_keccak256(&l) {
2632                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2633                Err(e) => compose_code(e),
2634            },
2635            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2636        },
2637        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2638            Ok(l) => match composition::compose_e7_augmentation_sha512(&l) {
2639                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2640                Err(e) => compose_code(e),
2641            },
2642            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2643        },
2644        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2645    }
2646}
2647
2648/// CS-E8 composition (label). `algo` selects the σ-axis (operand
2649/// width + composed axis); `out_label` must be writable for at least
2650/// `UOR_ADDR_MAX_LABEL_BYTES` bytes.
2651///
2652/// # Safety
2653///
2654/// Operand pointers are null (with len 0) or readable for their lengths;
2655/// `out_label` writable for `out_label_len`; `out_written` if non-null
2656/// writable.
2657#[cfg(feature = "alloc")]
2658#[no_mangle]
2659pub unsafe extern "C" fn uor_addr_compose_e8(
2660    algo: u8,
2661    operand: *const u8,
2662    operand_len: usize,
2663    out_label: *mut u8,
2664    out_label_len: usize,
2665    out_written: *mut usize,
2666) -> i32 {
2667    let s = match unsafe { borrow_input(operand, operand_len) } {
2668        Ok(s) => s,
2669        Err(c) => return c,
2670    };
2671    match algo {
2672        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2673            Ok(l) => match composition::compose_e8_embedding(&l) {
2674                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2675                Err(e) => compose_code(e),
2676            },
2677            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2678        },
2679        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2680            Ok(l) => match composition::compose_e8_embedding_blake3(&l) {
2681                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2682                Err(e) => compose_code(e),
2683            },
2684            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2685        },
2686        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2687            Ok(l) => match composition::compose_e8_embedding_sha3_256(&l) {
2688                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2689                Err(e) => compose_code(e),
2690            },
2691            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2692        },
2693        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2694            Ok(l) => match composition::compose_e8_embedding_keccak256(&l) {
2695                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2696                Err(e) => compose_code(e),
2697            },
2698            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2699        },
2700        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2701            Ok(l) => match composition::compose_e8_embedding_sha512(&l) {
2702                Ok(o) => unsafe { write_outcome(o, out_label, out_label_len, out_written) },
2703                Err(e) => compose_code(e),
2704            },
2705            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2706        },
2707        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2708    }
2709}
2710
2711/// CS-E8 composition (verifiable witness handle). See
2712/// [`uor_addr_compose_e8`].
2713///
2714/// # Safety
2715///
2716/// As [`uor_addr_compose_e8`]; `out_handle` is a valid writable
2717/// `*mut UorAddrGrounded`.
2718#[cfg(feature = "alloc")]
2719#[no_mangle]
2720pub unsafe extern "C" fn uor_addr_compose_e8_with_witness(
2721    algo: u8,
2722    operand: *const u8,
2723    operand_len: usize,
2724    out_handle: *mut *mut UorAddrGrounded,
2725) -> i32 {
2726    let s = match unsafe { borrow_input(operand, operand_len) } {
2727        Ok(s) => s,
2728        Err(c) => return c,
2729    };
2730    match algo {
2731        UOR_ADDR_HASH_SHA256 => match KappaLabel::<71>::from_bytes(s) {
2732            Ok(l) => match composition::compose_e8_embedding(&l) {
2733                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2734                Err(e) => compose_code(e),
2735            },
2736            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2737        },
2738        UOR_ADDR_HASH_BLAKE3 => match KappaLabel::<71>::from_bytes(s) {
2739            Ok(l) => match composition::compose_e8_embedding_blake3(&l) {
2740                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W71(o), out_handle) },
2741                Err(e) => compose_code(e),
2742            },
2743            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2744        },
2745        UOR_ADDR_HASH_SHA3_256 => match KappaLabel::<73>::from_bytes(s) {
2746            Ok(l) => match composition::compose_e8_embedding_sha3_256(&l) {
2747                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W73(o), out_handle) },
2748                Err(e) => compose_code(e),
2749            },
2750            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2751        },
2752        UOR_ADDR_HASH_KECCAK256 => match KappaLabel::<74>::from_bytes(s) {
2753            Ok(l) => match composition::compose_e8_embedding_keccak256(&l) {
2754                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W74(o), out_handle) },
2755                Err(e) => compose_code(e),
2756            },
2757            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2758        },
2759        UOR_ADDR_HASH_SHA512 => match KappaLabel::<135>::from_bytes(s) {
2760            Ok(l) => match composition::compose_e8_embedding_sha512(&l) {
2761                Ok(o) => unsafe { write_grounded_any(AnyOutcome::W512(o), out_handle) },
2762                Err(e) => compose_code(e),
2763            },
2764            Err(_) => UOR_ADDR_ERR_INVALID_INPUT,
2765        },
2766        _ => UOR_ADDR_ERR_UNKNOWN_HASH,
2767    }
2768}
2769
2770// ─── Panic handler for `no_std` builds without `std` ───────────────
2771
2772// Panic handler is required on any `no_std` target. With `--features std`
2773// the standard library provides one and this stub is suppressed. The
2774// no_alloc surface never panics on well-formed input (bound checks
2775// return error codes); the handler is a safety net for unreachable
2776// arms.
2777// On bare-metal targets (`target_os = "none"`, e.g.
2778// `thumbv7em-none-eabihf`) no `std`-provided panic handler is
2779// linkable, so the crate must supply one. Hosted targets
2780// (`linux`, `macos`, `windows`, …) take `std::panic`'s default.
2781// We key off `target_os = "none"` rather than `feature = "std"` so
2782// cargo's workspace feature-unification (which can enable `std` in
2783// transitive deps for `--all-targets` test builds) doesn't cause a
2784// duplicate `panic_impl` lang item.
2785// Embedded bare-metal builds get our panic handler; hosted builds
2786// (`target_os = linux/macos/windows/…`) pull `std`'s default via the
2787// `std` feature.
2788#[cfg(all(not(feature = "std"), target_os = "none"))]
2789#[panic_handler]
2790fn panic(_info: &core::panic::PanicInfo) -> ! {
2791    loop {}
2792}