qub protokollspecifikáció

A qub egy kriptográfiai időbeli kötelezettségvállalási protokoll: szavakat zár egy jövőbeli dátumhoz, majd ellenőrizhetővé teszi, hogy pontosan mit pecsételtek le, melyik drand-kör kapuzta a felszabadítását, továbbá — ha tárolási tranzakció vagy átláthatósági napló bizonyítéka rendelkezésre áll — azt a függetlenül időbélyegzett felső korlátot, ameddig a titkosított szöveget már rögzítették.

Három alapelem teszi mindezt lehetővé. A drand decentralizált véletlenszerűségi jeladó — a felfedési dátumot kriptográfia érvényesíti, nem a qub jóindulata. A tartós tárolás és egy csak hozzáfűzhető átláthatósági napló megőrzi a lepecsételt bájtokat, és a kötegelt kötelezettségvállalásokat állandó nyilvános tárolóhoz horgonyozza; a fizetős T3 útvonal emellett egyedi állandó-tárolási tranzakciót is ír. Az ML-DSA-65 posztkvantum digitális aláírás — amikor a szerzőség engedélyezett, a qub egy olyan kulcspárhoz kötődik, amelynek titka sosem hagyja el a szerző eszközét.

Együttesen ezek az alapelemek időzárolt és hamisítás-érzékeny, opcionálisan tulajdonítható és függetlenül időbélyegezhető kijelentést hoznak létre — egy nyugtát, amelynek értéke azzal nő, ahogy a világ képessége a múlt meghamisítására fejlődik.

A dokumentum hátralévő része az interoperábilis megvalósításokhoz szükséges normatív specifikáció.


qub protokoll-specifikáció

Mező Érték
Dokumentumkiadás 1.0.0 (protocol-v1.0.0)
Wire-protokoll 0x01
Külső burkoló 0x01
Hatálybalépés dátuma 2026-09-23
Állapot Aktuális
Átnézve eddig 2026-09-23

Ez a dokumentum a qub időzített kötelezettségvállalási rendszer normatív protokoll-specifikációja. Meghatározza az interoperábilis megvalósításokhoz szükséges adatstruktúrákat, szerializációs szabályokat, levezetési képleteket és ellenőrzési eljárásokat.

Hatókör: a protokollréteg szándékosan nyelvfüggetlen — a qub törzse átlátszatlan egyszerű szöveg / markdown / paktum-bájtok, és a területi beállításnak megfelelő megjelenítés a megjelenítő felelőssége (qub.social webalkalmazás, <qub-embed> iframe, MCP-kliensek stb.).


1. Jelölés és konvenciók

