Internet-Draft KSG-Journal-Export October 2026
Nam Expires 15 April 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-nam-ksg-journal-export-01
Published:
Intended Status:
Informational
Expires:
Author:
Y. Nam
Keysingate

Keysingate Journal Export: Pages under a Portable Seal

Abstract

A Keysingate container keeps a work journal: pages without signatures, closed by one portable seal that covers every page before it and is moved forward by each new record. This document specifies the journal's pages, records and seals, the two forms of a journal (unanchored and anchored), the two exports a third party receives -- one page with its proof, or the whole journal once -- and how a verifier checks them without contacting anyone. It also specifies a profile for anchoring seals in Solana with a blind memo that shows outsiders only the fact of a write. The core documents, time format and anchor rule it relies on are those of draft-nam-ksg-core-00.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 15 April 2027.

▲

Table of Contents

1. Introduction

A page carries no signature; a record of up to 99 content pages and a service page is closed by one seal; the seal covers the whole chain of pages up to it; an anchor gives a record its time bound and its force. One verifier procedure reads both exports.

The container itself -- how it is built, who presses what, how its keys are held -- is not specified here. A verifier sees only pages, seals and anchors.

2. Conventions and Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The canonical form, document hash, signatures, time, limits and the Bound Rule are those of [KSG-CORE]. All documents here carry "@context": "urn:keysingate:core:v3" and "v": 3; v is the journal format's version, which today equals the core's and may move separately.

Page:
Room for content, up to 2 048 bytes; no signature.
Record:
The unit of writing: content pages and, when there is more than one page, a service page; one time mark; one seal.
Seal:
A signed statement that closes a record and covers all pages before it.
Agent, owner:
The two parties of a journal, each known by keys pinned in the journal itself.

3. Layout

A journal has 1 + 1000 + 100 + 2 places: page 0 (the opening); 1 000 working pages; 100 pages of the transfer zone (changes of owner); 2 coupling pages. All zones form one chain of pages in the order of writing.

4. Pages

{ "@context": "urn:keysingate:core:v3", "type": "BoundPage", "v": 3,
  "seq": 7, "zone": "work", "slot": 7,
  "batch": { "id": 3, "index": 0, "of": 2 },
  "offset_ms": 86400000, "body": { ... }, "prev": "1220..." }

The page hash is the core document hash of the page.

4.1. Bodies

Table 1
Body Content
opening container, mode (the form the journal opens in), agent and owner as {id, keys} -- pins both parties' keys
content kind (work, artifact_or_rights, shares_declared_lost, hash_binding), content (inline base64url bytes or digest), optional content_type URI
manifest the service page of a multi-page record; always its last page
transfer a hand-off between agents (work zone) or a change of owner (transfer zone)
coupling one of the two coupling places
rule the rule of two seals, set or lifted
form to: the form after this page
repeat_confirmation the journal's confirmation of ten identical records

All hashes are SHA-256 [FIPS180-4]. A content piece commits as SHA-256("ksg:bound:inline:v1" || bytes) or SHA-256("ksg:bound:digest:v1" || digest) -- plain concatenation, the label being fixed. A record's hash is SHA-256(F("ksg:bound:record:v1") || F(c1) || ... || F(cn)) over the commitments of its pieces in order, with F (length-prefixed field) as in [KSG-CORE]. A record is at most 99 content pages and 204 800 bytes.

5. Seals

{ "@context": "urn:keysingate:core:v3",
  "type": "JournalSeal", "v": 3,
  "container": "1220...", "number": 8, "batch": 3,
  "head": "1220...", "root": "1220...",
  "counts": { "work": 7, "transfer": 0, "coupling": 0 },
  "agent": "did:example:agent", "owner": "did:example:owner",
  "mode": "pro", "prev": "1220...", "offset_ms": 86400000,
  "signatures": [ ... ] }

Every seal covers the whole chain before it, so a later seal confirms the pages of every earlier record.

5.1. Further Seals

  • Transfer seal (TransferSeal: page, subject, signatures): a hand-off is sealed by both agents; a change of owner by agent and owner on both sides. Never removed. The new agent replaces the old one; the old one seals nothing afterwards.
  • Co-seal (CoSeal: batch, subject, signatures): the owner's second seal on a record. Required in the anchored form for artifact_or_rights, and for every record while the rule of two seals is in force; a record that needs it waits, and nothing else is written meanwhile.
  • Coupling: each of the two places is written once; place 2 names the coupled container and its last seal.

6. Forms

Table 2
Form Anchors
local none; a seal MUST NOT be anchored
pro every seal MUST be anchored

The form changes only by a form page sealed by the owner as well, in either direction, as long as pages last. Going to pro, the seal of that page is the first anchored one; an anchor made before the owner's seal on the change MUST be rejected. Without the owner, a journal stays local.

