MCEL: Merkle-Chaining Event Ledger
1.0.0.0a (A1)
A post-quantum secure block-chain ledger system
udil.h
Go to the documentation of this file.
1
/* 2025-2026 Quantum Resistant Cryptographic Solutions Corporation
2
* All Rights Reserved.
3
*
4
* NOTICE:
5
* This software and all accompanying materials are the exclusive property of
6
* Quantum Resistant Cryptographic Solutions Corporation (QRCS). The intellectual
7
* and technical concepts contained herein are proprietary to QRCS and are
8
* protected under applicable Canadian, U.S., and international copyright,
9
* patent, and trade secret laws.
10
*
11
* CRYPTOGRAPHIC ALGORITHMS AND IMPLEMENTATIONS:
12
* - This software includes implementations of cryptographic primitives and
13
* algorithms that are standardized or in the public domain, such as AES
14
* and SHA-3, which are not proprietary to QRCS.
15
* - This software also includes cryptographic primitives, constructions, and
16
* algorithms designed by QRCS, including but not limited to RCS, SCB, CSX, QMAC, and
17
* related components, which are proprietary to QRCS.
18
* - All source code, implementations, protocol compositions, optimizations,
19
* parameter selections, and engineering work contained in this software are
20
* original works of QRCS and are protected under this license.
21
*
22
* LICENSE AND USE RESTRICTIONS:
23
* - This software is licensed under the Quantum Resistant Cryptographic Solutions
24
* Public Research and Evaluation License (QRCS-PREL), 2025-2026.
25
* - Permission is granted solely for non-commercial evaluation, academic research,
26
* cryptographic analysis, interoperability testing, and feasibility assessment.
27
* - Commercial use, production deployment, commercial redistribution, or
28
* integration into products or services is strictly prohibited without a
29
* separate written license agreement executed with QRCS.
30
* - Licensing and authorized distribution are solely at the discretion of QRCS.
31
*
32
* EXPERIMENTAL CRYPTOGRAPHY NOTICE:
33
* Portions of this software may include experimental, novel, or evolving
34
* cryptographic designs. Use of this software is entirely at the user's risk.
35
*
36
* DISCLAIMER:
37
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
* IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS
39
* FOR A PARTICULAR PURPOSE, SECURITY, OR NON-INFRINGEMENT. QRCS DISCLAIMS ALL
40
* LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
41
* ARISING FROM THE USE OR MISUSE OF THIS SOFTWARE.
42
*
43
* FULL LICENSE:
44
* This software is subject to the Quantum Resistant Cryptographic Solutions
45
* Public Research and Evaluation License (QRCS-PREL), 2025-2026. The complete license terms
46
* are provided in the accompanying LICENSE file or at https://www.qrcscorp.ca.
47
*
48
* Written by: John G. Underhill
49
* Contact: contact\qrcscorp.ca
50
*/
51
52
#ifndef UDIL_H
53
#define UDIL_H
54
55
#include "udilcommon.h"
56
106
107
//#define UDIL_HASHLEN 32
108
//#define MAX_DEPTH 64
109
//
110
//static const uint8_t TAG_CHK[] = "UDIL/CHK";
111
//static const uint8_t TAG_ENV[] = "UDIL/ENV";
112
//static const uint8_t TAG_ID[] = "UDIL/ID";
113
//static const uint8_t TAG_LEAF[] = "UDIL/LEAF";
114
//static const uint8_t TAG_NODE[] = "UDIL/NODE";
115
//static const uint8_t TAG_PAY[] = "UDIL/PAY";
116
//static const uint8_t TAG_REC[] = "UDIL/REC";
117
//static const uint8_t TAG_SIG_CHK[] = "UDIL/SIG/CHK";
118
//static const uint8_t TAG_SIG_REC[] = "UDIL/SIG/REC";
119
//
120
//UDIL_EXPORT_API typedef enum
121
//{
122
// RTYPE_MESSAGE = 0x0001,
123
// RTYPE_ACK = 0x0002,
124
// RTYPE_NACK = 0x0003,
125
// RTYPE_RECEIPT = 0x0004,
126
// RTYPE_ADMIN = 0x0005,
127
// RTYPE_CHECKPOINT = 0x0006,
128
// RTYPE_ANCHOR_REF = 0x0007
129
//} udil_record_type;
130
//
131
//UDIL_EXPORT_API typedef struct udil_anchor_ref
132
//{
133
// uint16_t version;
134
// uint8_t chk_commit[UDIL_HASHLEN];
135
// uint16_t anchor_type; // 1=consortium, 2=regulator, 3=provenance-pillar
136
// uint8_t anchor_id[32]; // for example txid hash, receipt id hash
137
// uint64_t anchored_time;
138
// uint8_t reserved[16];
139
//} udil_anchor_ref;
140
//
141
//UDIL_EXPORT_API typedef struct udil_merkle_proof
142
//{
143
// uint8_t siblings[MAX_DEPTH][UDIL_HASHLEN];
144
// uint8_t directions[MAX_DEPTH];
145
// size_t depth;
146
//} udil_merkle_proof;
147
//
148
//UDIL_EXPORT_API typedef struct udil_envelope
149
//{
150
// uint16_t version;
151
// uint16_t msg_type;
152
// uint8_t sender_id[UDIL_HASHLEN];
153
// uint8_t receiver_id[UDIL_HASHLEN];
154
// uint8_t corr_id[16];
155
// uint64_t time;
156
// uint64_t valid_until;
157
//} udil_envelope;
158
//
159
//UDIL_EXPORT_API typedef struct udil_record_hdr
160
//{
161
// uint16_t version;
162
// uint16_t rtype;
163
// uint8_t ledger_id[UDIL_HASHLEN];
164
// uint32_t epoch;
165
// uint64_t seq;
166
// uint64_t time;
167
// uint8_t prev_hash[UDIL_HASHLEN];
168
// uint8_t env_hash[UDIL_HASHLEN];
169
// uint8_t pay_hash[UDIL_HASHLEN];
170
// uint8_t corr_id[16];
171
// uint32_t flags;
172
//} udil_record_hdr;
173
//
174
//UDIL_EXPORT_API typedef struct udil_checkpoint_body
175
//{
176
// uint16_t body_version;
177
// uint8_t ledger_id[UDIL_HASHLEN];
178
// uint32_t epoch;
179
// uint64_t start_seq;
180
// uint64_t end_seq;
181
// uint32_t record_count;
182
// uint8_t batch_root[UDIL_HASHLEN];
183
// uint8_t prev_checkpoint_commit[UDIL_HASHLEN];
184
// uint64_t created_time;
185
// uint32_t flags;
186
// uint8_t reserved[16];
187
//} udil_checkpoint_body;
188
//
189
//UDIL_EXPORT_API typedef struct udil_ledger_state
190
//{
191
// uint8_t ledger_id[UDIL_HASHLEN];
192
// uint32_t epoch;
193
// uint64_t head_seq;
194
// uint8_t head_hash[UDIL_HASHLEN];
195
// uint64_t last_checkpoint_end_seq;
196
// uint8_t last_checkpoint_commit[UDIL_HASHLEN];
197
// void* udif_signing_key;
198
// void* store;
199
//} udil_ledger_state;
200
//
201
//
202
//int32_t store_append(void* store, const uint8_t* bytes, size_t len);
203
//int32_t store_read_by_seq(void* store, uint64_t seq, uint8_t** out_bytes, size_t* out_len);
204
//int32_t store_read_range(void* store, uint64_t start_seq, uint64_t end_seq,
205
// uint8_t*** out_records, size_t** out_lens, size_t* out_count);
206
//int32_t store_get_head(void* store, uint64_t* out_head_seq, uint8_t out_head_hash[UDIL_HASHLEN]);
207
//int32_t store_set_head(void* store, uint64_t head_seq, const uint8_t head_hash[UDIL_HASHLEN]);
208
//int32_t store_find_last_checkpoint(void* store, uint8_t out_chk_commit[UDIL_HASHLEN], uint64_t* out_end_seq);
209
//
210
//
212
// * Detect equivocation between two checkpoints (same ledger/epoch, overlapping
213
// * range, different roots or commitments).
214
// *
215
// * Returns:
216
// * 1 if equivocation is detected, 0 otherwise.
217
// */
218
//UDIL_EXPORT_API int32_t udil_audit_detect_equivocation(const udil_checkpoint_body* a, const uint8_t a_commit[UDIL_HASHLEN],
219
// const udil_checkpoint_body* b, const uint8_t b_commit[UDIL_HASHLEN]);
220
//
222
// * \brief Verify that a record commitment is included in a checkpoint Merkle root (sample audit).
223
// *
224
// * This function is used by auditors and counterparties to validate that a given
225
// * record commitment was incorporated into a checkpointed batch without requiring
226
// * access to the full ledger or plaintext message content.
227
// *
228
// * The verifier recomputes the Merkle root from the provided record commitment
229
// * and Merkle proof, then compares it to the expected checkpoint root.
230
// *
231
// * \param checkpoint_root The expected 32-byte Merkle root committed by a checkpoint.
232
// * \param rec_commit The 32-byte record commitment being proven included.
233
// * \param proof The Merkle inclusion proof for rec_commit under checkpoint_root.
234
// *
235
// * \return 0 on success (proof verifies and matches checkpoint_root), otherwise a negative error code.
236
// */
237
//UDIL_EXPORT_API int32_t udil_audit_sample_inclusion(const uint8_t checkpoint_root[UDIL_HASHLEN], const uint8_t rec_commit[UDIL_HASHLEN], const udil_merkle_proof* proof);
238
//
239
// /**
240
// * Compute the checkpoint commitment from a checkpoint body.
241
// *
242
// * chk_commit = SHAKE256("UDIL/CHK" || SER(checkpoint_body), 32)
243
// *
244
// * out : [out] 32-byte checkpoint commitment.
245
// * body : [in] checkpoint body.
246
// */
247
//UDIL_EXPORT_API void udil_compute_checkpoint_commit(uint8_t out[UDIL_HASHLEN], const udil_checkpoint_body* body);
248
//
250
// * Compute the domain-separated envelope hash.
251
// *
252
// * The envelope hash commits to the canonical envelope bytes (message metadata).
253
// * This is used to prove message identity without storing full payload content.
254
// *
255
// * out : [out] 32-byte hash output.
256
// * env : [in] canonical envelope bytes.
257
// * envlen : [in] number of envelope bytes.
258
// */
259
//UDIL_EXPORT_API void udil_compute_env_hash(uint8_t out[UDIL_HASHLEN], const uint8_t* env, size_t envlen);
260
//
262
// * Compute the domain-separated payload hash.
263
// *
264
// * The payload hash commits to the payload bytes or ciphertext bytes (if encrypted).
265
// *
266
// * out : [out] 32-byte hash output.
267
// * pay : [in] payload bytes.
268
// * paylen : [in] number of payload bytes.
269
// */
270
//UDIL_EXPORT_API void udil_compute_payload_hash(uint8_t out[UDIL_HASHLEN], const uint8_t* pay, size_t paylen);
271
//
273
// * Compute the record commitment for a record header.
274
// *
275
// * rec_commit = SHAKE256("UDIL/REC" || SER(record_hdr), 32)
276
// *
277
// * out : [out] 32-byte record commitment.
278
// * hdr : [in] record header fields.
279
// */
280
//UDIL_EXPORT_API void udil_compute_record_commit(uint8_t out[UDIL_HASHLEN], const udil_record_hdr* hdr);
281
//
283
// * \brief Append an administrative reset record and transition the ledger to a new epoch.
284
// *
285
// * This function is used to record and justify a ledger reset event (for example,
286
// * storage corruption, disaster recovery, or operator-directed reinitialization)
287
// * while preserving audit continuity.
288
// *
289
// * A compliant implementation must:
290
// * - Append an ADMIN record containing the reset reason and sufficient metadata
291
// * to link the new epoch to the prior ledger state (for example, last checkpoint
292
// * commitment and/or head commitment).
293
// * - Increment the ledger epoch (or require the caller to do so explicitly, per spec).
294
// * - Ensure that future checkpoints chain from the last known checkpoint commitment,
295
// * preventing silent history deletion.
296
// *
297
// * \param st Ledger state object.
298
// * \param reset_reason UTF-8 or opaque bytes describing the reset reason.
299
// * \param reason_len Length of reset_reason in bytes.
300
// *
301
// * \return 0 on success, otherwise a negative error code.
302
// */
303
//int32_t udil_ledger_admin_reset(udil_ledger_state* st, const uint8_t* reset_reason, size_t reason_len);
304
//
306
// * \brief Append a new record to the local evidence ledger.
307
// *
308
// * This function appends a new ledger record of the specified type, binding it to:
309
// * - The current ledger head (via prev_hash),
310
// * - A monotonically increasing sequence number,
311
// * - Optional envelope and payload commitments,
312
// * - Optional correlation identifier,
313
// * - Optional record body bytes.
314
// *
315
// * The record commitment is computed over the canonical serialized header fields
316
// * and is then signed using the UDIF signing key carried in the ledger state.
317
// * The storage backend is append-only, and the ledger head is updated on success.
318
// *
319
// * The function does not interpret message semantics. It stores evidence artifacts.
320
// *
321
// * \param st Ledger state object.
322
// * \param rtype Record type (message, ack, receipt, admin, etc.).
323
// * \param env_hash Optional 32-byte envelope hash, may be NULL if unused by rtype.
324
// * \param pay_hash Optional 32-byte payload hash, may be NULL if unused by rtype.
325
// * \param corr_id Optional 16-byte correlation id, may be NULL if unused.
326
// * \param body Optional record body bytes (opaque), may be NULL.
327
// * \param body_len Length of body in bytes, may be 0.
328
// * \param out_rec_commit Optional 32-byte output buffer receiving the computed record commitment.
329
// *
330
// * \return 0 on success, otherwise a negative error code.
331
// */
332
//UDIL_EXPORT_API int32_t udil_ledger_append(udil_ledger_state* st, udil_record_type rtype, const uint8_t env_hash[UDIL_HASHLEN], const uint8_t pay_hash[UDIL_HASHLEN],
333
// const uint8_t corr_id[16], const uint8_t* body, size_t body_len, uint8_t* out_rec_commit);
334
//
336
// * \brief Append an external anchoring reference for a checkpoint commitment.
337
// *
338
// * This function records that a specific checkpoint commitment has been anchored
339
// * to an external witness system (for example, a regulator-operated anchor, a
340
// * consortium witness, or later a global provenance pillar).
341
// *
342
// * The anchor reference is evidence that a checkpoint existed at or before some
343
// * externally attested point in time. The anchor mechanism itself is out of scope
344
// * for the local ledger and is represented here only by an identifier (receipt id,
345
// * transaction id hash, or equivalent).
346
// *
347
// * \param st Ledger state object.
348
// * \param a Anchor reference structure containing checkpoint commitment and witness identifier.
349
// *
350
// * \return 0 on success, otherwise a negative error code.
351
// */
352
//UDIL_EXPORT_API int32_t udil_ledger_append_anchor_reference(udil_ledger_state* st, const udil_anchor_ref* a);
353
//
355
// * \brief Construct a checkpoint body for a contiguous record range.
356
// *
357
// * This function computes the Merkle root over the sequence of record commitments
358
// * for records in the inclusive range [start_seq, end_seq]. It then populates a
359
// * checkpoint body that binds:
360
// * - ledger_id and epoch,
361
// * - the sequence range,
362
// * - the record count,
363
// * - the computed batch root,
364
// * - the previous checkpoint commitment (for checkpoint chaining),
365
// * - the checkpoint creation time.
366
// *
367
// * This function builds the checkpoint body only. Signing and appending the
368
// * checkpoint is performed by udil_ledger_issue_checkpoint().
369
// *
370
// * \param st Ledger state object.
371
// * \param start_seq First record sequence number in the checkpoint batch (inclusive).
372
// * \param end_seq Last record sequence number in the checkpoint batch (inclusive).
373
// * \param out_body Output checkpoint body structure.
374
// *
375
// * \return 0 on success, otherwise a negative error code.
376
// */
377
//UDIL_EXPORT_API int32_t udil_ledger_build_checkpoint_body(udil_ledger_state* st, uint64_t start_seq, uint64_t end_seq, udil_checkpoint_body* out_body);
378
//
380
// * \brief Build a Merkle inclusion proof for a target record within a checkpoint range.
381
// *
382
// * This function produces an inclusion proof showing that the record at target_seq
383
// * is included in the Merkle root computed for the inclusive range [start_seq, end_seq].
384
// *
385
// * The proof contains sibling hashes and direction bits sufficient for an independent
386
// * verifier to recompute the Merkle root from out_rec_commit and the proof, and compare
387
// * it to out_root (or to a checkpoint’s batch_root).
388
// *
389
// * \param st Ledger state object.
390
// * \param start_seq First record sequence number in the proof batch (inclusive).
391
// * \param end_seq Last record sequence number in the proof batch (inclusive).
392
// * \param target_seq Sequence number of the record to prove included.
393
// * \param out_proof Output Merkle proof structure.
394
// * \param out_rec_commit Output 32-byte record commitment for target_seq.
395
// * \param out_root Output 32-byte Merkle root for [start_seq, end_seq].
396
// *
397
// * \return 0 on success, otherwise a negative error code.
398
// */
399
//UDIL_EXPORT_API int32_t udil_ledger_build_inclusion_proof(udil_ledger_state* st, uint64_t start_seq, uint64_t end_seq, uint64_t target_seq,
400
// udil_merkle_proof* out_proof, uint8_t out_rec_commit[UDIL_HASHLEN], uint8_t out_root[UDIL_HASHLEN]);
401
//
403
// * \brief Initialize a ledger state and load persistent head and checkpoint state from storage.
404
// *
405
// * This function initializes the in-memory ledger state with its fixed identity and
406
// * operational parameters, then synchronizes it with the persistent storage backend.
407
// *
408
// * A compliant implementation should:
409
// * - Set ledger_id and epoch.
410
// * - Associate the UDIF signing key used for signing new records and checkpoints.
411
// * - Associate the append-only storage backend.
412
// * - Load the current head sequence and head commitment from storage, or set a
413
// * genesis head if storage is empty.
414
// * - Load the last checkpoint commitment and its end sequence if available.
415
// *
416
// * \param st Ledger state object to initialize.
417
// * \param ledger_id Stable 32-byte identifier for this ledger instance.
418
// * \param epoch Epoch number (incremented on reset or signing-key rollover).
419
// * \param udif_signing_key Opaque handle to the UDIF signing key for this ledger.
420
// * \param store Opaque handle to the storage backend.
421
// *
422
// * \return 0 on success, otherwise a negative error code.
423
// */
424
//UDIL_EXPORT_API int32_t udil_ledger_initialize(udil_ledger_state* st, const uint8_t ledger_id[UDIL_HASHLEN], uint32_t epoch, void* udif_signing_key, void* store);
425
//
427
// * \brief Issue, sign, and append a checkpoint record to the ledger.
428
// *
429
// * This function creates a checkpoint for records in the inclusive range
430
// * [start_seq, end_seq] and appends it as a checkpoint record to the ledger.
431
// *
432
// * A compliant implementation must:
433
// * - Build the checkpoint body (udil_ledger_build_checkpoint_body()).
434
// * - Compute the checkpoint commitment over the canonical body.
435
// * - Sign the checkpoint commitment using the ledger’s UDIF signing key.
436
// * - Append a CHECKPOINT record that contains the body and checkpoint signature.
437
// * - Update the ledger state’s last checkpoint tracking values.
438
// *
439
// * The returned out_chk_commit is intended for external anchoring and for
440
// * audit exchange.
441
// *
442
// * \param st Ledger state object.
443
// * \param start_seq First record sequence number in the checkpoint batch (inclusive).
444
// * \param end_seq Last record sequence number in the checkpoint batch (inclusive).
445
// * \param out_chk_commit Output 32-byte checkpoint commitment.
446
// *
447
// * \return 0 on success, otherwise a negative error code.
448
// */
449
//UDIL_EXPORT_API int32_t udil_ledger_issue_checkpoint(udil_ledger_state* st, uint64_t start_seq, uint64_t end_seq, uint8_t out_chk_commit[UDIL_HASHLEN]);
450
//
452
// * \brief Parse a stored record blob into header, body, and signature components.
453
// *
454
// * This function decodes the record container format produced by udil_ledger_append()
455
// * and returns:
456
// * - the committed header fields,
457
// * - the optional opaque body bytes,
458
// * - the signature bytes.
459
// *
460
// * The caller owns the returned out_body and out_sig buffers and must free them
461
// * using the allocator compatible with the implementation.
462
// *
463
// * This function does not verify signatures. Use udil_ledger_verify_record_blob()
464
// * for verification.
465
// *
466
// * \param blob Raw stored record blob bytes.
467
// * \param blob_len Length of blob in bytes.
468
// * \param out_hdr Output parsed record header.
469
// * \param out_body Output pointer to allocated body bytes (may be NULL if no body).
470
// * \param out_body_len Output body length (0 if no body).
471
// * \param out_sig Output pointer to allocated signature bytes.
472
// * \param out_sig_len Output signature length.
473
// *
474
// * \return 0 on success, otherwise a negative error code.
475
// */
476
//UDIL_EXPORT_API int32_t udil_ledger_parse_record(const uint8_t* blob, size_t blob_len, udil_record_hdr* out_hdr, uint8_t** out_body,
477
// size_t* out_body_len, uint8_t** out_sig, size_t* out_sig_len);
478
//
480
// * \brief Rotate the UDIF signing key used by the ledger and transition to a new epoch.
481
// *
482
// * This function updates the ledger’s signing key to a new UDIF key and increments
483
// * the epoch to explicitly mark the key transition in the evidentiary record.
484
// *
485
// * A compliant implementation should:
486
// * - Update st->udif_signing_key to new_udif_signing_key.
487
// * - Increment st->epoch.
488
// * - Preserve continuity by issuing a checkpoint over any uncheckpointed records
489
// * prior to completing the rollover (policy dependent, but recommended).
490
// *
491
// * \param st Ledger state object.
492
// * \param new_udif_signing_key Opaque handle to the new UDIF signing key.
493
// *
494
// * \return 0 on success, otherwise a negative error code.
495
// */
496
//UDIL_EXPORT_API int32_t udil_ledger_rotate_key(udil_ledger_state* st, void* new_udif_signing_key);
497
//
499
// * \brief Verify a stored record blob signature and recompute its record commitment.
500
// *
501
// * This function parses the record blob, recomputes the record commitment from the
502
// * committed header fields, and verifies that the signature over the record commitment
503
// * is valid under the supplied signer certificate.
504
// *
505
// * The output record commitment can be used as an input leaf to checkpoint Merkle trees
506
// * and as an evidentiary identifier for the record.
507
// *
508
// * \param blob Raw stored record blob bytes.
509
// * \param blob_len Length of blob in bytes.
510
// * \param signer_cert The signer’s UDIF certificate bytes used for verification.
511
// * \param cert_len Length of signer_cert in bytes.
512
// * \param out_rec_commit Output 32-byte record commitment.
513
// *
514
// * \return 0 on success (signature valid), otherwise a negative error code.
515
// */
516
//UDIL_EXPORT_API int32_t udil_ledger_verify_record_blob(const uint8_t* blob, size_t blob_len, const uint8_t* signer_cert, size_t cert_len, uint8_t out_rec_commit[UDIL_HASHLEN]);
517
//
519
// * Compute the Merkle leaf node hash from a record commitment.
520
// *
521
// * leaf = SHAKE256("UDIL/LEAF" || rec_commit, 32)
522
// *
523
// * out : [out] 32-byte leaf hash.
524
// * rec_commit : [in] 32-byte record commitment.
525
// */
526
//UDIL_EXPORT_API void udil_merkle_leaf(uint8_t out[UDIL_HASHLEN], const uint8_t rec_commit[UDIL_HASHLEN]);
527
//
529
// * Compute the Merkle parent node hash.
530
// *
531
// * parent = SHAKE256("UDIL/NODE" || left || right, 32)
532
// *
533
// * out : [out] 32-byte parent hash.
534
// * left : [in] 32-byte left child.
535
// * right : [in] 32-byte right child.
536
// */
537
//UDIL_EXPORT_API void udil_merkle_parent(uint8_t out[UDIL_HASHLEN], const uint8_t left[UDIL_HASHLEN], const uint8_t right[UDIL_HASHLEN]);
538
//
540
// * Verify a Merkle inclusion proof and recompute the root.
541
// *
542
// * out_root : [out] computed Merkle root from the proof.
543
// * rec_commit : [in] record commitment being proven.
544
// * proof : [in] inclusion proof (siblings + directions).
545
// */
546
//UDIL_EXPORT_API void udil_merkle_verify(uint8_t out_root[UDIL_HASHLEN], const uint8_t rec_commit[UDIL_HASHLEN], const udil_merkle_proof* proof);
547
//
549
// * \brief Compute the Merkle root over a contiguous set of record commitments.
550
// *
551
// * This function computes a deterministic Merkle root using the UDIL Merkle
552
// * construction rules:
553
// * - Each record commitment is first transformed into a Merkle leaf.
554
// * - Parent nodes are computed pairwise from left and right children.
555
// * - If a level has an odd number of nodes, the final node is duplicated.
556
// *
557
// * The resulting root is suitable for inclusion in a checkpoint body and
558
// * for later audit verification using Merkle inclusion proofs.
559
// *
560
// * \param root Output buffer receiving the computed Merkle root.
561
// * \param rec_commits Pointer to a flat array of record commitments
562
// * (count * UDIL_HASHLEN bytes).
563
// * \param count Number of record commitments in the array.
564
// */
565
//UDIL_EXPORT_API void udil_merkle_root(uint8_t root[UDIL_HASHLEN], const uint8_t* rec_commits, size_t count);
566
//
568
// * \brief Serialize an anchor reference into canonical byte form.
569
// *
570
// * This function serializes an \c udil_anchor_ref structure into its canonical
571
// * binary representation. The serialized output is suitable for inclusion as
572
// * the body of an ANCHOR_REFERENCE ledger record.
573
// *
574
// * The caller owns the returned buffer and must free it using the allocator
575
// * compatible with the implementation.
576
// *
577
// * \param a Anchor reference structure to serialize.
578
// * \param out_len Output parameter receiving the serialized length in bytes.
579
// *
580
// * \return Pointer to a newly allocated buffer containing the serialized
581
// * anchor reference, or NULL on failure.
582
// */
583
//UDIL_EXPORT_API uint8_t* udil_serialize_anchor_reference(const udil_anchor_ref* a, size_t* out_len);
584
//
586
// * \brief Serialize a checkpoint body into canonical byte form.
587
// *
588
// * This function serializes an \c udil_checkpoint_body structure into the exact
589
// * canonical format used for computing checkpoint commitments and signatures.
590
// * The serialization includes all committed fields in fixed order and
591
// * big-endian encoding for multi-byte integers.
592
// *
593
// * The returned buffer is used as input to the checkpoint commitment hash
594
// * function.
595
// *
596
// * The caller owns the returned buffer and must free it when no longer needed.
597
// *
598
// * \param c Checkpoint body structure to serialize.
599
// * \param out_len Output parameter receiving the serialized length in bytes.
600
// *
601
// * \return Pointer to a newly allocated buffer containing the serialized
602
// * checkpoint body, or NULL on failure.
603
// */
604
//UDIL_EXPORT_API uint8_t* udil_serialize_checkpoint_body(const udil_checkpoint_body* c, size_t* out_len);
605
//
607
// * \brief Serialize a record header into canonical byte form.
608
// *
609
// * This function serializes the committed fields of an \c udil_record_hdr into
610
// * a canonical binary representation. The output is used exclusively for
611
// * computing the record commitment hash.
612
// *
613
// * Signature bytes, variable-length bodies, and container framing are not
614
// * included in this serialization.
615
// *
616
// * The caller owns the returned buffer and must free it when finished.
617
// *
618
// * \param h Record header structure to serialize.
619
// * \param out_len Output parameter receiving the serialized length in bytes.
620
// *
621
// * \return Pointer to a newly allocated buffer containing the serialized
622
// * record header, or NULL on failure.
623
// */
624
//UDIL_EXPORT_API uint8_t* udil_serialize_record_header(const udil_record_hdr* h, size_t* out_len);
625
//
627
// * \brief Sign a checkpoint commitment using a UDIF signing key.
628
// *
629
// * This function produces a cryptographic signature over a checkpoint
630
// * commitment. The commitment must already have been computed from a canonical
631
// * checkpoint body.
632
// *
633
// * The signature binds the issuing authority, the checkpoint content, and the
634
// * signing context, providing non-repudiable evidence that the checkpoint was
635
// * issued by the holder of the UDIF key.
636
// *
637
// * \param out_sig Output buffer receiving the signature bytes.
638
// * \param out_siglen Output parameter receiving the signature length in bytes.
639
// * \param udif_key Opaque handle to the UDIF signing key.
640
// * \param chk_commit 32-byte checkpoint commitment to be signed.
641
// */
642
//UDIL_EXPORT_API void udil_sign_checkpoint(uint8_t* out_sig, size_t* out_siglen, void* udif_key, const uint8_t chk_commit[UDIL_HASHLEN]);
643
//
645
// * \brief Sign a record commitment using a UDIF signing key.
646
// *
647
// * This function produces a cryptographic signature over a record commitment.
648
// * The record commitment must already have been computed from the canonical
649
// * record header serialization.
650
// *
651
// * The resulting signature provides non-repudiation for the existence and
652
// * ordering of the record within the ledger.
653
// *
654
// * \param out_sig Output buffer receiving the signature bytes.
655
// * \param out_siglen Output parameter receiving the signature length in bytes.
656
// * \param udif_key Opaque handle to the UDIF signing key.
657
// * \param rec_commit 32-byte record commitment to be signed.
658
// */
659
//UDIL_EXPORT_API void udil_sign_record(uint8_t out_sig[], size_t* out_siglen, void* udif_key, const uint8_t rec_commit[UDIL_HASHLEN]);
660
//
662
// * \brief Verify a checkpoint signature against a checkpoint commitment.
663
// *
664
// * This function verifies that a provided signature is a valid signature over
665
// * the given checkpoint commitment under the supplied UDIF certificate.
666
// *
667
// * This verification step is required for:
668
// * - Audit acceptance of a checkpoint.
669
// * - Detection of forged or unauthorized checkpoints.
670
// * - Establishing evidentiary validity of ledger checkpoints.
671
// *
672
// * \param cert UDIF certificate bytes of the purported signer.
673
// * \param cert_len Length of the certificate in bytes.
674
// * \param chk_commit 32-byte checkpoint commitment that was signed.
675
// * \param sig Signature bytes to verify.
676
// * \param siglen Length of the signature in bytes.
677
// *
678
// * \return 0 if the signature is valid, otherwise a negative error code.
679
// */
680
//int32_t udil_verify_checkpoint_signature(const uint8_t* cert, size_t cert_len, const uint8_t chk_commit[UDIL_HASHLEN], const uint8_t* sig, size_t siglen);
681
//
683
// * \brief Verify a record signature against a record commitment.
684
// *
685
// * This function verifies that a provided signature is a valid signature over
686
// * the given record commitment under the supplied UDIF certificate.
687
// *
688
// * Successful verification proves that the record was authorized by the
689
// * certificate holder and that the committed record header has not been
690
// * altered.
691
// *
692
// * \param cert UDIF certificate bytes of the purported signer.
693
// * \param cert_len Length of the certificate in bytes.
694
// * \param rec_commit 32-byte record commitment that was signed.
695
// * \param sig Signature bytes to verify.
696
// * \param siglen Length of the signature in bytes.
697
// *
698
// * \return 0 if the signature is valid, otherwise a negative error code.
699
// */
700
//UDIL_EXPORT_API int32_t udil_verify_record_signature(const uint8_t* cert, size_t cert_len, const uint8_t rec_commit[UDIL_HASHLEN], const uint8_t* sig, size_t siglen);
701
//
703
// * Simple UDIL Ledger Smoke Test
704
// *
705
// * This function performs a minimal end to end validation of the ledger:
706
// * - initialize ledger
707
// * - append a record
708
// * - read the record back
709
// * - recompute and verify the record commitment and signature
710
// *
711
// * This is intended as a basic sanity test, not a full audit test.
712
// * It assumes that the storage backend and UDIF sign/verify primitives
713
// * are already wired and functional.
714
// */
715
//UDIL_EXPORT_API int32_t udil_ledger_basic_selftest(udil_ledger_state* st, const uint8_t ledger_id[UDIL_HASHLEN], void* udif_signing_key, void* store, const uint8_t* signer_cert, size_t cert_len);
716
//
717
//UDIL_EXPORT_API bool udil_ledger_selftest();
718
719
#endif
MCEL
Saved
udil.h
Generated by
1.14.0