Jelölés Jelentés
u8, u64, i64 Megadott bitszélességű előjel nélküli/előjeles egészek
[u8; N] N bájt fix hosszúságú bájttömb
Vec<u8> Változó hosszúságú bájttömb
Option<T> T típusú érték, vagy hiányzó
String UTF-8 szöveges karakterlánc, NFC-normalizált
`
SHA3-256(x) Az x bájtsorozat NIST SHA3-256 kivonata (FIPS 202)
ceil(x) Felső egészrész függvény: a legkisebb egész ≥ x
CBOR Concise Binary Object Representation (RFC 8949)
big-endian A legjelentősebb bájt elöl

A bemeneti képek (preimage) konstrukcióiban minden egész szám big-endian fix szélességű bájttömbként van kódolva (i64 → 8 bájt, u8 → 1 bájt), hacsak másként nincs megadva.

Minden időbélyeg Unix másodperc UTC-ben.


2. Adatstruktúrák

2.1 ComposeQub (alkotó memóriában lévő állapota)

Nem szerializálódik CBOR-ba. Nem íródik állandó tárhelyre. Az alkotó alkalmazásához helyi.

ComposeQub {
    draft_id:       [u8; 16],        // Random, generated locally
    created_at:     i64,             // Unix seconds UTC
    unlock_at:      Option<i64>,     // Unix seconds UTC; None while composing
    visibility:     u8,              // 0x00 = private; 0x01 = public
    content_type:   u8,              // 0x01 text; 0x03 pact; 0x04 verdict
    plaintext:      Vec<u8>,         // Raw body bytes (UTF-8 for text)
    sender_label:   Option<String>,  // Display name; V2-signed when authorship is enabled
    title:          Option<String>,  // Plaintext countdown title; bound via title_hash
    reply_to:       Option<[u8; 32]>,// Parent qub_id; V2-signed when authorship is enabled
    outcome_at:     Option<i64>,     // Optional future judgment time; bound to qub_id
    status:         DraftStatus,     // Composing | Sealed | Uploaded | Failed
}

2.2 QubEnvelope (visszafejtett hasznos adat)

Kanonikus CBOR-ral szerializálva (§3). A SealedQub belsejében titkosítva. Ez a struktúra bizonyítja a tartalom integritását a visszafejtés után.

QubEnvelope {
    version:             u8,              // Protocol major version (0x01 for v1)
    qub_id:              [u8; 32],        // Derived (see §4.1)
    content_type:        u8,              // Content type registry (see §6)
    created_at:          i64,             // Unix seconds UTC
    unlock_at:           i64,             // Unix seconds UTC
    outcome_at:          Option<i64>,     // When reality renders judgment; bound to qub_id
    sender_label:        Option<String>,  // Not in qub_id; V2-signed when authorship is enabled
    reply_to:            Option<[u8; 32]>,// Parent qub_id; not in qub_id; V2-signed when present
    body:                Vec<u8>,         // UTF-8 text or canonical CBOR pact/verdict body
    body_hash:           [u8; 32],        // SHA3-256(body) (see §4.2)
    sig_alg:             u8,              // Signature algorithm (see §9.2)
    author_signature:    Option<Vec<u8>>, // Set when sig_alg != 0x00
    author_pubkey:       Option<Vec<u8>>, // Set when sig_alg != 0x00
    cosigner_pubkey:     Option<Vec<u8>>, // Set for cosigned pact bilateral agreements
    cosigner_signature:  Option<Vec<u8>>, // Set for cosigned pact bilateral agreements
}

Alapeset (aláíratlan szöveges qub): version = 0x01, content_type = 0x01, sig_alg = 0x00; az aláírási és társaláíró mezők hiányoznak. Más opcionális metaadatmezők jelen lehetnek.

Egyéb v1 konfigurációk: content_type = 0x03 (paktum-törzs, lásd §6.1); sig_alg = 0x01 (ML-DSA-65) jelen lévő author_signature és author_pubkey mezőkkel (lásd §9.3); cosigner_pubkey és cosigner_signature együttesen jelen van a társaláírt paktumoknál (lásd §9.7); reply_to a szülő qub qub_id értékére állítva a válaszlánc-qubokhoz (az aláírás-hatókör következményeiért lásd §9.3).

2.3 SealedQub (kanonikus wire-formátum)

Kanonikus CBOR-ral szerializálva (§3). Ez a belső wire-műtermék: nyilvános kézbesítéskor ezek a bájtok csupaszon kerülnek tárolásra, míg privát kézbesítéskor tárolás előtt OuterWrapper burkolatba kerülnek (§13).

SealedQub {
    version:           u8,              // Protocol major version (0x01 for v1)
    qub_id:            [u8; 32],        // Same as QubEnvelope.qub_id
    visibility:        u8,              // 0x00 = private/wrapped; 0x01 = public/bare
    unlock_at:         i64,             // Unix seconds UTC
    outcome_at:        Option<i64>,     // Surfaced on the verdict-watch CTA
                                        //   before reveal; mirrors QubEnvelope.outcome_at;
                                        //   bound to qub_id via the §4.1 preimage.
    drand_chain_id:    String,          // drand chain hash (hex string)
    drand_round:       u64,             // Target drand round number
    drand_chain_version: Option<u8>,    // W3 — chain-migration version. Absent / 0 = quicknet
                                        //   (the only chain today). Lets a future chain swap
                                        //   be expressed on the wire without a breaking format
                                        //   change. NOT part of the §4.1 qub_id preimage, so its
                                        //   addition never alters an existing qub's identity.
    tlock_ciphertext:  Vec<u8>,         // tlock-encrypted QubEnvelope CBOR bytes
    recipient_pubkey:  Option<[u8; 32]>,// Reserved field; accepted by canonical CBOR
                                        //   but not interpreted by the v1 reference viewer
    title:             Option<String>,  // Plaintext title surfaced on the viewer
                                        //   countdown before reveal. Bound to qub_id
                                        //   via title_hash (§4.1). 1..=100 NFC code
                                        //   points, no hostile/control code points.
}

2.4 RevealedQub (megjelenítő alkalmazás állapota)

Nem szerializálódik CBOR-ba. A megjelenítő alkalmazáshoz helyi. Sikeres visszafejtés és ellenőrzés után épül fel.

RevealedQub {
    qub_id:              [u8; 32],
    arweave_tx_id:       String,
    visibility:          u8,
    content_type:        u8,
    created_at:          i64,
    unlock_at:           i64,
    outcome_at:          Option<i64>,       // Carried from both wire layers; drives the verdict-watch block
    drand_chain_id:      String,
    drand_round:         u64,
    sender_label:        Option<String>,
    title:               Option<String>,    // Carried forward from SealedQub.title
    reply_to:            Option<[u8; 32]>,
    body:                Vec<u8>,
    body_hash:           [u8; 32],
    body_hash_verified:  bool,
    author_signature:    Option<Vec<u8>>,
    author_pubkey:       Option<Vec<u8>>,
    signature_verified:  Option<bool>,
    cosigner_pubkey:     Option<Vec<u8>>,
    cosigner_signature:  Option<Vec<u8>>,
    cosigner_verified:   Option<bool>,
}

3. Kanonikus CBOR-profil

Minden SealedQub és QubEnvelope szerializációnak meg KELL felelnie ennek a profilnak. Két megvalósításnak ugyanazon logikai struktúra esetén azonos bájtokat KELL előállítania.

3.1 Kódolási szabályok

Szabály Specifikáció
Szabvány RFC 8949 §4.2.1 (Core Deterministic Encoding Requirements)
Kulcsrendezés a térképben Először a kódolt bájthossz szerint rendezve (rövidebb a hosszabb előtt), majd lexikografikusan (bájtonként az azonos hosszúságú kódolásoknál)
Egész szám kódolása Legrövidebb forma: 0–23 a kezdeti bájtban; 24–255 2 bájtban; 256–65535 3 bájtban; stb.
Hosszkódolás Csak határozott hosszúságok. Nincsenek határozatlan hosszúságú tömbök, térképek, bájtsorozatok vagy szöveges karakterláncok (a kiegészítő info = 31 tilos).
Címkék Nincsenek CBOR-címkék (a 6-os főtípus tilos).
Lebegőpontos Nincsenek lebegőpontos számok (a 7-es főtípus 0xF9–0xFB értékei tiltottak).
Szöveges karakterláncok UTF-8 kódolt, NFC-normalizált (Unicode Normalization Form C).
Bájtsorozatok Nyers bájtok. Nincs base64 kódolás a CBOR-rétegen.
Duplikált kulcsok Hibával elutasítva. Az elemzők NEM fogadhatják el csendben a duplikált térképkulcsokat.
Ismeretlen kulcsok Hibával elutasítva. Az elemzők NEM tolerálhatják a típus kanonikus kulcskészletén kívüli térképkulcsokat — két különböző kanonikus bájtsorozat soha nem dekódolódhat ugyanarra az értékre (encode(decode(x)) == x), aláírt törzsek esetében pedig egy extra kulcs olyan rejtett tartalom lenne, amelyhez mindkét aláírás kötelezi magát. A séma fejlődése a version mezőn keresztül történik, soha nem extra kulcsokkal.
Egyszerű értékek Csak a true (0xF5), false (0xF4) és null (0xF6) megengedett.
Opcionális mezők A hiányzó opcionális mezők teljesen kihagyásra kerülnek a CBOR-térképből (nem null-ként kódolva). A jelen lévő opcionális mezők rendezett kulcssorrendben szerepelnek.

3.2 Ellenőrzött kanonikus kulcssorrendek

Ezek a kulcssorrendek normatívak. A megvalósításoknak pontosan ebben a sorrendben KELL kibocsátaniuk a kulcsokat. A hibakeresési ellenőrzéseknek (debug assertions) ELLENŐRIZNIÜK KELLENE a sorrendet a nem kiadási buildekben.

QubEnvelope (0x01-es verzió, aláíratlan, minden opcionális mező hiányzik):

"body"                (5 encoded bytes)
"qub_id"              (7 encoded bytes)
"sig_alg"             (8 encoded bytes)
"version"             (8 encoded bytes)
"reply_to"            (9 encoded bytes)   ← only if present (reply chains)
"body_hash"           (10 encoded bytes)
"unlock_at"           (10 encoded bytes)
"created_at"          (11 encoded bytes)
"outcome_at"          (11 encoded bytes)  ← only if present (verdict mechanic)
"content_type"        (13 encoded bytes)
"sender_label"        (13 encoded bytes)  ← only if present
"author_pubkey"       (14 encoded bytes)  ← only if present
"cosigner_pubkey"     (16 encoded bytes)  ← only if present (pact cosign)
"author_signature"    (17 encoded bytes)  ← only if present
"cosigner_signature"  (19 encoded bytes)  ← only if present (pact cosign)

QubEnvelope kulcssorrend levezetése: minden kulcs egy CBOR szöveges karakterlánc. Kódolt hossz = 1 bájt fejléc + a karakterlánc hossza (24 bájtnál rövidebb karakterláncoknál). Először a teljes kódolt hossz szerint rendezve, majd lexikografikusan az azonos hosszúságú kulcsoknál.

SealedQub (0x01-es verzió, nyilvános, címzett nélkül):

"title"             (6 encoded bytes)   ← only if present
"qub_id"            (7 encoded bytes)
"version"           (8 encoded bytes)
"unlock_at"         (10 encoded bytes)
"outcome_at"        (11 encoded bytes)  ← only if present (verdict mechanic)
"visibility"        (11 encoded bytes)
"drand_round"       (12 encoded bytes)
"drand_chain_id"    (15 encoded bytes)
"recipient_pubkey"  (17 encoded bytes)  ← only if present
"tlock_ciphertext"  (17 encoded bytes)
"drand_chain_version" (20 encoded bytes) ← only if present (W3; absent = quicknet)

PactTerms (paktum-törzs, content_type 0x03):

"notes"         (6 encoded bytes)  ← only if present
"terms"         (6 encoded bytes)
"title"         (6 encoded bytes)
"party_a"       (8 encoded bytes)
"party_b"       (8 encoded bytes)
"pact_version"  (13 encoded bytes)

PactTerm (a terms tömb egy sora):

"key"    (4 encoded bytes)
"value"  (6 encoded bytes)

PartyIdentifier (party_a / party_b térkép):

"label"    (6 encoded bytes)
"contact"  (8 encoded bytes)  ← only if present

3.3 Bájtkódolási referencia

Típus CBOR-kódolás Példa
SHA3-256 kivonat (32 bájt) 0x58 0x20 + 32 bájt body_hash, qub_id
Időbélyegek (i64) 0-s főtípus (pozitív) vagy 1-es (negatív), legrövidebb kódolás Unix másodperc
Verzió (u8, 1-es érték) 0x01 (egyetlen bájt)
Tartalomtípus (u8, 1-es érték) 0x01 (egyetlen bájt)
sig_alg (u8, 0-s érték) 0x00 (egyetlen bájt)
ML-DSA-65 aláírás (3 309 bájt) 0x59 0x0C 0xED + 3 309 bájt author_signature, cosigner_signature
ML-DSA-65 nyilvános kulcs (1 952 bájt) 0x59 0x07 0xA0 + 1 952 bájt author_pubkey, cosigner_pubkey

4. Normatív levezetések

4.1 qub_id

A qub_id egyedileg azonosít egy qubot, és összeköti a QubEnvelope-ot a SealedQub-bal. Determinisztikusan vezetődik le a boríték tartalmából.

qub_id = SHA3-256(
    "QUB_ID_V2"          ||  // domain separator: ASCII bytes [0x51 0x55 0x42 0x5F 0x49 0x44 0x5F 0x56 0x32] (9 bytes) + 0x00 padding (1 byte) = 10 bytes
    version              ||  // u8 (1 byte)
    content_type         ||  // u8 (1 byte)
    created_at           ||  // i64 big-endian (8 bytes)
    unlock_at            ||  // i64 big-endian (8 bytes)
    outcome_at_or_zero   ||  // i64 big-endian (8 bytes; 0 when outcome_at is absent)
    drand_round          ||  // u64 big-endian (8 bytes)
    body_hash            ||  // [u8; 32] (32 bytes)
    title_hash               // [u8; 32] (32 bytes; absent-sentinel = [0u8; 32])
)
// Total preimage: 108 bytes → 32-byte output

Tartománymegkülönböztető kódolása: a "QUB_ID_V2" karakterlánc 9 ASCII-bájt. Egyetlen 0x00 kitöltőbájt fűződik hozzá, hogy elérje a 10 bájtot az igazításhoz. A megvalósításoknak pontosan ezt a 10 bájtot KELL használniuk: [0x51, 0x55, 0x42, 0x5F, 0x49, 0x44, 0x5F, 0x56, 0x32, 0x00].

outcome_at kódolása: egy kiadás előtti megvalósítási változat 92 bájtról 100 bájtra bővítette a bemeneti képet, hogy az opcionális outcome_at mezőt a kötésbe fonja. A hiányzó outcome_at 8 nulla bájtként kódolódik; a protokoll-validátorok mindenhol elutasítják az outcome_at <= 0 értékeket, így ez az őrérték nem ütközhet egy érvényes értékkel. Lásd a §3.2-t (wire-formátum) és a fán belüli tasks/verdict-uplift-plan.md fájlt a mezőt motiváló ítélet-mechanikáért.

drand_round kódolása: egy későbbi kiadás előtti megvalósítási változat 100 bájtról 108 bájtra bővítette a bemeneti képet, hogy a drand_round mezőt (a cél drand-kör, §4.3) is bekösse a kötésbe, és a tartományelválasztót QUB_ID_V2-re emelte. Ez beköti az időzáras kört a qub identitásába: egy átjáró nem kötheti át a titkosított szöveget egy másik (pl. már elmúlt) körhöz, mint amit a megjelenített unlock_at sugall. A feloldási eljárás (§8) ezen felül igazolja, hogy a tlock titkosított szöveg szakaszába (stanza) sütött kör megegyezik az unlock_round(unlock_at) értékével, így a megjelenített feloldási idő bizonyíthatóan az a kör, amely a visszafejtést kapuzza.

Tulajdonságok:

4.2 body_hash

body_hash = SHA3-256(body)

Ahol a body a nyers Vec<u8> tartalom-hasznosadat. Szöveges qubok esetén ez az UTF-8 kódolt qub-törzs.

4.2.1 title_hash

title_hash = SHA3-256(NFC(title).utf8_bytes)   if title is present
title_hash = [0u8; 32]                         if title is absent

Ahol a title az opcionális egyszerű szöveges cím, amely a megjelenítő visszaszámlálásán jelenik meg a felfedés előtt (lásd §3.2). Az NFC-normalizálás a kivonatképzés idején fut, így a kivonat stabil a vizuálisan egyenértékű kódpont-sorozatok között. A csupa nulla őrérték a hiányzó esetre van fenntartva; az üres karakterlánc a kanonikus CBOR-határon a „hiányzó” nem kanonikus kódolásaként kerül elutasításra (a kanonikus kódolás teljesen kihagyja a mezőt).

4.3 Feloldási kör leképezése

drand_round = floor((unlock_at - chain_genesis_time) / chain_period_seconds) + 1
Paraméter Forrás Példa
unlock_at Felhasználó által választott Unix másodperc UTC 1735689600 (2025-01-01 00:00:00 UTC)
chain_genesis_time drand-lánc info (genesis_time) 1595431050
chain_period_seconds drand-lánc info (period) 30

Ez a drand referencia-CurrentRound leképezése. A drand az r kör aláírását a chain_genesis_time + (r - 1) * chain_period_seconds időpontban teszi közzé.

Igazítási tulajdonság (a gyakorlatban fontos eset): ha az (unlock_at - chain_genesis_time) pontosan osztható a chain_period_seconds értékkel, a kiválasztott kör aláírása pontosan az unlock_at időpontban, sosem előbb jelenik meg. A referencia-telepítésben ez mindig teljesül: a quicknet genezisideje (1692803367) osztható a 3 másodperces periódusával, a referenciaalkalmazások pedig egész percekre rögzítik a feloldási időt. Nem igazított unlock_at esetén a kiválasztott kör aláírása szigorúan egy periódusnál kevesebbel az unlock_at előtt jelenik meg — a kötelezettségvállalás időbeli pontossága egy beacon-periódus.

Régi, kiadás előtti leképezés és feloldásoldali tolerancia: az eredeti leképezés ceil((unlock_at - chain_genesis_time) / chain_period_seconds) volt, amely a fenti periódushoz igazított esetben a unlock_at előtt pontosan egy teljes periódussal közzétett kört választotta ki. A két leképezés pontosan +1-gyel tér el, amikor a különbség osztható a periódussal, máskülönben megegyezik. Mivel a drand_round az állandó qub_id bemeneti képébe van kötve (§4.1), a régi leképezéssel lepecsételt műtárgyak nem vezethetők át újra; ezért a §8 6a. lépésének kör-keresztellenőrzését végző ellenőrzőknek el KELL fogadniuk, ha a tárolt drand_round vagy a levezetett kör, vagy a levezetett kör mínusz egy (és meg KELL követelniük, hogy a tlock szakaszköre pontosan a tárolt kör legyen). A tolerancia legfeljebb egy periódussal hozza előre a kapuzó aláírást. A paktum-előkészítő szolgáltatás ugyanezt a toleranciát alkalmazza a színrevitt paktum qub_id-jának újralevezetésekor, és ahhoz a körhöz pecsételi a végleges paktumot, amelyhez a qub_id ténylegesen kötődik.

Validáció: az unlock_at értéknek a lezárás idején a jövőben KELL lennie. Az unlock_at NEM lehet több mint 10 évvel a created_at után (a hosszú távú drand-függőség kockázatának korlátozása érdekében; a felhasználói felületnek FIGYELMEZTETNIE KELLENE a 2 éven túli feloldási dátumoknál).


5. Wire-formátum newtype-ok

A wire-formátum newtype-ok fordítási idejű biztonságot nyújtanak a CBOR-bájtok JSON-nal, nyers egyszerű szöveggel vagy más bájtkódolásokkal való összetévesztése ellen.

Típus Tartalmazza Előállítja Felhasználja
SealedQubCbor A SealedQub kanonikus CBOR-ja serialize_sealed_qub() Belső vezetékes műtárgy; nyilvános kézbesítésnél csupaszon, privát kézbesítésnél burkolva tárolódik, majd a megjelenítő állítja helyre
QubEnvelopeCbor A QubEnvelope kanonikus CBOR-ja serialize_qub_envelope() tlock-titkosítás bemenete, tlock-visszafejtés kimenete

5.1 Konstrukciós szabályok

// Production code — only through CBOR serialisers:
let sealed = SealedQubCbor::from_encoded(cbor_bytes);

// There is deliberately NO From<Vec<u8>> implementation.
// You cannot accidentally wrap arbitrary bytes in a wire format type.

// Accessing raw bytes:
let bytes: &[u8] = sealed.as_bytes();
let bytes: Vec<u8> = sealed.into_bytes();

5.2 Validáció a konstrukciónál

A from_encoded()-nak ELLENŐRIZNIE KELLENE, hogy a bemenet érvényes CBOR-térképfejléccel kezdődik. A teljes szerkezeti validáció az elemzés idején történik, nem a konstrukció idején, hogy elkerülje a dupla elemzést.


6. Tartalomtípus-nyilvántartás

Érték Típus Max. törzsméret Megjegyzések
0x00 Fenntartott (érvénytelen) — NEM HASZNÁLHATÓ
0x01 Egyszerű szöveg (UTF-8, korlátozott Markdown) 50 KB fizetős / 10 KB ingyenes A megjelenítési szabályokért lásd §10. Az ingyenes / fizetős felosztást a feltöltési szolgáltatás érvényesíti; a protokollréteg kemény felső határa 50 KB.
0x02 Fenntartott (jövőbeli) — Jövőbeli tartalomtípus számára lefoglalva; v1-ben nem érvényes. A megjelenítőknek el KELL utasítaniuk az alábbi szabály szerint.
0x03 Paktum (kétoldalú megállapodás, CBOR-törzs) 100 KB A törzs kanonikus CBOR PactTerms (§6.1). Társaláírás a §9.7 szerint.
0x04 Ítélet (alkotói önértékelés, CBOR-törzs) 8 KB A törzs kanonikus CBOR VerdictBody (§6.2). Csak a rendszeroldali verdict szándék bocsátja ki. A szülőkapcsolat a Parent-Tx-Id Arweave-címkén van, nem a törzsben. Lásd verdict-uplift-plan §3.4.

A megjelenítőknek el KELL utasítaniuk az ismeretlen tartalomtípusokat egyértelmű, felhasználó számára látható hibával. A megjelenítők NEM kísérelhetik meg az ismeretlen típusok szövegként való megjelenítését.

6.1 Paktum-törzs (content_type = 0x03)

A paktum-törzs egy PactTerms érték kanonikus CBOR-kódolása:

PactTerms {
    pact_version:  u8,                    // 0x01 for structured/v1
    title:         String,                // ≤ 200 bytes, NFC
    terms:         Vec<PactTerm>,         // ≤ 20 rows
    party_a:       PartyIdentifier,       // initiator
    party_b:       PartyIdentifier,       // counter-signer
    notes:         Option<String>,        // ≤ 5,000 bytes, NFC; absent key if none
}

PactTerm       { key: String (≤ 100 bytes), value: String (≤ 2,000 bytes) } // NFC
PartyIdentifier{ label: String (≤ 100 bytes), contact: Option<String (≤ 320 bytes)> }

A három térkép kanonikus CBOR-kulcssorrendjeit a §3.2 adja meg. A teljes szerializált paktum-CBOR NEM haladhatja meg a 100 KB-ot (megegyezik a §6-tal).

Sémamegkülönböztető. A structured/v1 paktum terms tömbjének első sorának { key: "pact_schema", value: "structured/v1" }-nek KELL lennie. Az ezen jelölés nélküli sorok „egyedi” paktumok, és nem kapnak strukturált validációt vagy sématudatos megjelenítést.

Fagyasztott visszaigazolási helyek. A structured/v1 paktumok pontosan négy visszaigazolási sort hordoznak ezeken a kulcsokon:

"initiator_standard_terms"
"initiator_capacity_terms"
"counterparty_standard_terms"
"counterparty_capacity_terms"

Mindegyik value mezője nyolc fagyasztott angol karakterlánc egyike, amelyet a (role, kind) pár választ ki, ahol role ∈ { seller, buyer, provider, client } és kind ∈ { standard, capacity }. Maguk a karakterláncok normatív protokolladatok — mindkét fél ML-DSA-65 aláírása a body_hash-en keresztül a pontos bájtokra kötelez. NEM lokalizáltak; az aláírt törzs nyelvfüggetlen. Bármely szövegezési változtatás új sémaverziót igényel (structured/v2).

A nyolc karakterláncot, keresésüket (acknowledgement_for(role, kind)) és mindegyik indoklását a referencia-megvalósítás rögzíti. A megfelelő megvalósításoknak bájtazonos visszaigazolási értékeket KELL kibocsátaniuk; mind a négy szerepkombinációt lefedő arany-fixture SHA3-256 body-hash tesztek elkapnak bármely eltérést.

Megjelenítő-megjelenítési sorrend. A visszaigazolási karakterláncok olyan kifejezéseket tartalmaznak, mint a „described above” (fent leírt), amely feltételezi, hogy a leírás / hatókör sorok a visszaigazolások előtt jelennek meg. A megjelenítőknek a terms tömböt CBOR-sorrendben KELL megjeleníteniük; az átrendezés megtöri a prózai szemantikát.

Ellenérdekelt fél kapcsolata. Amikor a B fél contact mezője érvényes e-mail-cím, a qub feltöltési szolgáltatás automatikusan elküld egy áttekintési / társaláírási meghívó e-mailt a színrevitel idején, és az esetleges társaláírást ugyanazon cím ellenőrzéséhez köti (§9.7). Azok a paktumok, amelyek B felének kapcsolata hiányzik, továbbra is társaláírhatók, de csak sávon kívüli csatornán keresztül — a szolgáltatás visszautasítja azokat a társaláírási kéréseket, amelyek nem tudnak megfelelő 15 perces e-mail-ellenőrzési jelölőt előállítani.

6.2 Ítélet-törzs (content_type = 0x04)

Az ítélet-törzs egy VerdictBody érték kanonikus CBOR-kódolása:

VerdictBody {
    verdict_version: u8,                  // 0x01 for structured/v1
    outcome:         u8,                  // 1=Right · 2=Partial · 3=Wrong · 4=Unfalsifiable
    reflection:      Option<String>,      // ≤ 2,000 bytes NFC; "what changed, what did you learn"
    evidence_url:    Option<String>,      // ≤ 2,048 bytes; HTTPS only; absent key when omitted
}

Kanonikus CBOR-kulcssorrend:

"outcome"          (8 encoded bytes)
"reflection"       (11 encoded bytes)  ← only if present
"evidence_url"     (13 encoded bytes)  ← only if present
"verdict_version"  (16 encoded bytes)

A teljes szerializált ítélet-CBOR NEM haladhatja meg a 8 KB-ot (megegyezik a fenti regisztrációs sorral).

Eredmény-enumeráció. A wire-bájt szándéktól független; a négy kategória — Right / Partial / Wrong / Unfalsifiable — lefedi minden ítéletet hordozó szándék eredményterét. A szándékfüggő címkék („Megmondtam” / „Megtartottam” / „Terv szerint szállítottuk” / „Az események igazolták” a Right esetében stb.) a megjelenítő oldali renderelés kérdése, a szülő qub szándéka alapján — a wire nyelv- és szándék-független marad. Az 1..=4 tartományon kívüli értékeket dekódoláskor el KELL utasítani.

Szülő-kapcsolat. Egy ítélet-qub NEM hordozza a szülő-hivatkozást a törzsében. A szülő qub Arweave-tranzakcióazonosítója a Parent-Tx-Id tárolási címkeként kerül kibocsátásra feltöltéskor (§7 tárolási címkeréteg). Ez a törzset önálló, aláírt önértékelési nyilatkozatként tartja meg; az audit-lánc („mire vonatkozóan volt igaza?”) az Arweave-címke keresése révén jön létre.

Bizonyíték-URL biztonsága (normatív). Amikor az evidence_url jelen van, a validátoroknak (összeállítás-oldal, wire-oldal, Worker él) érvényesíteniük KELL:

  1. Csak HTTPS. A karakterláncnak a https:// bájtsorozattal KELL kezdődnie. Bármely más séma — http, ftp, javascript, data, file stb. — elutasításra kerül.
  2. Hosszkorlát. ≤ 2 048 bájt (gyakorlati böngésző-URL-korlát).
  3. NFC + ellenséges-kódpont-ellenőrzés. Ugyanaz a szabály, mint a title és reflection esetén — bidi-felülírás / nulla szélességű / tag-blokk / BOM / C0 / C1 kódpontok elutasításra kerülnek. A definíció megegyezik a Rust crate::handle::contains_hostile_text_codepoint és a TS workers/api/src/utils/unicode.ts::isHostileCodepoint függvényekkel (tartsd őket szinkronban).
  4. Nincs szóköz, nincsenek ASCII-vezérlők. A szóközök / DEL / 0x20 alatti bájtok az URL bármely pontján elutasításra kerülnek — ez zárja le a \n/\t injekciós vektort, amelyet a bidi-szabály nem fed le.
  5. Nem üres gazdagép-szegmens. A https:// és az első /, ? vagy # közötti tartománynak nem üresnek KELL lennie.

Nincs szerveroldali lekérés. A Worker NEM proxyzhatja, kérheti le vagy nézheti meg előnézetben az URL-t. A protokoll egy karakterláncot tárol; a megjelenítés megjelenítő-oldalon történik rel="nofollow noopener noreferrer" target="_blank" attribútumokkal és a linkszöveg mellett láthatóan megjelenített gazdagéppel.

Reflexió. Opcionális alkotó által írt reflexiós szöveg („mi változott, mit tanultál”). Ugyanaz az NFC + ellenséges-kódpont-validáció, mint a title esetében. Az üres / csak szóközből álló bemenet az építéskor hiányzóra esik vissza.

Sémaverzió. A v1 csak verdict_version = 0x01 értéket támogat. A jövőbeli sémaverziók megemelik ezt a bájtot, és új protokollverzióval együtt érkeznek a §12 szerint.


7. Lezárási protokoll

A teljes lezárási sorozat. Minden lépés normatív.

 1. User composes plaintext and metadata in ComposeQub.
 2. Validate:
    a. body is non-empty.
    b. body size ≤ max for content_type and user tier (see §6).
    c. unlock_at is in the future.
    d. unlock_at ≤ created_at + 10 years.
    e. content_type is a known, supported value.
    f. visibility is 0x00 (private) or 0x01 (public).
 3. Compute body_hash = SHA3-256(body).
 4. Set created_at = current Unix seconds UTC.
 5. Select drand chain. Load chain_genesis_time and chain_period_seconds, and
    compute drand_round = floor((unlock_at - chain_genesis_time) / chain_period_seconds) + 1
    (§4.3). (Computed here, before qub_id, because drand_round is bound into the
    qub_id preimage—§4.1.)
 6. Compute qub_id (see §4.1), folding in drand_round from step 5.
 7. Construct QubEnvelope with all fields.
 8. Serialise QubEnvelope using canonical CBOR → bytes B.
    Assert: serialised output matches canonical profile (§3).
 9. Compute C = tlock_encrypt(B, drand_round, drand_chain_public_key).
10. Construct SealedQub with tlock_ciphertext = C and matching qub_id, version,
    visibility, unlock_at, drand_chain_id, and drand_round.
11. Serialise SealedQub using canonical CBOR → SealedQubCbor.
12. Select the delivery shape from visibility:
    a. Private (0x00): generate K = 32 random bytes and N = 12 random bytes
       using a CSPRNG. Compute W = wrap_sealed_qub(SealedQubCbor,
       qub_id=qub_id, key=K, nonce=N) per §13. Upload payload = W.
    b. Public (0x01): upload payload = bare SealedQubCbor; do not generate K.
13. Display seal-time disclosure. User confirms.
14. Validate upload eligibility via the qub upload service (bot-detection, entitlement, rate limits).
15. Submit the selected upload payload to the qub upload service. For a private
    browser seal, the service is byte-blind to the inner SealedQubCbor and never
    receives K. The Builder `/api/v1/seal` route is an explicit exception: it
    receives plaintext and caller-supplied K in memory, then persists neither.
16. Receive arweave_tx_id from the service. For private delivery, construct
    `<origin>/c/<arweave_tx_id>#<base64url(K)>` (or the equivalent short-code
    path). For public delivery, omit the fragment. Browsers do not transmit URL
    fragments to servers, so K from the browser-seal path is not observed by
    qub.social or any storage gateway.