Force. A record has force when its seal is anchored. Two records' link is confirmed when both are anchored and no unanchored record lies between them. A report names the runs of consecutive anchored records.

7. Exports

7.1. Final Export

The whole journal, once; the container works no more after it.

{ "@context": "urn:keysingate:core:v3", "type": "BoundJournalExport",
  "pages": [ ... ], "seal": { ... },
  "anchors": [ { "batch": 3, "anchor": { ... } } ],
  "transfers": [ ... ], "coseals": [ ... ] }

Empty arrays are omitted.

7.2. Pointwise Export

One page with its inclusion proof [RFC6962] under the current seal and, in the anchored form, the seal's anchor:

{ "@context": "urn:keysingate:core:v3",
  "page": { ... }, "proof": { ... },
  "seal": { ... }, "anchor": { ... } }

One pointwise export carries 1 to 24 distinct pages, each in the form above and each verified on its own. The container limits how many pointwise exports a journal gives -- 12 unless the container's class sets another; the count is kept by the container and is not checked by a verifier.

8. Verification

Input: the export, the container identifier, the class (or the channel it derives from, [KSG-CORE]), the agent's keys from the verifier's own source, a profile, network readers.

Final export. The verifier replays the journal from page 0 by the same rules that wrote it:

  1. limits, then strict parsing of every document;
  2. page 0 is the opening, prev is the container identifier, its pinned agent keys equal the ones the verifier holds, its form agrees with the class;
  3. every page links to the previous one; zones, slots and records are in place; every record's pages and service page agree;
  4. every seal is recomputed from the pages (number, head, root, counts, parties, form, rule, prev) and its signatures verified under the pinned keys; transfer seals and co-seals where the rules require them;
  5. in pro, every seal has an anchor, read by the Bound Rule; in local, no anchor is accepted;
  6. the report: number of pages, the current agent and owner, the form, transfers, co-sealed records, each record with its seal and whether it is anchored, the anchored runs with their bounds, and an explicit list of what is not established.

Pointwise export. The page's hash is included under the seal's root at seq; the seal's signatures verify under the agent keys the verifier holds; in pro, the anchor is read by the Bound Rule. A pointwise export proves the page and its time bound; it does not prove the pages around it.

9. Relation to SCITT

The SCITT architecture [RFC9943] defines Signed Statements about Artifacts, registered in a Transparency Service that returns Receipts: signed proofs that a Signed Statement is included in a Verifiable Data Structure [RFC9942]. Both designs let a Relying Party verify evidence offline, without the party that holds it. They differ in where the evidence lives and in encoding.