Tárolási címkeréteg (sávon kívül). A qub feltöltési szolgáltatás szándékosan kis halmaz tárolási tranzakciós címkét csatol a kiválasztott feltöltési hasznos adat mellé. A Content-Type=application/octet-stream normatívan kötelező. A referencia-szolgáltatás emellett három opcionális címkét csatol, amikor az alkotó úgy dönt, hogy megjeleníti őket: Intent (engedélylistával ellenőrzött összeállítási szándék — announcement, thesis, prediction, letter, secret, commitment, proof vagy a rendszer által kibocsátott verdict), Author (az alkotó §9.3 nyilvános kulcsának ujjlenyomata 64 karakteres kisbetűs hexként) és Parent-Tx-Id (a szülő qub tárolási tranzakciós azonosítója válaszláncokhoz, 43 karakteres base64url).

Az Author címke qubonként választható: a referencia-alkotóalkalmazás csak akkor csatolja, ha a felhasználó kifejezetten engedélyezi a nyilvános tulajdonítást a lezárás idején. Amikor a kapcsoló ki van kapcsolva — ez az alapértelmezett —, nem íródik Author címke, és a qub a láncon tulajdonítatlan: semmi az állandó tárhelyen nem köti össze a feltöltést egy alkotó kezelőjével, e-mail-címével vagy más qubjaival. Amikor a kapcsoló be van kapcsolva, az Author ujjlenyomat az alkotó által választott @kezelő-re oldódik fel a §9.5 attesztációs láncon keresztül. A válaszlánc-kapcsolatok és az Intent nem azonosítóak. Privát kézbesítésnél a külső burkoló (§13) titkosítja a felismerhető belső SealedQub-artefaktumot, ezért a tárolt burkolók begyűjtése és a nyilvános drand-aláírások megszerzése K nélkül továbbra sem elegendő a törzs visszanyeréséhez; a tárolási címkék szándékosan nyilvános metaadatok maradnak.

A referencia-szolgáltatás szándékosan NEM csatol App-Name, App-Version vagy Type címkéket: bármely ilyen egyértékű szűrő egy GraphQL-lekérdezésnek a teljes qub-korpuszt visszaadná, ami nincs összhangban a burkoló csak-törzs bizalmassági hatókörével.

A megfelelő ellenőrzőnek NEM szabad semmilyen tárolási címkétől függenie a §11 harmadik fél általi ellenőrzéshez; a body hash / qub_id / aláírás csak a belső CBOR-ra kötelez, soha nem a címkehalmazra.


8. Feloldási protokoll

A teljes feloldási sorozat. Minden lépés normatív.

 1. Viewer opens delivery URL. Extract arweave_tx_id from the path and retain
    the optional URL fragment. Do not assume a missing fragment is an error:
    public/bare delivery intentionally has no K.
 2. Check denylist. If tx_id is denylisted → display block message. Stop.
 3. Fetch the stored bytes (with multi-gateway fallback).
 3a. Resolve the delivery shape structurally:
    a. If the bytes parse as OuterWrapper, require a well-formed 32-byte K in
       the URL fragment, require wrapper version 0x01, and unwrap per §13.
       Any missing/malformed K or AEAD failure is a terminal error.
    b. Otherwise require the bytes to parse as bare SealedQubCbor; no K is
       required. If neither shape parses, report an integrity error.
 4. Parse SealedQubCbor → SealedQub.
 5. Validate: SealedQub.version is known (0x01), visibility is known, and the
    delivery shape matches it (wrapped = 0x00 private; bare = 0x01 public).
    Reject any mismatch or unknown value.
 6. If current time < SealedQub.unlock_at → display countdown. Poll or wait.
 6a. Round-binding check. Recompute expected_round from
    SealedQub.unlock_at per §4.3. Reject unless SealedQub.drand_round ==
    expected_round OR SealedQub.drand_round == expected_round - 1 (the
    legacy pre-release mapping—see §4.3), AND the round baked into the tlock
    ciphertext stanza (read via the age/tlock header, no signature required)
    == SealedQub.drand_round exactly. The stanza round is the one that
    actually gates decryption; without this check a malicious creator could
    bind the ciphertext to an already-past round while displaying a future
    countdown, so anyone reading the stored bytes could decrypt before
    unlock_at. Implementations with no chain identity (test mocks) skip this
    check.
 7. Once current time ≥ SealedQub.unlock_at:
    a. Fetch drand round signature for SealedQub.drand_round from drand network.
    b. Compute B = tlock_decrypt(SealedQub.tlock_ciphertext, round_signature).
 8. Parse B → QubEnvelope.
 9. Validate QubEnvelope.version is known.
10. Verify: SHA3-256(QubEnvelope.body) == QubEnvelope.body_hash.
    Fail → integrity error.
11. Verify: QubEnvelope.qub_id == SealedQub.qub_id.
    Fail → integrity error.
12. Verify: QubEnvelope.unlock_at == SealedQub.unlock_at.
    Fail → integrity error.
12a. Verify: QubEnvelope.outcome_at == SealedQub.outcome_at (both absent, or
    both present and equal). Fail → integrity error.
12b. Content re-derivation. Recompute qub_id per §4.1 from the decrypted
    fields — (QubEnvelope.version, content_type, created_at, unlock_at,
    outcome_at, SealedQub.drand_round, QubEnvelope.body_hash,
    title_hash(SealedQub.title)) — and verify it equals SealedQub.qub_id.
    Fail → integrity error. The pairwise checks in steps 10-12a only prove
    the two layers agree with EACH OTHER; a forger who rewrites a bound
    field consistently on both surfaces (a pre-reveal title swap, or a
    post-round body swap with a recomputed body_hash re-encrypted to the
    same round under the same qub_id) passes them all. Only re-deriving
    the identity from content closes this.
13. Verify: QubEnvelope.content_type is known and renderable.
    Known values: 0x01 (text), 0x03 (pact), 0x04 (verdict).
    Unknown → display error.
14. If QubEnvelope.sig_alg != 0x00 → verify author signature (see §9.4).
15. If cosigner_pubkey or cosigner_signature present → verify cosigner (see §9.7).
16. Render content using the appropriate renderer (see §10 for text and §6 for pact/verdict).
17. Construct RevealedQub for display.

9. Szerzőség aláírása

9.1 Indoklás

A qubok állandó tárhelyen tárolódnak. A szerzőségi aláírásoknak határozatlan ideig hamisíthatatlannak kell maradniuk, ezért a v1.0 a posztkvantum ML-DSA-65 sémát (FIPS 204) használja, nem pedig egy klasszikus sémát, amelynek biztonsága a qub állandó élettartamán belül romolhat.

9.2 Algoritmus-nyilvántartás

sig_alg Séma Kulcsméret Aláírásméret Állapot
0x00 Nincs aláírás (aláíratlan) — — Aktív
0x01 ML-DSA-65 (FIPS 204) 1 952 bájt 3 309 bájt Aktív
0x02 Ed25519 32 bájt 64 bájt Fenntartott konstans; a v1 protokollban nem támogatott

A v1 protokoll megjelenítőinek a {0x00, 0x01} halmazon kívüli minden értéket el KELL utasítaniuk, beleértve a fenntartott 0x02 értéket is. A fenntartás megakadályozza a véletlen újrafelhasználást; nem jelenti az aktiválást. Az aktiválás a §15-ben leírt szabályozott változtatást igényli.

9.3 Aláírt bemeneti kép konstrukciója

Két bemeneti kép-verzió létezett. Minden aláírásnak V2-t KELL használnia, és az ellenőrzőknek KIZÁRÓLAG a V2-t KELL elfogadniuk. A régi V1 bemeneti kép (alább, történeti hivatkozásként dokumentálva) csak ellenőrzési tartalékként volt elfogadott a V2-re való átállás idején; ez a tartalék azóta kivezetésre került, és a kizárólag V1 ellen érvényes aláírást mostantól elutasítjuk.

V2 (jelenlegi — minden új szerzői aláírás, valamint a paktum-színrevitel / társaláírási folyamat mindkét aláírása ezt állítja elő):

sig_input = SHA3-256(
    "QUB_AUTHOR_SIG_V2"  ||    // domain separator (17 bytes)
    version              ||    // u8 (1 byte)
    qub_id               ||    // [u8; 32] (32 bytes)
    body_hash            ||    // [u8; 32] (32 bytes)
    unlock_at            ||    // i64 big-endian (8 bytes)
    0x00                 ||    // u8 (1 byte): MUST be 0x00 in v1.x
    sender_label_hash    ||    // [u8; 32]: SHA3-256(NFC(sender_label)),
                               //   or 32 zero bytes when absent
    reply_to_or_zero           // [u8; 32]: parent qub_id, or 32 zero
                               //   bytes when absent
)

// Total preimage: 155 bytes → 32-byte hash

signature = Sign(author_secret_key, sig_input)

A sender_label_hash ugyanazt a hiányt jelző (absent-sentinel) konvenciót követi, mint a title_hash (§4.2.1): a 32 nullbájt nem érvényes SHA3-256 kimenet, így a „hiányzó” soha nem ütközhet egy jelen lévő címkével. Minden mező fix szélességű, így a bemeneti kép hosszelőtagok nélkül is egyértelmű.

V1 (régi — KIVEZETVE; többé nem állítjuk elő, és ellenőrzéskor sem fogadjuk el):

sig_input = SHA3-256(
    "QUB_AUTHOR_SIG_V1"  ||    // domain separator (17 bytes)
    version              ||    // u8 (1 byte)
    qub_id               ||    // [u8; 32] (32 bytes)
    body_hash            ||    // [u8; 32] (32 bytes)
    unlock_at            ||    // i64 big-endian (8 bytes)
    0x00                       // u8 (1 byte): MUST be 0x00 in v1.0
)

// Total preimage: 91 bytes → 32-byte hash

A V1 bemeneti kép kihagyta a sender_label és reply_to mezőket. Csak ellenőrzési tartalékként volt elfogadott a V2-re való átállás idején; ez a tartalék azóta kivezetésre került — az ellenőrzőknek KIZÁRÓLAG a V2 bemeneti képet KELL elfogadniuk. A definíciót itt történeti hivatkozásként, valamint az alábbi tartománymegkülönböztető magyarázata céljából őrizzük meg. Az olyan aláírást, amely csak a V1 ellen érvényes, ellenőrzési hibaként KELL kezelni.

Tartománymegkülönböztetők: a "QUB_AUTHOR_SIG_V1" / "QUB_AUTHOR_SIG_V2" egyenként 17 ASCII-bájt ([0x51, 0x55, 0x42, 0x5F, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x5F, 0x53, 0x49, 0x47, 0x5F, 0x56, 0x31/0x32]). Nincs kitöltés. Az eltérő megkülönböztető tartományilag elválasztja a két konstrukciót, így az egyik bemeneti kép fölötti aláírás soha nem ellenőrizhető a másikként.

org_id_present bájt: az unlock_at-ot követő bájtnak 0x00-nak KELL lennie. A referencia-megvalósítás ezt ORG_ID_PRESENT_INDIVIDUAL = 0x00 konstansként teszi elérhetővé a crates/qub-core/src/signing.rs fájlban; az ellenőrzéshez sig_input-ot újraépítő megjelenítőknek ugyanazt a bájtot KELL kibocsátaniuk.

Aláírás-hatókör — mi van és mi nincs lefedve. A V2 sig_input közvetlenül a version, qub_id, body_hash, unlock_at, sender_label és reply_to mezőkre kötelez (plusz a rögzített tartománymegkülönböztető és az org_id_present bájt). A qub_id maga is a version, content_type, created_at, unlock_at, outcome_at, drand_round és body_hash mezőkből vezetődik le a §4.1 bemeneti képen keresztül, így e mezők bármely változtatása eltérő qub_id-t eredményez, és tranzitíven érvényteleníti az aláírást. A közvetlenül hitelesített felület tehát:

Mező Aláírás által hitelesített Hogyan
version ✓ Közvetlen bemenet a sig_input-hoz
qub_id ✓ Közvetlen bemenet
body_hash ✓ Közvetlen bemenet
unlock_at ✓ Közvetlen bemenet
content_type ✓ Tranzitíven, a qub_id bemeneti képen keresztül
created_at ✓ Tranzitíven, a qub_id bemeneti képen keresztül
outcome_at ✓ Tranzitíven, a qub_id bemeneti képen keresztül
drand_round ✓ Tranzitíven, a qub_id bemeneti képen keresztül
body ✓ Tranzitíven, a body_hash = SHA3-256(body)-on keresztül
author_pubkey — (implicit) Az aláírást ellenőrző kulcs definíció szerint a szerző
sender_label ✓ Közvetlen bemenet a sender_label_hash-en keresztül (V2 bemeneti kép — az egyetlen elfogadott forma)
reply_to ✓ Közvetlen bemenet a reply_to_or_zero-n keresztül (V2 bemeneti kép — az egyetlen elfogadott forma)
cosigner_pubkey / cosigner_signature — Függetlenül aláírva ugyanazon sig_input-ra (lásd §9.7)
drand_chain_id, tlock_ciphertext, visibility — Külső SealedQub mezők, nem a borítékon belül — saját szerkezeti invariánsaik (kör- / lánckonzisztencia) fedik le őket, de nem a szerzői aláírás (A drand_round mostantól tranzitívan kötve van a qub_id preimage-en keresztül — lásd fent.)

Miért a V2 az egyetlen elfogadott bemeneti kép.

Azoknak a megvalósításoknak, amelyek sender_label-t vagy reply_to-t jelenítenek meg a végfelhasználóknak, a hitelesített identitást (nyilvános kulcs ujjlenyomata, attesztáció) KELL elsődleges identitásjelzésként megjeleníteniük, nem a címkét.

9.4 Ellenőrzési eljárás

1. Read sig_alg from QubEnvelope.
2. If sig_alg == 0x00 → unsigned. No verification. Display "unsigned qub."
3. If sig_alg is unknown → reject. Display "unrecognised signature scheme."
4. Extract author_signature and author_pubkey. If either is absent → integrity error.
5. Reconstruct sig_input using fields from QubEnvelope (V2 formula, §9.3).
6. Verify(author_pubkey, sig_input, author_signature). The V2 preimage is the
   only accepted form — the legacy V1 fallback is retired (§9.3), so a
   signature that does not verify against V2 fails, full stop.
7. If verification succeeds → display "signed by [key fingerprint]."
8. If verification fails → display "signature verification failed."

Az aláírás-ellenőrzés a legdrágább művelet (különösen az ML-DSA-65). Az összes olcsóbb ellenőrzés (kivonat, qub_id, unlock_at) sikeres áthaladása UTÁN KELLENE elvégezni.

9.5 Identitás-attesztációk

Az identitás-attesztációk — az author_pubkey leképezése ember számára felismerhető identitási állításokra, mint például egy qub-kezelő, e-mail-cím, közösségi kezelő vagy passkey hitelesítő adat — megjelenítő-oldali progresszív fejlesztés, és nem szükségesek az aláírás-ellenőrzéshez. Azoknak a megjelenítőknek, amelyek megjelenítési identitásra oldják fel az attesztációkat, az alábbi elsőbbséget KELL alkalmazniuk:

handle > email > social > fingerprint

Az ujjlenyomat-tartalékérték a SHA3-256(author_pubkey) kisbetűs hexa formája; mindig elérhető bármely aláírt qubhoz. A megjelenítők megjelenítés céljából RÖVIDÍTHETIK — a referencia-megjelenítő a qub: előtagot, majd az első és utolsó négy bájtot jeleníti meg (qub:<8 hex>…<8 hex>).

A megfelelő ellenőrző a §9.4 minden ellenőrzését el tudja végezni anélkül, hogy a qub API-val kapcsolatba lépne, az állandó tárhelyen és a drandon túli bármilyen hálózat nélkül, és bármilyen szerveroldali keresés nélkül. Az attesztáció feloldása külön, legjobb erőfeszítésű lépés, amelyet csak az aláírás-ellenőrzés sikeres befejezése után végeznek el.

9.6 Méretre gyakorolt hatás

Ed25519 ML-DSA-65
Aláírás 64 bájt 3 309 bájt
Nyilvános kulcs 32 bájt 1 952 bájt
Összesen qubonként 96 bájt 5 261 bájt
Tárolási költségkülönbség (~$5/MB-nál) ~$0,0005 ~$0,026

Egy 500–2 000 bájtos szöveges qub esetén az ML-DSA-65 nagyjából megháromszorozza a tárolt méretet. Az abszolút költség elhanyagolható.

9.7 Társaláíró-ellenőrzés (paktum kétoldalú megállapodások)

Kétoldalú megállapodásoknál (content_type = 0x03) egy második aláírási réteg bizonyítja, hogy mindkét fél hozzájárult ugyanazokhoz a feltételekhez.

Borítékmezők:

Mindkét mezőnek együtt KELL jelen lennie, vagy mindkettőnek hiányoznia. Ha pontosan az egyik van jelen, a megjelenítőknek integritáshibát KELL jelenteniük.

Ellenőrzési eljárás:

1. If cosigner_pubkey absent and cosigner_signature absent → no cosigner. Done.
2. If exactly one is present → integrity error.
3. Verify cosigner_pubkey != author_pubkey (prevent self-cosigning).
   Fail → display "cosigner pubkey must differ from author."
4. Reconstruct sig_input using the same formula as §9.3 (V2 only — the
   legacy V1 fallback is retired; all pact clients produce V2 signatures).
5. Verify(cosigner_pubkey, sig_input, cosigner_signature).
6. Success → display "co-signed by [cosigner fingerprint]."
7. Failure → display "co-signature verification failed."

Tulajdonságok:

E-mail-kötési kapu (működési). Amikor egy színrevitt paktum B fél e-mail-kapcsolatot hordoz (§6.1), a qub feltöltési szolgáltatásnak el KELL utasítania a társaláírási kérést, hacsak nem létezik rövid élettartamú e-mail-ellenőrzési jelölő, amely megegyezik mind a színrevitel azonosítójával, mind az adott kapcsolat normalizált e-mail-kivonatával. A jelölőt a /api/v1/auth/verify írja, amikor a magic-link token staging_id-t hordoz, és az ellenőrzött cím megegyezik a SHA-256(normalise_email(party_b.contact))-tal — ahol a normalise_email(addr) megőrzi a helyi rész kis-/nagybetűjét, és csak a tartományrészt kisbetűsíti (az RFC 5321 §2.3.11 szerint), és a SHA-256 itt a NIST FIPS 180-4 kivonat (eltérő a §4 levezetésekben használt SHA3-256-tól) —, és 900 másodperccel (15 perccel) a kibocsátás után lejár. Ez működési megszemélyesítés-elleni kapu, NEM a láncon lévő qub-bizonyíték része — egy harmadik fél ellenőrzőnek, amely a §11-et lejátssza, csak állandó tárhelyre és drandra van szüksége, bármilyen szerveroldali keresés nélkül. A jelölő csak szerveroldalon létezik, és soha nem része az aláírt törzsnek.

Méretre gyakorolt hatás (ML-DSA-65 szerző + társaláíró):

Komponens Méret
Szerzői aláírás 3 309 bájt
Szerzői nyilvános kulcs 1 952 bájt
Társaláírói aláírás 3 309 bájt
Társaláírói nyilvános kulcs 1 952 bájt
Teljes kriptográfiai többletteher 10 522 bájt
Tárolási költségkülönbség ~$0,05

10. Markdown-megjelenítés és -tisztítás

Ez a szakasz biztonságkritikus. A megjelenítő a szöveges qubokat (content_type = 0x01) korlátozott Markdown-részhalmazzal jeleníti meg.

10.1 Engedélyezett elemek

10.2 Tiltott elemek

Elem Kezelés
Nyers HTML (<div>, <script> stb.) Teljesen eltávolítva. Semmilyen HTML nem jut át.
Képek (![alt](url)) Eltávolítva. A kép-szintaxis eltávolításra kerül a kimenetből.
Hivatkozások ([text](url)) Az URL látható egyszerű szövegként jelenik meg. Nincs automatikus hivatkozás. Kifejezett felhasználói művelet nélkül nem kattintható.
Veszélyes URL-sémák javascript:, data:, vbscript:, file: — eltávolítva.
Iframe-ek, beágyazások, objektumok Eltávolítva.
HTML-entitások Megjelenítési karakterekké dekódolva, csak ha biztonságosak.

10.3 Megvalósítás

A megvalósításoknak szigorú engedélylista-elemzőt KELL használniuk, nem tiltólistát. Az ajánlott megközelítés:

  1. A Markdown elemzése pulldown-cmark (vagy egyenértékű) használatával.
  2. Az AST bejárása, és bármely olyan csomópont elvetése, amely nincs az engedélylistán (§10.1).
  3. Hivatkozási csomópontoknál: az URL kibocsátása látható szövegként, nem kattintható <a> elemként.
  4. A szűrt AST átalakítása típusos köztes ábrázolássá (pl. egy MarkdownNode enum csak biztonságos variánsokkal). A nyers HTML szerkezetileg nem ábrázolható ebben a köztes ábrázolásban.
  5. Megjelenítés a típusos köztes ábrázolásból a cél megjelenítési rétegbe (pl. reaktív megjelenítési komponensek, DOM-csomópontok). Semmilyen ponton nincs HTML-karakterlánc-összefűzés vagy innerHTML.

A tiltólista-megközelítések törékenyek, mert az új Markdown-bővítmények vagy elemző-furcsaságok szűretlen elemeket vezethetnek be. A típusos-AST megközelítés szerkezetileg lehetetlenné teszi az XSS-t — nincs olyan variáns, amely tetszőleges HTML-t hordozhatna.

10.4 Méret- és szerkezeti korlátok


11. Harmadik fél általi ellenőrzés

Bármely harmadik fél, aki birtokolja a tárolt bájtokat (privát/burkolt qub esetén K-t is), a qub együttműködése nélkül ellenőrizheti a kriptográfiai műtárgyat. A függetlenül időbélyegzett létezési állításhoz emellett vagy qubonként ellenőrzött állandó-tárolási befoglalás, vagy ellenőrzött §16 átláthatósági napló bizonyíték szükséges.

1. Obtain the stored bytes. For a private delivery, also obtain K from the
   delivery-link fragment.
2. Resolve the delivery shape (§8 step 3a): unwrap OuterWrapper with K, or
   accept bare SealedQubCbor. Require shape/visibility agreement.
3. Parse SealedQubCbor → SealedQub; validate protocol version, visibility,
   content type, chain identity, and structural bounds.
4. Recompute expected_round from unlock_at (§4.3); require the stored round
   (allowing the documented legacy minus-one case) and ciphertext-stanza round
   to agree exactly as §8 step 6a specifies.
5. Obtain the drand signature for SealedQub.drand_round and verify its BLS
   signature against the pinned chain public key.
6. tlock_decrypt(tlock_ciphertext, round_signature) → QubEnvelope CBOR bytes.
7. Parse → QubEnvelope.
8. Verify SHA3-256(body) == body_hash.
9. Verify envelope/sealed equality for qub_id, unlock_at, and outcome_at.
10. Recompute qub_id from the decrypted fields, sealed drand_round, and title;
    require it to equal the carried qub_id (§4.1).
11. If sig_alg != 0x00, verify the V2 author signature (§9.4). If cosigner
    fields are present, verify their pairing, key separation, and signature
    (§9.7).
12. For an existence-time claim, independently verify either:
    a. the permanent-storage transaction's data-to-id binding, owner, block
       inclusion, and block timestamp; or
    b. a §16 inclusion proof through its pinned anchor and anchor block time.
13. Report each verified claim separately; do not collapse an absent storage
    or anchor proof into a successful timing verdict.

Mit bizonyít az ellenőrzés:

Bizonyítási bemenet Mit állapít meg
Érvényes csomag / lepecsételt műtárgy + drand-aláírás A visszanyert törzs megfelel a body_hash értékének; a qub_id-ba kötött metaadatok sértetlenek; a titkosított szöveg a kijelölt drand-körhöz kötött; és a kör eltelt. Ez nem állapítja meg, mikor hozták létre a titkosított szöveget.
Érvényes V2 szerzői/társaláírói aláírás A megfelelő titkos kulcs(ok) birtokosa(i) hitelesítették a §9.3 aláírt felületét.
Függetlenül ellenőrzött qubonkénti tárolási tranzakció A pontosan tárolt titkosított szöveg legkésőbb a blokk időbélyegének idején létezett.
Érvényes lehorgonyzott átláthatósági napló bizonyíték A §16.11 levéltípus-specifikus állítása, beleértve a kötelezettségvállalási idő felső korlátját a horgonyblokkból.

Mit NEM bizonyít az ellenőrzés:

Nem-bizonyíték Miért
Szerzőség A sender_label dekoratív. sig_alg ≥ 0x01 nélkül bárki lezárhatta volna ezt a tartalmat.
Szándék A műtárgy bájtokat és kriptográfiai kapcsolatokat bizonyít, nem azt, amit az alkotó szubjektíven gondolt.
Előzetes kötelezettségvállalás csak a .qub csomagból Egy alkotó a kötött kör eltelte után is összeállíthat érvényes csomagot. A beágyazott drand-aláírás a kör elteltét, nem a titkosított szöveg korábbi létezését bizonyítja.
A pecsételőgomb pontos ideje A tárolási vagy horgonyblokk időbélyege függetlenül ellenőrizhető felső korlát, és késhet a felhasználó helyi műveletéhez képest. A sealed_at / received_at állítások nem bizonyító erejűek.

A megvalósított átláthatósági napló (§16) qubokon átívelően hamisítás-érzékeny sorrendet és megbízható harmadik fél nélküli felső korlátú kötelezettségvállalási időt (a horgonyblokk idejét) ad hozzá, a levél típusa szerint hatókörözve (§16.11). Nem ad hozzá szerzőséget vagy szándékot; az alapértelmezett bájtvak feltöltési útvonalon önmagában nem bizonyítja a body_hash vagy drand_round értékét, amelyek továbbra is a műtárgy ellenőrzéseiből származnak.


12. Verziókezelés és kiadásvezérlés

A dokumentumkiadások, a belső wire-protokoll és a külső burkoló külön verziótér. Így egy csak dokumentációs pontosítás nem változtatja meg észrevétlenül a bájtokat, egy jövőbeli wire-migráció pedig nem álcázhatja magát szerkesztési változtatásnak.

12.1 Dokumentumkiadás verziója

Ez a specifikáció szemantikus dokumentumkiadásokat (MAJOR.MINOR.PATCH) és protocol-v<release> nevű megváltoztathatatlan Git-címkét használ.

A kiadási állapot Tervezet (még nem normatív), Aktuális (az egyetlen ajánlott megvalósítási cél) vagy Felváltott (történeti ellenőrzés céljából megőrzött). A verzió nélküli /protokoll útvonal az Aktuális kiadást jeleníti meg; a kiadási címke megőrzi annak pontos forrását és minden vele kiadott területi változatot. Az állapot vagy a kiadási szám módosításához ugyanabban a felülvizsgált változtatásban frissíteni kell ezt a táblázatot és a kiadástörténetet.

Dokumentumkiadás Hatálybalépés dátuma Állapot Wire-protokoll Burkoló Forrás
1.0.0 2026-09-23 Aktuális 0x01 0x01 protocol-v1.0.0

12.2 Protokollverzió

A version mező (u8) mind a SealedQub-ban, mind a QubEnvelope-ban a fő protokollverziót azonosítja.

12.3 Protokollverzió-történet

Verzió Érték Leírás
v1 0x01 Privát/burkolt és nyilvános/csupasz kézbesítés; szöveges (0x01), paktum- (0x03) és ítélet- (0x04) törzsek; ML-DSA-65 V2 szerzői/társaláírói aláírás; drand quicknet tlock; SHA3-256.

12.4 Előrekompatibilitás

Egy v1-megjelenítőnek, amely ismeretlen CBOR-térképkulcsokat (a §3.2 kanonikus sorrendjében nem szereplő kulcsokat) tartalmazó QubEnvelope-ba ütközik, dekódolási hibával el KELL utasítania azt (§3.1). Az előrekompatibilitás a version mezőn nyugszik, nem a kulcsok tolerálásán: a jövőbeli kiegészítések — még a kisebb metaadatok is — új version érték alatt jelennek meg, amelyet egy v1-megjelenítő egyértelmű „újabb protokoll” hibával utasít el, ahelyett hogy csendben eldobná azt a tartalmat, amelyhez az aláírások kötelezik magukat.

Egy v1-megjelenítőnek, amely sig_alg = 0x01 (ML-DSA-65) értékbe ütközik, de hiányzik az ML-DSA-65 ellenőrzési támogatása, a qub-tartalmat „aláírás jelen van, de nem ellenőrizhető” megjegyzéssel KELLENE megjelenítenie, nem pedig a qubot teljesen elutasítania. A referencia-megvalósítás ma minden sig_alg értéket elutasít a 0x00 és 0x01 kivételével, mert a v1 nyilvántartás nem tartalmaz más érvényes algoritmust — a szigorú elutasítás és a lágy hiba megfigyelhetően azonosak, amíg egy harmadik algoritmus regisztrálásra nem kerül. A fenti lágy-hiba viselkedés akkor válik teherviselővé, amikor a §9.2 új bejegyzést fogad be, és a referencia-megjelenítő ezen a ponton frissül lágy-hibára.

12.5 Külső burkoló verziója

A §13-ban leírt OuterWrapper saját version bájtot hordoz, függetlenül a SealedQub.version és QubEnvelope.version mezőktől. A két verziótér külön fejlődik: egy jövőbeli posztkvantum-biztonságos szimmetrikus csere megemeli a burkoló bájtját anélkül, hogy a belső protokollverziót érintené, és egy jövőbeli protokollréteg-kiegészítés (pl. egy új borítékmező) megemeli a belső verziót anélkül, hogy a burkoló bájtját érintené.

OUTER_WRAPPER_VERSION_* Érték Algoritmus Állapot
OUTER_WRAPPER_VERSION_1 0x01 AES-256-GCM 12 bájtos nonce-szal, 16 bájtos hitelesítési címkével, a qub_id-hoz kötött AAD-vel Aktív privát kézbesítéshez
— 0x02–0xFF Fenntartott Jövőbeli

A megjelenítőknek el KELL utasítaniuk az ismeretlen burkoló-verziókat egyértelmű hibával. A protokoll szándékosan szűken tartja a burkoló-verzióteret, amíg egy konkrét migrációs hajtóerő meg nem jelenik (pl. egy másik AEAD-et előnyben részesítő NIST-irányelv); egy 0x02 hely ugyanabban a felülvizsgálatban kerül kiosztásra, amely bevezeti az algoritmust.


13. Külső titkosító burkoló

13.1 Indoklás

A protokollrétegek (QubEnvelope → tlock → SealedQub) időzárolttá teszik a lezárt qubot: a törzs olvashatatlan az unlock_at-ig, és amíg a drand-kör aláírása közzétételre nem kerül. A feloldás után azonban a kör aláírása nyilvános, és a SealedQub kanonikus CBOR-alakja felismerhető, így egy gyűjtő, aki indexelte az állandó tárhelyű tranzakciókat, tömegesen visszafejthetné az egész qub-korpuszt.

Privát kézbesítésnél a külső titkosító burkoló egy további szimmetrikus AEAD-réteget iktat a kanonikus SealedQubCbor és a tárolt bájtok közé. A böngészős pecsételési útvonalon a 256 bites K kulcs kizárólag a kézbesítési URL töredékében és a felhasználói eszközökön él; a böngészők nem továbbítják az URL-töredékeket a szervereknek, így a qub.social, minden tárolási átjáró és minden CDN bármelyikük előtt nem látja K-t. Egy privát qub tárolt alakja ezért átlátszatlan titkosított szöveg, amelynek nyílt szövege az alkotó által megosztott URL nélkül nem nyerhető vissza. A nyilvános kézbesítés szándékosan elhagyja ezt a réteget (§13.8).

Nettó hatás:

13.2 Rétegezés

plaintext body                       ← QubEnvelope.body (§2.2)
  ↓ canonical CBOR (§3)
envelope CBOR
  ↓ tlock encrypt to drand round (§7 step 10)
tlock_ciphertext (inside SealedQub) (§2.3)
  ↓ canonical CBOR (§3)
SealedQubCbor bytes                  ← inner wire artifact
  ├─ public (visibility=0x01) ───────────────▶ stored directly (§13.8)
  └─ private (visibility=0x00)
       ↓ AES-256-GCM(K, nonce, AAD=qub_id) (§7 step 12, this section)
     OuterWrapper CBOR bytes         ← stored private payload

A lezárás és feloldás a protokollrétegen (§7, §8) változatlan a burkoló-határ alatt; a burkoló a seal() hívási helyén csatlakozik, és az unlock() hívási helyén válik le.

13.3 OuterWrapper adatstruktúra

struct OuterWrapper {
    version:    u8,           // 0x01, see §12.5
    qub_id:     [u8; 32],     // copied from inner SealedQub; AEAD AAD
    nonce:      [u8; 12],     // 96-bit AEAD nonce
    ciphertext: Vec<u8>,      // AES-256-GCM(K, nonce, SealedQubCbor, AAD=qub_id) || 16-byte tag
}

Mező-invariánsok.

CBOR-kódolás. Kanonikus CBOR a §3 szerint, ugyanazzal a kulcsrendezési szabállyal (kódolt bájthossz szerint növekvően rendezve, majd lexikografikusan). A négy kulcs:

Kulcs Kódolt bájtok Sorrend
nonce 6 1
qub_id 7 2
version 8 3
ciphertext 11 4

Az OuterWrapper CBOR első bájtja tehát egy 4 bejegyzéses térkép határozott hosszúságú térképfejléce (0xA4).

13.4 AAD-kötés a qub_id-hoz

A burkoló a qub_id-t AEAD kiegészítő hitelesített adatként köti. Ez a teherviselő szerkezeti védelem három támadásosztály ellen:

Támadás Védelem
A rejtjelezett szöveg áthelyezése egy másik qub_id mező alá a burkolóban AAD-eltérés → az AEAD-hitelesítés meghiúsul
Az A qub URL-fragmentjének keverése a B qub tárolt bájtjaival Hibás kulcs (és ettől függetlenül kötött AAD) → az AEAD-hitelesítés meghiúsul
A burkoló qub_id mezőjének meghamisítása a feltöltés után AAD-eltérés → az AEAD-hitelesítés meghiúsul

A qub_id burkoló egyszerű szövegében való hordozása nem gyengíti érdemben a felsorolás-immunitást — a qub_id maga is a §4.1 bemeneti kép SHA3-256 kivonata, a kivonatból nem visszanyerhető bemeneti képpel, és egy felsoroló, aki már begyűjtötte a burkoló bájtjait, semmi olyat nem tanul a látható qub_id-ból, amit ne tudna kikövetkeztetni magának a feltöltésnek a létezéséből.

13.5 Becsomagolási és kicsomagolási algoritmusok

wrap_sealed_qub(SealedQubCbor S, qub_id Q, key K, nonce N):
    require K.len() == 32 and N.len() == 12 and Q.len() == 32
    I := canonical_cbor_decode(S) as SealedQub
    require I.qub_id == Q               // reject mismatched caller AAD
    C := AES_256_GCM_encrypt(key=K, nonce=N, msg=S, aad=Q)
    // C includes the 16-byte authentication tag at the end
    return canonical_cbor_encode(OuterWrapper{
        version:    0x01,
        qub_id:     Q,
        nonce:      N,
        ciphertext: C,
    })

unwrap_sealed_qub(OuterWrapper bytes W, key K):
    require K.len() == 32
    O := canonical_cbor_decode(W) as OuterWrapper
    require O.version == 0x01           // §12.5
    P := AES_256_GCM_decrypt(
            key=K, nonce=O.nonce, ciphertext=O.ciphertext, aad=O.qub_id
         )
    // any AEAD failure → DECRYPT_FAILED, indistinguishable to caller
    S := canonical_cbor_decode(P) as SealedQub
    require S.qub_id == O.qub_id       // explicit inner/outer cross-check
    return P                            // P is the validated SealedQubCbor

Hibamód-összeomlás. A rossz K, a rossz nonce, az AAD-eltérés és a meghamisított rejtjelezett szöveg mind ugyanazt a DECRYPT_FAILED hibát eredményezi. Ez szándékos AEAD-tulajdonság: a hibamód megkülönböztetése oldalcsatornát hozna létre, amelyet egy távoli támadó hibás formátumú burkolók küldésével és a válasz időzítésével vizsgálhatna. A referencia-megvalósításoknak minden AEAD-hibát egyetlen hibaalakra KELL összeomlasztaniuk.

13.6 Kulcsanyag és terjesztés

A becsomagoló K kulcs egy 256 bites egyenletes véletlen érték, amelyet qubonként generál egy CSPRNG. A referencia-megvalósítások az alábbiakból nyerik:

Terjesztés: a K mezőt URL-biztonságos base64-ként KELL kódolni (RFC 4648 §5, kitöltés nélkül), és a kézbesítési URL-hez fragmentkomponensként hozzáfűzni:

delivery_url = <origin>/c/<arweave_tx_id>#<base64url(K)>

A fragmentet egy megfelelő böngésző soha nem továbbítja egyetlen szervernek sem. Azok a helyreállítási csatornák (szerveroldali előzményindex, választható e-mailes automatikus küldés), amelyek a teljes kézbesítési URL-t — beleértve a fragmentet — a felhasználó eszközén túl megőrzik, kifejezett kompromisszum az alapértelmezett kripto-aprítási tartással szemben, és kifejezett felhasználói beleegyezéshez KELL kötni őket.

Fragmentvesztés. Ha egy felhasználó elveszíti az URL-fragmentet, és nincs helyreállítási csatornája, a qub olvashatatlan. Ez a tervezés teherviselő kompromisszuma, és a lezárás idején KÖZÖLNI KELL a felhasználóval. Az MVP megerősíti a lezárás-idejű közlést kifejezett „mentse el ezt az URL-t” szöveggel és egy ellenőrzött e-mailes helyreállítási csatornával azoknak a felhasználóknak, akik ezt választják.

13.7 A szakasz hatókörén kívül

13.8 Nyilvános qubok (a burkoló elhagyása)

A külső burkoló a kézbesítési rétegen választható. Egy alkotó nyilvánosként is lepecsételhet egy qubot, amely esetben a kanonikus SealedQubCbor közvetlenül lép be a tárolási folyamatba, OuterWrapper réteg és K kulcs nélkül:

SealedQubCbor bytes  ──(public)──▶  stored as-is
SealedQubCbor bytes  ──(private)─▶  AES-256-GCM(K, …) ▶ OuterWrapper ▶ stored

Egy nyilvános qub időzárolt, de nincs hivatkozással kapuzva: olvashatatlan marad, amíg a drand-köre közzétételre nem kerül (a tlock-réteg változatlan), de a feloldás után bárki vissza tudja fejteni, akinek megvan a tárolási tranzakció azonosítója — nincs szükség URL-fragmentre, mert nincs K. Ez a szándékos kompromisszum azokhoz a felületekhez, amelyeket a szervernek kell működtetnie: a felfedés-értesítő e-mailekhez, a fragment nélküli oEmbed/automatikus beágyazási hivatkozásokhoz és a gazdagabb felfedés utáni SEO-hoz olyan hivatkozás kell, amely a szerver által soha nem birtokolt titok nélkül működik (§13.6). Egy privát qub továbbra is használhatja a kifejezett <qub-embed src="full_delivery_url"> alakot, ha a közzétevő megadja a fragmentet tartalmazó teljes képességét.

Következmények, amelyekkel egy előállítónak SZÁMOLNIA KELL:

A privát (becsomagolt) marad az alapértelmezett; a nyilvános kifejezett, qubonkénti alkotói választás.


14. Tesztvektorok

14.1 qub_id levezetése

Input:
  version      = 0x01
  content_type = 0x01
  created_at   = 1735689600 (2025-01-01 00:00:00 UTC)
  unlock_at    = 1736294400 (2025-01-08 00:00:00 UTC)
  outcome_at   = absent
  drand_round  = 4695446  (= floor((1736294400 - 1595431050) / 30) + 1, §4.3 mapping, drand mainnet params §14.2)
  body         = "Hello, future."  (UTF-8, 14 bytes)
  title        = absent

Intermediate:
  body_hash  = SHA3-256("Hello, future.")
             = 76ab8b3f843c6ed4f2d0fd75b9f457b4
               ad49dd4450f9c22723ae430e3af3211d
  title_hash = [0u8; 32]   (title absent — §4.2.1 sentinel)

Domain separator (10 bytes):
  [0x51, 0x55, 0x42, 0x5F, 0x49, 0x44, 0x5F, 0x56, 0x32, 0x00]

Preimage (108 bytes—current protocol v1):
  domain_separator    ||  // 10 bytes
  0x01                ||  // version
  0x01                ||  // content_type
  0x0000000067748580  ||  // created_at as i64 big-endian (1735689600)
  0x00000000677DC000  ||  // unlock_at as i64 big-endian (1736294400)
  0x0000000000000000  ||  // outcome_at_or_zero (outcome_at absent)
  0x000000000047A596  ||  // drand_round as u64 big-endian (4695446)
  body_hash           ||  // 32 bytes
  title_hash              // 32 bytes (all-zeros sentinel; title absent)

Expected output:
  qub_id = SHA3-256(preimage)
         = 4a84e3dfaec32954949c30073f8e6506
           fd3204c1bb97f9162b81c7587afe412e

Az implementációknak ehhez a bemenethez azonos body_hash és qub_id értékeket KELL előállítaniuk. Ezt a tesztvektort érdemes első egységtesztként megírni. A fenti kanonikus értékeket a referencia-megvalósítás számította ki, és bitről bitre egyezniük KELL. A történeti, kiadás előtti prototípus-elrendezések (az első kettőtől egyetlen élő qub sem függött) 92 bájtot használtak az outcome_at előtt (3d9fc2390eab043d38a1669ed3b71be76f9eefe872b9569ab1aaa027b88392b0), majd 100 bájtot az outcome_at_or_zero hozzáadása után (b0d032898ad629795150fdcb3f84e518f59ed05b7a2a82bc24ebdb87f52144ed). A jelenlegi 108 bájtos elrendezés ezután hozzáadta a drand_round mezőt és a QUB_ID_V2 tartományelválasztót. Egy korai 108 bájtos vektor a régi ceil körleképezést (drand_round = 4695445) használta, és 3a9fcb31b750d985c262fada6d4f777fd6a28be831d941d85c131f5a4bbaf8a4 értéket adott — ez továbbra is érvényes qub_id ahhoz a körbemenethez, míg a fenti példa a §4.3 jelenlegi körleképezését követi.

14.2 Feloldási kör leképezése

Input:
  unlock_at           = 1735689600
  chain_genesis_time  = 1595431050
  chain_period_seconds = 30

Calculation:
  (1735689600 - 1595431050) / 30 = 4675285.0
  floor(4675285.0) + 1 = 4675286

drand_round = 4675286

A 4675286. kör a 1595431050 + (4675286 - 1) * 30 = 1735689600 időpontban jelenik meg — pontosan az unlock_at időpontban, sosem előtte. (A régi, kiadás előtti ceil leképezés 4675285-öt adott, amely 1735689570 időpontban, 30 másodperccel korábban jelent meg; az ellenőrzők a §4.3 szerint elfogadják ezt a régi kört.)

14.3 Kanonikus CBOR oda-vissza

A megvalósításoknak ellenőrizniük KELL, hogy a serialize(parse(serialize(qub))) == serialize(qub) minden érvényes bemenetre. Ez tulajdonságteszt, nem egyetlen vektor.

14.4 PactTerms CBOR (content_type 0x03)

Input:
  pact_version = 1
  title        = "Scooter deposit"
  terms        = [
    { key: "Item",    value: "Honda Metropolitan scooter" },
    { key: "Price",   value: "$100" },
    { key: "Deposit", value: "$10" }
  ]
  party_a      = { label: "Alice" }
  party_b      = { label: "Bob", contact: "bob@example.com" }
  notes        = absent

Canonical CBOR key order (PactTerms):
  "notes"(6) < "terms"(6) < "title"(6) < "party_a"(8) < "party_b"(8) < "pact_version"(13)

Canonical CBOR key order (PactTerm):
  "key"(4) < "value"(6)

Canonical CBOR key order (PartyIdentifier):
  "label"(6) < "contact"(8)

A kanonikus CBOR-bájtokat és a SHA3-256 body_hash-t a referencia-megvalósítás számítja ki. A megvalósításoknak bájtazonos CBOR-t KELL előállítaniuk erre a bemenetre.

A megvalósításoknak emellett ellenőrizniük KELL, hogy a serialize(parse(serialize(pact))) == serialize(pact) minden érvényes PactTerms bemenetre (tulajdonságteszt).

14.5 Külső burkoló nyelvközi vektorok

A külső burkolónak (§13) külön kanonikus fixture-je van itt: crates/qub-core/tests/vectors/wrapper_v1.json. Minden eset egy (key, nonce, qub_id, sealed_cbor) rendezett ötöst rögzít átlátszatlan hexa-bemenetekként, és egy konkrét expected_wrapper_hex kimenetet állít. Mindkét referencia-megvalósítás ugyanazt a JSON-fájlt használja:

A fixture jelenleg három alacsony szintű burkolóesetet rögzít. Ezek a determinisztikus OuterWrapper-kódolást és az AEAD-interoperabilitást a §13.8 szerinti kézbesítési alakra vonatkozó invariánstól függetlenül tesztelik; különösen a történeti basic-text-public név és belső visibility = 0x01 értéke nem teszi az így kapott burkolt bájtokat megfelelő nyilvános kézbesítéssé. Az előállítónak továbbra is csupaszon KELL tárolnia a nyilvános belső bájtokat, és csak a privát (0x00) belső bájtokat szabad becsomagolnia.

Eset Lefedettség
basic-text-public Történeti alacsony szintű fixture-név. A legkisebb realisztikus SealedQub-alak, opcionális mezők nélkül; kizárólag a burkolóbájtokat teszteli, és nem megfelelő §13.8 szerinti tárolt kézbesítés.
with-recipient-pubkey SealedQub beállított recipient_pubkey-vel (fenntartott jövőbeli útvonal). Eltérő belső CBOR-kulcskészletet gyakorol; a fixture eltérő tartalma ettől függetlenül eltérő qub_id-t eredményez (maga a recipient_pubkey nem része a §4.1 szerinti preimage-nek).
longer-body ~4 KiB-os törzs — gyakorolja a többbájtos CBOR-hosszelőtagokat mind a belső borítékon, mind a külső rejtjelezett szövegen belül.

A megvalósításoknak bájtazonos expected_wrapper_hex-et KELL előállítaniuk a rögzített bemenetekre. A fixture újragenerálása QUB_REGEN_VECTORS=1 cargo test -p qub-core --test wrapper_vectors parancsot igényel, és szándékos formátumváltoztatásokra van fenntartva.


15. Kriptográfiai profil kormányzása (jövőbeli)

Ez a szakasz informatív a v1-re, és normatívvá válik, amikor először lép be egy második algoritmus a qub kriptográfiai alapelemeinek bármelyikébe.

15.1 Jelenlegi tartás

A v1 protokoll alapelemenként pontosan egy algoritmust köt:

Az ellenőrzők jelenleg keményen kódolják az aktív primitívek kulcs- és aláíráshosszait. A sig_alg és a burkolóverzió bájtjai kifejezett választók, de a v1 nem végez sávon belüli egyeztetést, és csak a fenti aktív értékeket fogadja el.

15.2 Tervezett alak

Amikor egy második algoritmus belép a protokollba, az ellenőrző egy elnevezett CryptoProfile-hoz (pl. ExqubV1) lesz konfigurálva, amely felsorolja az alapelemenként engedélyezett értékek pontos halmazát — sig_alg-ek, drand-láncok, burkoló-verziók, tartalomtípusok. A profil az ellenőrzés idején rögzül, soha nincs sávon belül egyeztetve. Az aktív profilon kívüli bármely érték elutasításra kerül.

Ez garantálja, hogy az ML-DSA-87 hozzáadása vagy az Ed25519 aktiválása nem gyengítheti visszamenőlegesen a meglévő ellenőrző-konfigurációkat: egy v1-ellenőrző v1-ellenőrző marad még egy v2-profil közzététele után is.

15.3 Kiváltó feltételek

Léptesse elő a §15-öt normatív státuszra, amikor az alábbiak bármelyike javaslatra kerül:

Addig a §15 helykitöltő, amely rögzíti a migrációs alakot, hogy a jövőbeli PR-ek ismert célpontra érkezzenek, ahelyett, hogy a tárgyalási felületet a nulláról újratárgyalnák.


16. Átláthatósági napló és tartóssági szintek (Megvalósítva — értékelés befejezve)