Table 3
SCITT This document Difference
Signed Statement Seal over a record SCITT: COSE_Sign1 over CBOR. Here: JSON, JCS, detached signature array; the seal covers every page before it
Statement (opaque, possibly encrypted) Page content (inline or digest) A digest page is the analogue of an opaque Statement
Transparency Service Journal in the container plus an anchoring network SCITT: a service holds the sequence. Here: the holder's container holds the journal; the network holds only blind anchors
Registration Policy Journal rules before a record is sealed Out of scope here
Receipt Anchor of a seal SCITT: inclusion proof in the service's structure. Here: an anchor read by a profile under the Bound Rule
Inclusion proof Pointwise export Both: an RFC 6962 style path to a signed tree head (here the seal's root)
Append-only Log Page chain from page 0, seals linked by prev Order and completeness proven by the final export
Relying Party, Auditor Verifier Same role

Terminology. In SCITT, "Receipt" is a proof of registration in a Transparency Service. This document has no object of that name; the nearest counterpart of a Receipt is the anchor of a seal.

Composition. A seal can be carried as the payload of a SCITT Signed Statement and registered in a Transparency Service; the resulting Receipt is then one more kind of anchor for that seal. The encoding of such a Signed Statement and the matching anchoring profile are left to a separate document.

10. Solana Seal Profile

A seal is anchored as the memo of an ordinary Solana transaction (the SPL Memo program [SPL-MEMO]). The anchor's type is urn:ksg:anchor:solana:seal:v1; its proof names the transaction signature, slot and cluster. The memo is blind and of fixed length:

ksg:bs:v1 <link> <commit>
link   = PRF(K, "ksg:bs:link:v1"   || prev)
commit = PRF(K, "ksg:bs:commit:v1" || seal)
PRF(K, x) = HKDF-SHA256(salt = "ksg:bs:v1", IKM = K, info = x),
            16 bytes, lowercase hex

HKDF-SHA256 is HKDF [RFC5869] with SHA-256.

seal is the seal's hash (32 bytes); prev is the seal's own prev -- the previous seal's hash, whether or not that seal was anchored -- or the container identifier for the opening's seal, which has no prev.

Scan key. K is the holder's scan key for the calendar month (UTC) in which the seal was made:

K(YYYY-MM) = HKDF-SHA256(salt = "ksg:bs:v1", IKM = master,
             info = "ksg:bs:period:v1" || len64(label) || label)

with len64 the label's length as 8 bytes big-endian. A key handed out reads its month's seals and no other's. Scan keys are not part of any export or of this document's public material: the holder gives one to a verifier together with an export. Without it, an observer sees that a memo exists and nothing else.

Reader. The reader recomputes the memo from the seal and the key and finds it in the named transaction; a different memo is a rejection. It asks the node for its genesis hash and accepts only the cluster the verifier named. The moment it returns is the block time -- a stake-weighted estimate at one-second grain -- and it says so. A fork (two memos with one link and different commit) is visible only to a holder of the key.

Status records of [KSG-CORE] are anchored with an open memo, because the status section is the part of a container that is meant to be read:

ksg:st:v1 <link> <commit>
link   = SHA-256("ksg:st:link:v1"   || prev)
commit = SHA-256("ksg:st:commit:v1" || record hash)

prev is the record's own prev; both values are written as multihashes.

anchor type urn:ksg:anchor:solana:status:v1.

11. Security Considerations

Signatures. Every seal carries Ed25519; a verifier MUST require it. Keys come from the journal's own pinned pages and the verifier's source, never from the presenter. The post-quantum signature (ML-DSA-65 [FIPS204]) is on the stored container as a whole, not on each seal: an export, once it has left the container, is protected by its recipient. Against a future forger able to break Ed25519, an anchored seal is held by its anchor: a page that differs from the anchored one does not hash to the anchored value.

Time. Only an anchor read by the Bound Rule gives a bound; offset_ms and anchor statements are not evidence. In the local form a journal proves authorship and order, not time.

Replay. A verifier replays the journal by the rules that wrote it; a journal accepted by a verifier is one the writing rules would have produced.

Blind anchors. The blind memo hides the chain from outsiders and with it the visibility of forks: a fork is found only by someone holding the key. The paying account remains visible and groups its memos.

12. Privacy Considerations

Pages may carry a digest instead of content, so an export can prove a record without revealing it. The blind memo keeps a journal's existence and pace from becoming a public time series; status memos are open by design.

13. IANA Considerations

This document has no IANA actions. The anchor types urn:ksg:anchor:solana:seal:v1 and urn:ksg:anchor:solana:status:v1 and the memo tags ksg:bs:v1 and ksg:st:v1 are opaque, byte-compared strings; no URN namespace is registered by this document.

14. Normative References

[FIPS180-4]
National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, , <https://doi.org/10.6028/NIST.FIPS.180-4>.
[KSG-CORE]
Nam, Y., "Keysingate Core: Channel Documents, Status Records and Anchored Time", Work in Progress, Internet-Draft, draft-nam-ksg-core-00, , <https://datatracker.ietf.org/doc/draft-nam-ksg-core/>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC5869]
Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, , <https://www.rfc-editor.org/info/rfc5869>.
[RFC6962]
Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, , <https://www.rfc-editor.org/info/rfc6962>.
[RFC8032]
Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, , <https://www.rfc-editor.org/info/rfc8032>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, , <https://www.rfc-editor.org/info/rfc8174>.

15. Informative References

[FIPS204]
National Institute of Standards and Technology, "Module-Lattice-Based Digital Signature Standard", FIPS PUB 204, , <https://doi.org/10.6028/NIST.FIPS.204>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", RFC 7942, DOI 10.17487/RFC7942, , <https://www.rfc-editor.org/info/rfc7942>.
[RFC9942]
Steele, O., Birkholz, H., Delignat-Lavaud, A., and C. Fournet, "CBOR Object Signing and Encryption (COSE) Receipts", RFC 9942, DOI 10.17487/RFC9942, , <https://www.rfc-editor.org/info/rfc9942>.
[RFC9943]
Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande, Y., and S. Lasker, "An Architecture for Trustworthy and Transparent Digital Supply Chains", RFC 9943, DOI 10.17487/RFC9943, , <https://www.rfc-editor.org/info/rfc9943>.
[SPL-MEMO]
Solana Labs, "Memo Program", <https://spl.solana.com/memo>.

Appendix A. Implementation Status

Per [RFC7942]. ksg-core-v2 (Rust) writes and verifies the journal; ksg-verify-v2 verifies both exports and reads seal and status anchors from Solana. The workspace has over 750 tests; the test vectors are regenerated and compared byte for byte by the reference build.

Author's Address

Yevhenii Nam
Keysingate