Állapot. Ez a szakasz implementált (W5/UP-B1, 1–8. szakasz), itt van megadva a producer és a trust root hatótávolsága. A vezeték formátumok, a hashing és az ellenőrjáratok élő: a mag Merkle + kanonikus-CBOR típusok (qub-core), a TypeScript tükör + ANS-104 bundler (workers/api/src/crypto/), az egyíró LogDO + koordináta kulcsú R2 csomópont tároló, az /upload log-append kísérlet, a napi horgony + bundler-drain cronok, a GET /api/v1/qub/:tx_id/proof (inkluzió) és GET /api/v1/log/consistency (RFC 9162) bizonyítási végpontok, a .qub csomagban hordozott típusos befogadási bizonyítás (§17.5), a natív ANS-104 anchor verifiert (tools/qub-verify), valamint a dupla önkiadott-fejes hookot (§16.6). Egy sikeres /upload mindig R2-tartós, de csak akkor van log-lefedett, ha LOG_DO be van állítva, és az inline append sikeres lesz; csak ekkor viszi a válasza log_seq, receipt és anchor_status. Ha RECEIPT_SK hiányzik vagy érvénytelen, az a visszaigazolás sig_b64url üres, és nem ad visszautasítást. A jelenlegi /seal és pakt közzétételi útvonalak az egyes Arweave tranzakciókat ütemezik, de nem csatolnak naplólevelet. Jelenleg egyetlen kód hajtja végre a /upload kommentár által javasolt későbbi egyeztetést egy kiegészítő hiba után. A W5 külső felülvizsgálata befejeződött: a §16.15 rögzíti a tervezési döntéseket és a indítási korlátozásokat, de ezek a korlátozások nem bővítik a gyártó lefedettségét. Három bizalmi/telepítési elem zárt marad: (a) a dedikált anchor wallet (ANCHOR_JWK; LogProfile.anchor_owner továbbra is a [0xAB; 32] helykitöltő; (b) a visszaigazolási kulcs és a hozzá tartozó nyilvános kulcs pin (RECEIPT_SK opcionális, LogProfile.receipt_pubkey jelenleg üres); és (c) az önkiadott fejű GitHub tároló + token (§16.6). Amíg a anchor/profile pineket nem biztosítják, egy önálló ellenőrző őszintén jelenti a bizonyítási státuszt, ahelyett, hogy teljesen rögzített, rögzített ellenőrzést igényelne. A kialakítás szigorúan additív, és nincs változás a SealedQub / QubEnvelope vezeték formátumban.

16.1 Indoklás és tartóssági szintek

A jelenlegi közzétételi útvonalak elválasztják az elismerést az Arweave megerősítéstől: egyedi tranzakciót vezetnek és írnak alá, megőrzik az artefaktut és pontos beküldési állapotot az R2-ben, majd aszinkron módon posztolnak. Az átláthatósági napló egy önállóan rögzített sorrendi réteget ad hozzá az általános /upload kérések részhalmazához, amelynek LogDO kiegészítése sikeres:

Szint Név Garancia Mikor
T1 R2-első szinkron visszaigazolás Tartóssági minimum — a lezárt bájtokat és a pontos közzétételi állapotot tartós tárolóba írják, mielőtt a siker visszaigazolást visszaadják. Megvalósítva a jelenlegi közzétételi útvonalakon.
T2 Csomagolt átláthatósági naplóba való felvétel Csak hozzáfűzhető, manipulációt jelző kötelezettségvállalás + teljes rendezés egyszer, amikor beillesztik és horgonyozzák. Jelenlegi előállító: sikeres LogDO hozzáfűzések a /upload; a válasz a nyugtázó tuple-t hordozza. Nem univerzális.
T3 Qubonkénti Arweave állandóság Egyéni Arweave tranzakció a qub számára. Jelenleg minden elfogadott közzétételhez előkészítve és aszinkron módon közzétéve; a pontos aláírt tranzakció a kiüríthető kimenő postaládában marad, amíg kézbesítésre nem kerül.

A szintek különböző bizonyíték- és tartóssági tulajdonságokat írnak le, nem a jelenlegi kereskedelmi tervet. A jelenlegi kód továbbra is minden elfogadott közzétételhez ütemez egy egyéni Arweave tranzakciót; nem teszi elérhetővé a T3-at csupán fizetős kiegészítésként. Az API-kulcs/fiók kvóta plafonjai továbbra is külön alkalmazásvezérlők.

Tartóssági becsület. A T1 írás szinkron, így a sikeres válasz az alkalmazásszintű tartósságot garantálja anélkül, hogy várni kellene az Arweave átjáróra. Önmagában nem állít fel független időbélyeget. Egy megerősített egyéni tranzakció biztosítja a blokkidő felső határát. Egy teljes T2 nyugtázó tuple-t hordozó válasz esetén a következő megerősített horgony biztosíthatja az alább leírt napló bizonyítékot. Ha a tuple hiányzik, semmi sem sugallhatja, hogy ez a qub már az átláthatósági naplóban van. A horgony- és közzétételi késleltetésnek nincs protokoll szintű numerikus SLA-ja.

16.2 LogLeaf struktúra (két kötelezett forma)

Egy naplóbejegyzés egy LogLeaf, amely kézzel írott kanonikus CBOR-ként van kódolva a §3.1 profil szerint (határozott hosszúság, nincs címke, nincs lebegőpontos szám, rövid formátumú egész számok, NFC szöveg, az opcionális mezők hiány esetén elhagyva, a kulcsok kódolt bájthossz szerinti növekvő sorrendben, majd bájtonként rendezve). A §3.1 parse → re-encode → compare kanonikus őr alkalmazásra kerül a kódolás során, a hash-elés előtt (nem csak a dekódálásnál), így két implementáció nem térhet el a levélbájtoknál egész szám szélesség vagy kulcsrendi különbség miatt. Minden egész szám u8 / u64 / i64; minden digest 32 bájtos bájt-sorozat (bstr[32]). Egy tárolt Arweave tranzakció azonosító nyers 32 bájtos SHA-256 digestként jelenik meg bstr[32]-ként, soha nem base64url szövegként (a §3.3-mal összhangban).

A levélnek két formája van, amelyet egy kind bájt választ ki, mert az általános feltöltési útvonal bájtfüggetlen: POST /api/v1/upload szándékosan mindkét elfogadott adatforma opaque-ként kezeli, és qub_id-t és unlock_at-t csak nem megbízható kliensi állításokként fogad el. Az alapértelmezett privát útvonalon, body_hash, drand_round, created_at és drand_chain_version továbbiakban a §13 külső burkolaton belül vannak elrejtve, amelynek kulcsát a Worker soha nem birtokolja. A típus rendszer meghatározza továbbá az attesztált formát egy előállítóra, aki maga származtat body_hash / drand_round-t. A jelenlegi /seal útvonal ezeket az értékeket tartalmazza, de nem hívja meg LogDO-t, így a gyártás jelenleg csak állított (0x02) leveleket bocsát ki a sikeres általános feltöltési kiterjesztésekből. A szétválasztás minden rögzített értéket őszintén tart anélkül, hogy az attesztált előállítót bekapcsoltnak tételezné.

kulcs enc. len típus jelenlét jelentés
seq 4 u64 szükséges globális 0-alapú levélindex; az a pozíció, amelyhez az inklektív bizonyítás elköteleződik.
kind 5 u8 0x01 igazolt (defintál, jelenleg nem kibocsátott) vagy 0x02 állítás (kliens-pecsét/bájtvak feltöltés) szükséges.
ref 4. bstr[32] szükséges Leaf referenciaazonosító. Bizonyítva → nyers qub_id. A vakított azonosító → SHA3-256(qub_id ‖ log_blind_secret) (§16.2.1) állították.
chash 6 bstr[32] Tartalom címe SHA3-256(stored_bytes) — az egyetlen tartalomkötés, amit a Munkás mindig őszintén ki tud számolni, mindkét úton.
unlock_at 10 i64 szükséges Másolt (igazolt) vagy állított (állítva); > 0 igazolva, mielőtt belép a levélbe.
received_at 12 i64 szükséges Worker falóra-óra R2-ack-nél. Nem bizonyíték (operátor által állított; §16.6). Önleíráshoz való jelenlét, soha nem bizonyíték. Hitelesített > 0.
body_hash 10 bstr[32] kind=0x01 csak hagyta ki 0x02 — a Munkás nem rendelkezik a 13. § alapján.
drand_round 12 u64 kind=0x01 csak hagyták ki a 0x02-n.

Egy kind=0x02 levél szándékosan nem követi el sem body_hash, sem drand_round: igazolja egy átlátszatlan titkosított szöveg elköteleződését és rendezését a chash tartalomcímen, állítása qub_id és unlock_at — nem a tiszta szöveg vagy a kör. Az állított qub tiszta szöveg/kör lábai a meglévő §11 .qub-csomagos ellenőrzésből származnak, nem a naplóból (§16.11). drand_chain_version nincs a levélben (az alapértelmezett úton a csomagolásban van); a lánc granularitása a horgonyonyon él (§16.7). Kódoló fegyelem: elutasítsd az all-zero ref vagy chash-et, és elutasítsd a nem pozitív unlock_at / received_at-et, ami tükrözi a outcome_at > 0 sentinel guardot cbor.rs-ben.

16.2.1 Magán-qub vakítás

A napló nem válhat azzá az enumerációs orákulumba, amelyet a §13 külső csomagolás megakadályozni akar (§13.1). Egy privát (becsomagolt) qub esetén a asserted levél megköti a vakított azonosítót SHA3-256(qub_id ‖ log_blind_secret), ahol log_blind_secret szerver által őrzött titkos, és kihagyja a body_hash. Egy harmadik fél nem kötheti az ilyen levelet egy adott qub_id-hez; a qub tulajdonosa, akinek a szállítási URL-je van, így qub_id, újraszámolhatja a vakot, hogy megerősítse saját bevonását. Egy nyilvános qub (már felsorolható, már a §13.8 szerinti Visibility: public Arweave címkét viseli) elvégzi a nyers qub_id. Ez az egyetlen hely, ahol az önálló ellenőrizhetőség szándékosan enged egy terhvivő adatvédelmi invariánsnak; a magán qub-ok önálló köteléke chash (§16.9).

log_blind_secret őrzetesség (megoldva — §16.15 Q4). A vak védi levél összekapcsolhatóságát, nem a tiszta szöveges titoktartást (a §13 csomagolás ezt függetlenül tartja). Egy log_blind_secret kompromisszum esetén, bármely qub_id esetén az ellenfél már birtokolja vagy képes rekonstruálni (minden qub, amelynek csomagja/URL-je van, plusz bármilyen alacsony entrópiás vagy nyilvános qub_id), újraszámolja a ref levelet egy hash** formátumban és összekapcsolja — ez egy ismert populáció közvetlen összekapcsolása, nem egy ismeretlen tér feletti erőszak. Osztályozzuk log_blind_secret korrelációs/Sybil-szintű titkosnak ugyanabban a felügyeleti szintben, mint más szerver titkok, és csak előre forgatni (a rotáció újravakítja a jövőbeli leveleket; nem tudja utólag lekapcsolni a már rögzített leveleket).

16.3 Levél- és csomópont-hashing

RFC 6962 §2.1 tartomány-szétválasztott hashelés, SHA-256 helyett SHA3-256-tal helyettesítve:

leaf_hash      = SHA3-256(0x00 || canonical_cbor(LogLeaf))
node_hash(l,r) = SHA3-256(0x01 || l || r)
empty tree     = SHA3-256("")          // defined but never anchored

A 0x02 (entry chain, §16.4) és 0x03 (STH hash, §16.6) tartomány előtagok ezekből külön és különállóak. Egyetlen bájt, így nem ütközhetnek a meglévő 10 bájtos ASCII tartományelválasztókkal (QUB_ID_V2 stb.). A fa az RFC 6962 left-full, kiegyensúlyozatlan fa (minden belső oldal két legnagyobb, szigorúan kevesebb, mint az alfa levélszám), amely lehetővé teszi, hogy a befogadás és konzisztencia bizonyításai egy audit-út algoritmusban használják. A referenciaspecifikáció explicit bal/jobb levezetési pszeudokódot hordoz, és egy nem két-ható (5 leveles) tesztvektort rögzít, így a jobb szélű előléptetési esetet — amelyet egy 4leveles vektor elrejt — alkalmazzák.

16.4 Hash láncolás (internal)

A LogDO belső bejegyzési láncot tart fenn kizárólag a crash-konzisztens érdekében. Ez soha nem jelenik meg, és soha nem is ellenőrzőhöz:

entry_chain[seq] = SHA3-256(0x02 || entry_chain[seq-1] || leaf_hash[seq])
entry_chain[-1]  = SHA3-256("QUB_TLOG_GENESIS_V1")

A közzétett csak kiegészítő hatóság a kumulatív Merkle gyökér + annak horgonya (§16.5–16.6), soha nem az a nyers sorrend, amelyben az operátor a leveleket szolgálja: a lánc bármely szolgált sorrendre újraszámol, így csak a rögzített gyökér rögzíti a kanonikus pozíciót.

16.5 Összesített Merklefa és köteges

Van egy folyamatosan növekvő RFC 6962 fa az összes levél felett seq sorrendben — nem külön tételenkénti fák. (A carry-leaf-chained per batch konstrukciót elutasították: nem valódi előtag reláció, így a "konzisztencia bizonyításai" nem megbízható.) Az összesebb fa valódi RFC 9162 konzisztencia bizonyításokat ad, és lehetővé teszi, hogy egyetlen friss horgony bizonyítsa a befogadást bármely régebbi qub esetén.

A LogDO Tartós Objektum az egyetlen író (blockConcurrencyWhile, QuotaDO / EntitlementDO tükrözi) — a megosztott naplóhoz hozzáadva olvasás-módosítás-írás közös állapotban történik, ezért KELL DO-n keresztülmenni, soha KV-n. Gyorsítótárban tárolja a fa jobb szélének határát (O(log n) hash-eket), így a kötet lezárása O(batch). A batch a levelek összefüggő halmaza; a megvalósított triggerei legalább tree_size előrelépés LOG_BATCH_MAX_LEAVES-vel (alapértelmezett 4096), az életkor elérése a horgonyritmushoz, vagy egy explicit adminisztratív / cron kényszerítő lezárás. root_i a Merkle fa hasa a 0 .. tree_size_i levelek felett összegző összesített hasa.

16.6 Aláírt Tree Head az Arweave Anchoron keresztül

Az Arweave anchor tranzakció az az Aláírt Fafej, és helyettesíti egy operátor aláírást magának a fafejnek: a napi horgonynak nincs szüksége qub kulcsra, mert az Arweave tx owner az aláírás. A vizesárok tézis igaz — a megváltoztathatatlan alap, nem egy qub-által őrzött titk, terhelő a rögzített gyökér számára.

A naplótervezés egy meleg, sikeres csatolású fogadó kulcs (§16.10) igényli, amelyet LogProfile-ben rögzítettek és anchor_owner keresztaláír. A jelenlegi megvalósítás nem fejezte be ezt a bizalmi gyökér kijelölést: RECEIPT_SK opcionális, hiányzó/érvénytelen kulcs sig_b64url: "" ad, és a lefordított LogProfile.receipt_pubkey üres. Egy ilyen visszaigazolás leírhatja az csatolt levelet, de nem nem megérdőjelezhető aláírt blokk. Az erősebb tervezési igény csak akkor érvényes, ha egy ellenőrségi kiadás kitűzi a megfelelő nyilvános kulcsot, és a horgony tulajdonosa keresztaláírja. Egy teljes fogadó tuple nélküli publikációs válasz nem tesz napló-elfogadási állítást; egy üres aláírással rendelkező válasz csatolás-pozíció igényt tesz, de nincs aláírás-ellenőrzési igény.

A SignedTreeHead kanonikus CBOR (kulcsok kódolt hossz szerint): size:u64, root:bstr[32], batch:u64, prev:bstr[32] (sth_hash előtt; genesis = 32 nulla bájt), log_id:bstr[32], first_seq:u64, anchored_at:i64. Hashje sth_hash = SHA3-256(0x03 || canonical_cbor(SignedTreeHead)).

Rögzített megbízhatósági gyökér. log_id = SHA3-256("QUB_TLOG_V1" || anchor_owner_address). Egy megfelelő ellenőrzőnek KÖTELEZŐ igényelnie a anchor_tx.owner == LogProfile.anchor_owner-et, ahol a anchor_owner (és a nyugtakulcs nyilvános kulcsa) be van égetve a qub_core-be LogProfile-ként — a gyorshálózati állandók mellett, amelyek már benne vannak a DrandTimelockProvider::quicknet()-ben — és distribúcióra kerül az ellenőrző binárisával. Az ellenőrző KÖTELEZŐEN ellenőriznie kell az Arweave tranzakció adat → tx_id kötést helyben, a HTTP gateway /raw/ válaszában való megbízás helyett. Ez zárja a kártevő tárcákkal való kettős mérce hézagát: az „Arweave-ra horgonyozva” jelentés nélküli, amíg az ellenőrző nem tűzi ki, melyik tárca.

A forgatás a §15 irányítási kiterjesztés, nem újrahasználat (megoldva — §16.15 Q3). A §15.2 profilfelület jelenleg csak sig_algs / drand láncok / wrapper verziók / tartalomtípusok felsorolását tartalmazza, és a §15.3 kiváltólistája egyiket sem — a LogProfile / anchor_owner még nincs a §15 felületén. A forgatás irányítása ezért ki kell építeni: a §15.3 kiterjesztésre kerül (lent) a LogProfile kiváltó hozzáadásával, és a forgatás egy aláírt LogProfile emelés, amelyet az ellenőrző frissítése tartalmaz. Egy tervezett forgatás tartalmaz egy kilépő → belépő keresztaláírást; egy meghibásodásból eredő forgatás nem tudja (a kilépő kulcs ekkor megbízhatatlan/ nem elérhető), és visszatér a §15 által irányított emeléshez, a korábbi horgony elágazás-ellenőrzéssel (lent), amely ideiglenesen korlátozza a kárt.

Kettős mérce ablak (elsőrendű megbízhatósági paraméter). Egy levél csak akkor ellenáll a kettős mércézésnek, ha a lefedő horgonya Arweave-megerősített. Az ablak received_at → anchor confirmation (ritmus + Arweave véglegesség, protokoll-latencia garancia nélkül). A megbízhatósági gyökér biztosítása előtt a jelenlegi implementáció az üzemeltetési integritást (qub) nyújtja, plusz az összes aláíratlan hozzáfűzött metaadatot; nem nyújtja a tervezett tagadhatatlansági garanciát. Három elszámoltathatósági tárgy definiálja a kifejlesztett tervet (a tanú modell a §16.15 Q2 megoldása):

  1. Pecsét-fogadó (provisioning-függő) — az SCT analóg visszatér, amikor a feltöltés napló kiegészítése sikeres lesz (§16.10). Csak akkor válik visszautasításhatatlanná, ha sig_b64url nem üres és a megfelelő nyilvános kulcs/horgony-tulajdonos kapcsolat a hitelesítésben van rögzítve. A jelenleg üres gyártási profil tű nem támasztja alá ezt az ítéletet. Ez a kontroll nem vonatkozik kihagyott visszaigazolási tupléra vagy aláíratlan nyugtakra.
  2. Publikált monitor módszertan + előzetes lánc sétá — a lánc prev horgonyja a "walked head→genesis"; a vila (két horgony egy size különböző root vagy egy törött prev) publikálható bizonyíték a visszaélésre. Az kétértelműség felismerése egy kifejezett operatív elkötelezettség, nem egy néma feltételezés.
  3. Kettős önkiadott fej — minden új fej {sth_hash, tree_size} egy dediktált, qub tulajdonában lévő nyilvános, csak csatolható GitHub repozióriumba (a terhelő, manipuláló önkiadási rész) közzétételére kerül ki, a közösségi bejegyzés pedig csak a legjobb megerősítés érdekében. Egy sikertelen közzététel KÖTELEZŐ oldal (nem fail silent). *Megvalósítva (8. szakasz) a publishHead horogként a horgony a cronon (workers/api/src/utils/heads-publish.ts): a tartalom API-jának PUT sha nélkül csak kiegészítésre alkalmas (a 422 azt jelenti, hogy a fej már közzé van adva, soha nem felülírás); opt-in / deploy-kapus PUBLISH_HEAD_GITHUB_{TOKEN,OWNER,REPO}-en és inert addig, amíg a tároló kialakítódik. Egy kemény GitHub hiba a health_alert csatornán keresztül oldalaz, és egy tartós hiba metrikát (m:tlog_publish_head_fail) érint; maga az Arweave anchor soha nem görgeti vissza a közzétételi hibát. A "nem hibás hangtalanság" garantált az a tartós metrika — amelyen az operátoroknak KÖTELEZŐ dashboard-riasztást kell adniuk — még akkor is, ha a legjobb erőfeszítésű e-mail oldal nem érkezik meg. Két őszinte korlát van a "anchor-on-advance" (a cron csak a méret növekedése után jelenik meg): egy átmeneti GitHub-hiba *rést hagy a publikált fejek sorozatában ebben a méretben — korlátozott, nem néma (oldala), és mivel minden fej egy szuperset fát köt, egy §16.9 konzisztencia bizonyítás hidalja át a szakadékot; lényeges, hogy ez a konzisztencia bizonyítása a tekintélyes Arweave-által rögzített fából számítanak, nem a GitHub felületéről, így a GitHub rés sosem gyengíti az ellenőrizhetőséget. Egy felzárkózó visszatöltés, amely kitölti a publikált fejek hiányosságait, egy halasztott fejlesztés.

**Őszinteséghez kötött (kötelező korlátozás). ** Mivel a qub mindkét tervezett közzétételi felületet ellenőrzi, ez önkiadás, nem önállóan tanús. Egyetlen termék, marketing vagy jogi felület sem állíthatja, hogy a napló "önállóan tanús". Miután a belépő/profil/fejkapuk kibiztosították, az engedélyezett állítás, hogy kétértelműség észlelhető, és egy sikeresen aláírt csatolás nem visszavonható blokkát hagy hátra. Addig ez a igény nem elérhető. Egy valódi független harmadik fél tanút egy jövőbeli §15 kormányzati átállásra kerül.

received_at operátor által állított, és semmilyen igény nem támaszkodhat rá — soha nem jelenik meg bizonyítékként vagy vita megerősítésként semmilyen terméken, jogi / API-n / bizonyítási felületen. Az Arweave anchor block time T az egyetlen bizalmatlan időbélyeg (egy felső határ a "loged" alatt). Bármely monitor józan ész ellenőrzése received_at-on KELL összehasonlítania T-vel, nem az operátor által irányított anchored_at STH mezővel; ilyen ellenőrzés csak egy tisztességes operátor óra-hibája ellen véd, nem egy rosszindulatú operátor elleni elszámoltathatósági vezérlés (§16.15 Q5).

16.7 Anchor tranzakció formátuma és ritmusa

A AnchorBundle a kanonikus-CBOR Arweave tranzakció teste, amelyet a §16.8 bundlerrel írnak: ver:u8, sth:bstr (kanonikus SignedTreeHead bájt), prev_anchor:bstr (korábbi anchor tx id nyers bájt; a genesisnél kihagyva), chain_hash:tstr (a drand lánc érvényben — quicknet), és a batch levél-CBOR áramlata seq sorrendben, így a horgony önálló: egy monitor újra levezeti root a nulla qub-függőségű testből. (Ha a levélfolyam nagy volumenben nagyra válik, egy jövőbeli változat csak egy levéltartományt alkalmazhat referencia alapján; megjegyezve, nem alkalmazták az 1. v1-ben.)

Az Arweave címkék szándékosan megszámlálhatók — a napló megtalálható eredetű, ellentétben a privát qubokkal: App-Name: qub-tlog, Anchor-Format: 1, Log-Id: <hex>, Batch: <n>, Tree-Size: <n>, Root: <hex>, Prev-Anchor: <tx>, Content-Type: application/cbor. A címkék megbízhatatlan tippek; a CBOR test az egyetlen hatóság.

Cadence: alapértelmezett naponta, újra megnézve a volumengel (a méret trigger automatikusan rövidíti az effektív ritmust terhelés alatt). A jelenlegi gyártó nem vezet be fizetett zárás-erőhorgonyhorgot. A horgonytárca dedikált és alacsony sebességű, különálló a feltöltési pénztárcától — KÖTELEZŐEN saját JWK-nak kell lennie (egy különálló kulcs, nem logikus szerep a feltöltési tárcán), így a feltöltés-tárca kompromisszum nem tud hamisítani horgongot — kemény napi horgony-tranzakciós költségvetéssel. A lekezelő pozíció egyértelműen megfogalmazódik: egy szűk hatótávolságú gyorsbillentyű szoros megszakítóval és alacsony egyenleggel, nem "hideg" — egy olyan tárca, amely naponta automatikusan aláír, nem lehet hideg, és a specifikáció nem állít mást.

16.8 ANS-104 Bundler

Egy házon belüli ANS-104 DataItem kódoló és mély-hash aláíró, körülbelül 300 sor, Csak Web Crypto, nulla npm függőség (mindkét Turbo SDK nem teljesíti a npm ci --ignore-scripts ellátási lánc kapuját). DataItem bájt elrendezés:

signatureType (2, LE) || raw_signature || owner || target(flag+0|32) || anchor(flag+0|32) || num_tags(8, LE) || tags_len(8, LE) || avro_tags || data

Az aláírás Arweave deepHash — egy rekurzív SHA-384 digest (Arweave vezeték követelménye, crypto.subtle.digest("SHA-384")) ["dataitem", "1", sig_type, owner, target, anchor, encoded_tags, data] felett — majd RSA-PSS a mély hash-en keresztül a JWK tárcával crypto.subtle-n keresztül; id = base64url(SHA-256(signature)). A SHA-384 itt Arweave-wire primitívként karanténban van, soha nem qub trust primitív (§15 rögzíti a kerítést; qub trust hashing SHA3-256 végig).

Az ANS-104 kódút a halasztott tartalék/leszívó gépezetet szolgálja, és AnchorBundle DataItems gépet ír. A hagyományos közzétételi útvonal először egy pontos aláírt Arweave tranzakciót hoz létre, és a JSON-ját tartós kimenődobozban tartja; a közvetlen közzététel késleltetésoptimalizálás, és a drain path ugyanazt a tranzakciót próbálja újra, mielőtt alkalmazná a bundler tartalékot. Aláírási séma (megoldott — §16.15 Q8): v1 RSA-PSS-szel (aláírás típus 1) a meglévő Arweave pénztárca JWK mechanizmus újrahasznosítása (nulla új, hosszú életű kulcsőrző, a "egy kevesebb titok" tézist szolgálva); Az Ed25519 a §15 PQ-migrációs útra van áthelyezve.

A kézzel tekert deep hash a W5 legmagasabb kockázatú, legalacsonyabb természetes lefedettségi kódja, így a gating nem tárgyalható (§16.15 Q8):

  1. A nyelvközi tlog_v1.json rögzítés (Rust + TS, a §14.5 wrapper_v1.json minta) lefedi a mély hash-t, a DataItem bájtjait + azonosítóját, a levél hash-eket, egy 5 leveles gyökeret + audit útvonalat, egy STH hash-t, egy befogadási igazolást és egy konzisztencia igazolást — mind a aláírási, mind az ellenőrzési irányban (az ellenőrzési irány fontos, mert §16.6 helyi tx → tx_id ellenőrzés a mély hash-t minden önálló ellenőrzőbe beemeli, nem csak az íróba).
  2. Egy egyszeri interoperabilitási oda-vissza út egy referencia ANS-104 csomagolóval, csak statikus tesztadatként felhasználva — soha nem npm futási függőségként (a kizárólag Web-Crypto / nincs telepítési szkriptek hozzáállás érvényben marad).
  3. A mély hash + RSA-PSS útvonalnak végig kell mennie a ugyanazon crypto.subtle primitíveken a termelésben, így a házon belüli kódoló bájtközi kompatibilis.
  4. A folyamatban lévő post-csomag elfogadási monitor megerősíti, hogy minden anchor / fallback DataItem valójában eléri az Arweave elfogadást, riasztással + áramkör-kikapcsolóval — mert a mély hash az Arweave-hiányosságok pótló sorát is szolgálja, így egy néma visszaesés a hálózattól elutasított elemekkel töltené fel azt a sorozatot a pontos kimaradás idején, amit le kell fednie.

16.9 Befogadási és Konzisztencia Igazolások

Mindkettő RFC 9162, SHA3-256, kanonikus CBOR formátumban szolgáltatva.

InclusionProof — GET /api/v1/qub/:tx_id/proof: ver:u8, leaf:bstr (a pontos levél CBOR — az ellenőrző magától számítja újra a leaf_hash-t, és soha nem bízik egy megadott hash-ben), index:u64, size:u64, audit:[bstr[32]], root:bstr[32], anchor:{ txid:bstr[32], batch:u64, sth:bstr[32], log_id:bstr[32], block_height?:u64, anchored_at?:i64 }.

ConsistencyProof — GET /api/v1/log/consistency?first=<size_a>&second=<size_b>: ver:u8, first_size:u64, second_size:u64, first_root:bstr[32], second_root:bstr[32], nodes:[bstr[32]], first_anchor, second_anchor. Egyetlen egyértelmű kulcslista, tesztvektorral rögzítve.

Önálló ellenőrzés (qub szerver nélkül, kiterjeszti a §11-et):

1.  Parse .qub bundle → SealedQub; recompute qub_id (§4.1).
2.  Read leaf.kind.
3a. kind=0x01 (attested):
      assert leaf.ref == qub_id
      assert leaf.body_hash   == SHA3-256(body)
      assert leaf.drand_round == unlock_round(unlock_at)
3b. kind=0x02 (asserted):
      assert leaf.ref == SHA3-256(qub_id || blind)   // holder supplies blind
      OR treat ref as opaque and bind via leaf.chash == SHA3-256(stored_bytes)
4.  Recompute leaf_hash = SHA3-256(0x00 || leaf); fold `audit` per RFC 6962
    using index/size; require derived root == proof.root.
5.  Fetch anchor.txid from any gateway; verify the tx data → tx_id binding
    (do not trust a gateway /raw/ response); REQUIRE anchor_tx.owner ==
    LogProfile.anchor_owner.
6.  Parse AnchorBundle; require committed root == proof.root and size ==
    proof.size; read the Arweave block time T.
7.  Emit the claim scoped by leaf.kind (§16.11).

A proof-service tárolónak KELL koordináta kulcsolással (megoldott — §16.15 Q7, előfeltétel blokkolása). A hideg levél bizonyítás generálása helyesség-semleges csak akkor, aki** az R2 audit anyag egy tartós Merkle-csomópont tároló, amelyet abszolút fa koordináta (level, index) kulcsolt — nem batch csomópontonkénti delta. Koordináta kulcsos tárolóval bármely (leaf i, size N) audit útvonal O(log N) közvetlen R2 GET halmaza, amelyekben nincs újraszámítás a batch határain át; egy batch-key tárolónál nem, ami az a tároló-elrendezési rés, amelyet ez a felbontás bezár. A levéltestek is seq által tartalmi címezhetőek is. Egy W5 tesztvektornak bizonyítania kell egy genesis korszakbeli hideg levelet egy sokkal későbbi gyökérrel szemben, csak R2 + Arweave-vel, a LogDO tároló törlésével, így a §16.13-ban szereplő reclamation-safety állítás inkább alátámasztható, mint kiállított. A O(log N) szekvenciális R2 GET csak aszinkron bizonyítási végponton találhatók — soha nem a seal hot path-on (§16.10) vagy egy tick-en-tick cron-on.

16.10 R2-első Ack sorrend

A megvalósított POST /api/v1/upload sorozat a következő:

  1. Első félkapuk (auth, validáció, idempotencia szilánkulcs) — változatlan.
  2. Hozd létre, címkézze és írja alá pontosan az egyes Arweave tranzakciót. Ez helyben vezeti tx_id, bár a tranzakció létrehozása letöltheti a jutalma/horgonymetaadatokat egy átjáróból. Egy előkészítő hiba még mindig meghiúsítja a kérést a visszaigazolás előtt.
  3. Szinkron írja le a kiválasztott artefaktumot qub-cache/<tx_id>-nél, és persistente a stabil létrehozási/kimeneti rekordokat. Ezek a tartósság és újrapróbálkozás szintje; kudarcok a 503-as elszámolás előtt.
  4. Amikor LOG_DO be van állítva, szinkron próbálkozása LogDO.append(leaf). Az egyetlen író seq rendeli hozzá, meghosszabbítja a bejegyzési láncot, és frissíti a határt. Az append RPC csak ezt teszi; a batch close lefut a riasztáson. Az append transport/application hiba jelenleg fail-soft: a válasz még mindig sikeres lehet log_seq, receipt vagy anchor_status nélkül. A megvalósítási megjegyzés ellenére ma nincs automatikus későbbi naplóegyeztetés.
  5. Visszaküldje a visszaigazolást. Csak akkor tüntesse fel { log_seq, anchor_status: "pending", receipt }, amikor a kiegészített teljes sikeres tuple-t küldte vissza. receipt.sig_b64url üres, amikor a fogadó aláíró nem elérhető; az ügyfelek NEM nevezhetik ezt az értéket aláírtnak vagy nem visszavonhatónak. A tuple hiánya csak tartós közzétételt jelent, nem pedig átlátszósági napló elfogadást.
  6. Használj egy halasztott feladatot a pontos aláírt tranzakció közzétételére. Siker eltávolítja a kimenetet; a kudarc a korlátolt leszívó cronra kerül, és nem változtathatja meg a már elismert tx_id. Az ideiglenes metaadatok és más legjobb oldalkartok is halasztottak.

Késleltetési határ. A kérés útvonala tartalmazza az első felében történő hatósági/kvóta munkát, tranzakció előkészítést/aláírást, tartós R2 írásokat, és (ha konfigurált) a LogDO próbálkozást. A < 300 ms a tervezési felülvizsgálatban operatív célnak jelenik meg, nem pedig protokollgaranciának; a jelenlegi tranzakció-előkészítési lépés végezhet átjáró metaadat-kérést. A késleltetési riasztások és indítási kapuk operatív ellenőrzések, nem pedig a hitelesítő számára rendelkezésre álló bizonyítékok.

16.11 Bizalmi modell — a pontos állítás, levél típus által korlátozva

A kind=0x01 (tanúsított) esetén: „Ez a tartalom — test megegyezve a body_hash-szel, azonosítva a qub_id által — rögzítésre került a qub hozzáfűző logjában a seq pozíciónál, és legkésőbb az Arweave blokk időpontjáig T létezett; kriptográfiailag olvashatatlan volt a drand kör előtt R = unlock_round(unlock_at).” Ez a teljes {tlock round binding + Merkle inclusion + anchored root} hármas.

A kind=0x02 (állított, alapértelmezett) esetén: „Egy átlátszatlan titkosított szöveg a chash tartalom-címmel, igényelve qub_id és unlock_at, rögzítésre került a hozzáfűző logban a seq pozíciónál, és legkésőbb az Arweave blokk időpontjáig T létezett.” A kör- és test részeket a meglévő §11 .qub-csomag ellenőrzés (qub_core::unlock) szolgáltatja, nem a log; amit a log hozzáad egy puszta qub-tranzakcióhoz, az a beavatkozás-észlelhető sorrendiség, a bizalom nélküli felső határ elkötelezés ideje, és az ellentmondás-ellenállás.

Mindkét állítás kizárja a §11 alapján: szerzőség sig_alg ≥ 0x01 nélkül, szándék, és rész-anker granuláris időzítés. Egyik sem engedi, hogy bármely állítás a received_at-ra támaszkodjon.

Állítási plafon (kötő indítási korlátozás — megoldva §16.15 Q1). Egy állított (kind=0x02) levél esetén a fenti korlátozott állítás a plafon arra vonatkozóan, amit bármely termék, marketing, feltételek, vagy bizonyítási felület állíthat. Egyetlen felület sem állíthatja vagy sugallhatja, hogy a log bizonyítja a tartalmat vagy egy bájt-süket feltöltés feloldási körét — a log bizonyítja a sorrendet + egy bizalom nélküli felső határ elkötelezés idejét egy átlátszatlan titkosított szövegnél. A tartalom- és kör bizonyítás kizárólag a meglévő §11 .qub-csomag ellenőrzésből származik, ami független a logtól. Egy publikáció, amely sikertelen hozzáfűzéssel/átvétellel rendelkezik, egyáltalán nem rendelkezik log-állítással.

16.12 Verziózás és W3 koordináció

Nincs SealedQub vezeték-bump, így nincs protokoll-verzió bump (§12.2): a napló egy sidecar, amely a meglévő mezők és bájtok mellett köteleződik, így nem lép be a §12.3 protokollverzió történetébe. W3 opcionális drand_chain_version érintetlen, és továbbra is az egyetlen opcionális SealedQub mező. A napló ehelyett saját független verziótereket vezet be — LOG_VERSION_1, ANCHOR_FORMAT_1, InclusionProof.ver —, amelyek tükrözik a §12.5 wrapper-verzió függetlenségét (a burkoló verzió bájtját hordozza a protokoll verziójától, és a napló verziók ugyanazt a szétválasztást követik).

A bizonyítás átadása alapértelmezettben előhívható, opcionális egy kísérőúttal. Bizonyítás nem létezhet pecsétidőpontban (a horgonyt még nem írták meg), így a pecsét-idő .qub csomag bizonyítékmentes marad. W7 ellenőrzője egyszer hívja GET …/proof-ot, vagy teljesen offline módban rekonstruálja a bizonyítást a nyilvános AnchorBundle Arweave lekérdezéssel az Log-Id-n. A .qub csomag (W7) egy **opcionális inclusion_proof tagot tart fenn — amely a pecsétnél hiányzik, és egy horgonyutáni újraexporttal töltve fel hideg archív céljából — ugyanazt a "opcionális, alapértelmezetten kihagyott, additív" mintát követve, mint a W3 drand_chain_version-je.

16.13 Megtartás

A LogDO nyitott farok, az R2 bizonyító aljzat, a horgony megszakító számlálói és a bundler tartalék sorának megtartási ablakai docs/DATA-RETENTION.md-ben vannak megadva. Elv: a napló forró bejegyzésenkénti tárolása (LogDO) visszafoglalható a rögzítés után; az audit anyaga — a koordinátakulcsos (level, index) Merkle-csomópont tároló + az seq-címzett levéltest (§16.9) + az Arweave horgonyok — végleges. Ha egy hideg levél visszaszerzi a DO-tól, soha nem érvényteleníti a kiadott bizonyítást, mert a bizonyítás ellen oldódik az állandó R2 csomópont tárolóval és az Arweave angonyával, nem a DO-val (és ezt bizonyítja a §16.9 törölt DO tesztvektor).

16.14 Tesztvektorok

A W5 tartalmazza a keresztnyelvi fixtúrát tlog_v1.json (§16.8) plusz a munkás vektorokat: egy kind=0x01 és egy kind=0x02 levél → leaf_hash; az 5 leveles kumulatív gyökeret; egy bevonási bizonyítást; egy konzisztencia bizonyítást; egy AnchorBundle; és egy DataItem azonosítót. Ezek a §14.5 külső csomagolási vektorokkal együtt működnek, és mind a Rust (qub-core), mind a TypeScript (Worker) implementációk alkalmazzák őket.

16.15 Felülvizsgálati döntések (W5 — elzárva)

A W5 külső felülvizsgálata (ellenséges tervezési engedély + tulajdonosi jóváhagyás) befejeződött. Minden alábbi döntés elzáródott és tükröződik a fenti §16 szövegben; a kötelező indítási korlátokat a végén újra megfogalmazzuk. A megvalósítás ezek alapján folytatódhat.

  1. Alapértelmezett út (kind=0x02) levél őszinteség — MEGOLDVA. Küldjük a kétleveles felosztást a megadott módon: kind=0x02 sem body_hash, sem drand_round nem követ el. Nincs *_body_hash mező a bájtvak úton (ez lenne a legolvashatóbb hamis "ellenőrizett" jel az integrátorok számára, és a §11 már biztosít kényelmet a csomagból). Ne ne kell szerverpecsétet naplóval igazolt qub-okhoz (ami a tiszta szöveget kényszerítené a Munkáson, és megsemmisítené a kripto-szétszóró árkot). Bármilyen önmagát leíró rövidzárlat a .qub csomag / proof borítékba tartozik, mint egy ellenőriző által újrakiszámított mező, soha nem levélmező. Tulajdonos által megerősített igény plafonja: §16.11.

  2. Kétértelműség / elhagyás felelősségvállalása — TERVEZÉS MEGOLDVA, PROVISIONING HIÁNYOS. A tervezéshez a pecsét-visszaigazolási kulcsot LogProfile-ben kell rögzíteni, és anchor_owner keresztaláírja, valamint monitorozó módszertant, korábbi lánc sétát és kettős önkiadott fejet. A lefordított profil és telepítési hookok továbbra is helykitöltők/opcionálisak, ahogy azt a §16.6 részletezte, így a erősebb észlelhető + megvett állítás nem érvényes, amíg ezek a kapuk be nem záródnak. Sosem szabad függetlenül tanúként reklámozni. Egy valódi harmadik fél tanút egy §15-ös irányítási bumpra utal.

  3. Rögzített horgony-tulajdonosi bizalmi root + rotáció — MEGOLDVA. Fogadd be a LogProfile pint (§16.6); az ellenőrző ellenőrzi anchor_tx.owner == anchor_owner és ellenőrizi a tx adatokat → tx_id helyben kötést. A rotációs irányítás egy §15 kiterjesztés a buildhez (§15.3 trigger hozzáadva), nem újrahasználat; a tervezett rotációk keresztjelet mutatnak, kompromisszum-alapú rotációk visszaesnek a §15-ös bumphoz, ahol a fork check határolja a kárt.

  4. Privát-qub levélvakítás — MEGOLDVA. Fenntartsd a vakozást privát qub-oknál (ref = SHA3-256(qub_id ‖ log_blind_secret)), a nyers qub_id a nyilvános qub-oknál (már §16.2.1), chash önálló kötelékként. log_blind_secret korreláció/Sybil-fokozatú titkos, csak forgatás előre (§16.2.1).

  5. received_at — ELDÖNTVE. Tartsd a levélben, elkötelezett, de kifejezetten nem bizonyítékként; soha nem jelent meg bizonyítékként vagy vitató megerősítésként egyetlen felületen. Bármely monitor józan ész ellenőrzése összehasonlítja az Arweave blokkidő T-vel, nem a kezelő által vezérelt anchored_at (§16.6).

  6. Fokozatos bizonyítható időzítés — TERVEZÉSI FELBONTÁS, NEM AKTUÁLIS ÚTVONAL. Az átvizsgált terv a kötött szinthez a horgonyblokk időzítést rendeli, a fizetett T3-hoz pedig pontos óra-bizonyítást, az előbbihez pedig nincs numerikus SLA. A jelenlegi útvonalak nem rögzítették ezt a kereskedelmi megkülönböztetést: minden elfogadott kiadványhoz egyéni tranzakciót ütemeznek, és a napló lefedettsége feltételes marad, ahogy azt a §16.1/§16.10 is előírja. A termékmásolat a megvalósítást kell leírnia, nem ezt a jövőbeli szintfelosztást.

  7. Kumulatív fa a Munkásokon — MEGOLDVA. Egyetlen kumulatív RFC 9162 fa + határmentesen gyorsítótárazott egy-író LogDO (kényelmes tartalék a ~1k írás/sec DO plafonhoz képest; a shard-gyökerek Merkle-elosztását halasszuk a határhoz közel). A koordináta-kulcsos (level, index) R2 csomópont-tár + törölt-DO hideg-levél tesztvektor megvalósítva (§16.9). < 300 ms továbbra is tervezési/működési cél, nem protokoll ígéret (§16.10).

  8. ANS-104 aláírási séma + mély-hash — MEGOLDVA. RSA-PSS (aláírás típus 1, a dedikált anchor-wallet JWK újrahasználatával); Ed25519 későbbre halasztva a §15 PQ úton. A kézzel készített SHA-384 mély hash a kétirányú cross-impl rögzítőre, egy statikus-only referencia-bundler interoperabilitási ellenőrzésre, a shared-crypto.subtle oda-vissza útra, és a csomag utáni Arweave-elfogadási monitorra van kötve (§16.8).

Kötődik indítási korlátokhoz (végrehajtásba és termék/jogi felülvizsgálatba átvinni):


17. Hordozható ellenőrzési csomag (.qub)

Állapot. Ez a szakasz megvalósítva (W7 / UP-C2): a qub_core::export előállítja és elemzi a csomagot, a tools/qub-verify pedig nyilvános, önálló CLI, amely offline ellenőrzi. A §11 és §16.9 már „.qub csomagként” hivatkozik arra az egységre, amelyet egy önálló ellenőrző felhasznál; ez a szakasz meghatározza a bájtjait és az ellenőrzési menetet. Szigorúan kiegészítő — a csomag a meglévő §11 bemeneteket foglalja össze, és nem változtat semmilyen láncon lévő wire-formátumon.

17.1 Cél

A §11 megállapítja, hogy bármely harmadik fél a qub együttműködése nélkül ellenőrizheti egy qub kriptográfiai műtárgyát. A .qub csomag ezt az ellenőrzést hordozhatóvá és offline-ná teszi: a lepecsételt CBOR-t és az azt feloldó drand-kör aláírását egyetlen önálló műtárgyba csomagolja, így a címzett a tartalom integritását, a körhöz kötést és az esetleges szerzőségi aláírásokat minden hálózati hívás nélkül ellenőrizheti (nincs tárolási lekérés, élő drand-kérés vagy qub API). A csomag önmagában nem bizonyítja, mikor hozták létre a titkosított szöveget; ezt a külön létezésiidő-állítást függetlenül ellenőrzött tárolási tranzakció vagy lehorgonyzott naplóbizonyíték szolgáltatja (§11, §17.5).

17.2 Csomagformátum

A QubBundle kézzel írt kanonikus CBOR a §3.1 profil szerint (határozott hosszúságok, címkék és lebegőpontos számok nélkül, legrövidebb egészalakok, NFC-szöveg, a hiányzó opcionális mezők kihagyva, a kulcsok növekvő kódoltbájt-hossz, majd bájtsorrend szerint rendezve). A három 15 karakteres kulcs sorrendje d < i < s. Egy nyers .qub fájl pontosan ezekből a bájtokból áll; URL-es vagy másolás-beillesztéses szállításnál ugyanezek a bájtok base64url(no-pad) alakúak.

Kulcs Kód. hossz Típus Jelenlét Jelentés
version 8 u8 kötelező Csomagformátum verziója (0x01).
sealed_at 10 i64 opcionális Az alkotó által állított pecsételési idő (Unix-másodperc); önleíró, nem bizonyító erejű.
drand_round 12 u64 kötelező A kör, amelyhez a qub zárolva van. A beágyazott lepecsételt qub vetülete.
arweave_tx_id 14 tstr kötelező Annak a tranzakciónak az azonosítója, amely alatt a lepecsételt bájtokat tárolták (eredetmutató).
drand_chain_id 15 tstr kötelező A drand-lánc (hex). A beágyazott lepecsételt qub vetülete.
drand_signature 16 bstr kötelező A drand_round drand-beacon aláírása — a titkosított szöveget feloldó érték.
inclusion_proof 16 bstr opcionális A §16 átláthatósági napló Merkle-befoglalási bizonyítéka (§17.5).
sealed_qub_cbor 16 bstr kötelező A belső SealedQubCbor bájtjai (a §13 kicsomagolása után), vagyis a §11 ellenőrzési bemenete.

A drand_round és drand_chain_id a sealed_qub_cbor kényelmi vetületei, hogy az eszközök a belső CBOR elemzése nélkül olvashassák őket. Előállításkor levezetjük, dekódoláskor pedig újra ellenőrizzük őket az elemzett lepecsételt qubhoz képest; a felső szintű mező és a hasznos adat eltérése esetén a csomag elutasítandó. A kódolói fegyelem a wire-formátum többi részét tükrözi: az üres drand_signature vagy arweave_tx_id elutasítandó, és minden változó hosszúságú mező korlátozandó.

17.3 Mit bizonyít a beágyazott drand-aláírás

A csomag a drand-aláírást hordozza, nem követeli meg az ellenőrzőtől annak lekérését. Az időzáras visszafejtés (tlock a drand-láncon, §8) csak a kötött kör valódi beacon-aláírásával sikerülhet — ezzel az értékkel, amelyet a lánc csak a kör eltelte után tesz közzé, és amely érvényes BLS-aláírás a lánc nyilvános kulcsa alatt. A hamis vagy téves aláírás megbukik a BLS-ellenőrzésen vagy az IBE/AEAD-visszafejtésen. A sikeresen visszafejtett csomag ezért ezt bizonyítja: a titkosított szöveg az R körhöz kötött, és az R kör eltelt. Az ellenőrző rögzíti a láncot (DrandTimelockProvider::quicknet()), és alkalmazza a §11 körkötési ellenőrzését, így a csomag nem állíthat olyan kört, amelyhez a titkosított szöveg nincs kötve.

Ez felszabadításifeltétel-bizonyíték, nem létrehozási időbélyeg. Az R kör eltelte után bárki létrehozhat új titkosított szöveget R-hez, és becsomagolhatja a már nyilvános aláírást. Ezért a csomagot önmagában NEM SZABAD annak bizonyítékaként leírni, hogy a titkosított szöveg vagy tartalom R, az unlock_at vagy bármely esemény előtt létezett.

17.4 Offline ellenőrzési menet

A qub-verify <file.qub> a szabványos §11 eljárást teljesen a csomagból futtatja, a qub_core::unlock::unlock függvényt rögzített DrandTimelockProvider-rel hajtva:

1. Parse the .qub bytes → QubBundle (canonical-CBOR guard; bound every field;
   re-check drand_round / drand_chain_id against the embedded sealed qub).
2. BLS-verify bundle.drand_signature for the pinned chain and round, then
   tlock_decrypt(sealed.tlock_ciphertext, bundle.drand_signature) → QubEnvelope.
3. Verify SHA3-256(body) == body_hash               (§11 step 8).
4. Verify QubEnvelope.qub_id   == SealedQub.qub_id   (§11 step 9).
5. Verify QubEnvelope.unlock_at == SealedQub.unlock_at (§11 step 10).
6. Verify ciphertext round == unlock_round(unlock_at) and the chain binding.
7. If sig_alg != 0x00: verify author_signature (and any cosigner; §9.4).
8. Report integrity, round-elapsed/round-binding, authorship, and cosigner
   verdicts separately, plus the recovered body. Do not report a commitment
   timestamp unless step 9 succeeds.
9. Optional existence-time leg: verify an included §16 proof through its pinned
   anchor, or independently verify the referenced storage transaction. Report
   its block time as an upper bound on ciphertext existence.

A CLI 0 kóddal lép ki (ellenőrzött), 1 kóddal, ha az ellenőrzés meghiúsult — még zárolt, eltérő törzskivonat, hibás kör-/lánckötés vagy sikertelen aláírás-ellenőrzés —, illetve 2 kóddal használati hiba vagy rosszul formázott csomag esetén. A --json jelentés ugyanezeket az ítéleteket hordozza automatizáláshoz. Mivel a csomag önálló, egy harmadik félnek csak az ellenőrző crate-re (qub-core) és a CLI-re (qub-verify) van szüksége; mindkettő nyilvános és a protokoll meglévő ellenőrzési útvonalát használja — nincs egyedi kriptográfia.

17.5 Kapcsolat az átláthatósági naplóval

Az inclusion_proof opcionális hely a §16 Merkle-befoglalási bizonyítékának. A csak csomagos ellenőrzés (§17.4) teljes az integritás, a körhöz kötés / kör eltelte és az opcionális szerzőség tekintetében, de szándékosan nincs függetlenül időbélyegzett létezési állítása. Egy jelen lévő, horgonyig teljesen ellenőrzött inclusion_proof a csomagformátum verziójának módosítása nélkül hozzáadja a §16.11 levéltípus-specifikus kötelezettségvállalását és felső korlátú idejét. A hiányzó bizonyíték csak azt jelenti, hogy „nincs bizonyíték mellékelve” — nem azt, hogy „érvénytelen”, és nem feltétlenül azt, hogy „nincs lehorgonyozva”.

A referencia-megvalósításban a hely már típusos: a qub_core::export::QubBundle::inclusion_proof_typed() egy Option<InclusionProof> értéket ad vissza, amely a teljes §16.9 struktúrát (levél, auditút, lehorgonyzott gyökér és AnchorRef) ugyanazon átlátszatlan CBOR-mezőn keresztül hordozza — csomagformátum-verzió emelése nélkül. Az önálló qub-verify CLI a --anchor ágon fogyasztja; amíg a horgonypénztárca nincs kiépítve (§16, Állapot), a jelen lévő, de helykitöltő tulajdonosú bizonyítékot csak befoglalásiként, nem teljesen horgonyellenőrzöttként jelenti.