qub Protokollýsing

qub er ein protokoll fyri kryptografiskar tíðarbundnar bindingar: eitt skipan til at innsigla orð til ein framtíðardag og at prógva, tá ið tann dagurin kemur, beint hvat varð sagt og nær.

Trý grundleggjandi eind gera tað virkandi. drand er ein desentralieraður tilvildarljósvíti — avdúkingardagurin er framfylgjandi av fysikki, ikki av góðvilja nakrar parts. Varandi alment goymslupláss er eitt manipulatiónsfrítt alment goymslupláss — eingin partur kann broyta ella strika ein qub, tá ið hann er innsiglaður. ML-DSA-65 er ein post-kvantum stafrøk undirskrift — hvør qub er bundin at einum lyklapari, hvørs loyndarmál ongantíð fer frá tóleind høvundans.

Saman gera hesi grundleggjandi eind eina frágreiðing, sum er tíðarlæst, manipulatiónsávísandi og tilskrivanlig — ein kvittan, hvørs virði veksur, alt sum heimsins evni at smíða fortíðina batnar.

Restin av hesum skjali er tann normativa fyriskipanin, sum krevst fyri samvirkandi ímótkomningar.


qub Protokoll Fyriskipan

Teigur Virði
Útgáva 1.0 (protokollútgáva 0x01, ytri umbúgvingsútgáva 0x01)
Dato 2026-05-01
Støða Uppkast
Eftirkannað fram til 2026-05-01

Hetta skjalið er tann normativa protokollfyriskipanin fyri qub tíðarbundnu bindingarskipanina. Hon ásetir dátubygnaðir, raðfestingarreglur, avleiðingarformlar og verifikatiónsmannagongdir, sum krevjast fyri samvirkandi ímótkomningar.

Umfang: protokollagið er við vilja málneutralt — qub-likamið er ógjøgnumskygt reintekstur / markdown / pakt-bæti, og staðbundin framsýning er ábyrgd vísarans (qub.social vevtænasta, <qub-embed> iframe, MCP-klientar, o.s.fr.).


1. Teknleiðing og Vanir

Teknleiðing Merking
u8, u64, i64 Tekn-/tekleys heiltøl við ásettari bitabreidd
[u8; N] Fastlongdar bætibrá av N bætum
Vec<u8> Broytilig-longdar bætibrá
Option<T> Virði av slag T, ella fráverandi
String UTF-8 tekstrein, NFC-normaliserað
`
SHA3-256(x) NIST SHA3-256 stytting av bætisreini x (FIPS 202)
ceil(x) Loftfunksjón: minsta heiltal ≥ x
CBOR Concise Binary Object Representation (RFC 8949)
big-endian Mest týðandi bæti fyrst

Øll heiltøl í forímyndabygningum verða raðfest sum big-endian fastbreiddar bætibráir (i64 → 8 bæti, u8 → 1 bæti) uttan so at annað er ásett.

Øll tíðarmerki eru Unix-sekund í UTC.


2. Dátubygnaðir

2.1 ComposeQub (Skapara Innminnis-Støða)

Ikki raðfest til CBOR. Ikki skrivað til varandi goymslupláss. Staðbundið hjá skaparaappini.

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,              // 0x01 = public (only value in MVP)
    content_type:   u8,              // 0x01 = text (only value in MVP)
    plaintext:      Vec<u8>,         // UTF-8 qub body
    sender_label:   Option<String>,  // Decorative display name; not authenticated
    status:         DraftStatus,     // Composing | Sealed | Uploaded | Failed
}

2.2 QubEnvelope (Avkrypterað Nýttulast)

Raðfest við kanoniskum CBOR (§3). Krypterað innan í SealedQub. Hetta er bygnaðurin, sum prógvar innihaldsheild eftir avkryptering.

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>,     // V1.1 — when reality renders judgment (verdict-uplift-plan §3.1)
    sender_label:        Option<String>,  // Decorative; not authenticated in MVP
    reply_to:            Option<[u8; 32]>,// Parent qub_id for reply chains; not in qub_id preimage; not signed (see §9.3)
    body:                Vec<u8>,         // Content payload (UTF-8 for text, CBOR for pact)
    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
}

Grundlinja (óundirskrivaður tekst-qub): version = 0x01, content_type = 0x01, sig_alg = 0x00, allir Option-teigar fráverandi.

Aðrar v1-uppsetingar: content_type = 0x03 (pakt-likam, sí §6.1); sig_alg = 0x01 (ML-DSA-65) við author_signature og author_pubkey til staðar (sí §9.3); cosigner_pubkey og cosigner_signature til staðar saman fyri samundirskrivaðar paktir (sí §9.7); reply_to sett til foreldur-qubsins qub_id fyri svarkeðju-qubbar (sí §9.3 fyri avleiðingarnar fyri undirskriftarumfangið).

2.3 SealedQub (Kanoniskt Tráðasnið)

Raðfest við kanoniskum CBOR (§3). Skrivað til varandi goymslupláss. Hetta er á-keðju-artefaktið.

SealedQub {
    version:           u8,              // Protocol major version (0x01 for v1)
    qub_id:            [u8; 32],        // Same as QubEnvelope.qub_id
    visibility:        u8,              // 0x01 = public; v1 viewers reject other values
    unlock_at:         i64,             // Unix seconds UTC
    outcome_at:        Option<i64>,     // V1.1 — 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
    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 control characters.
}

2.4 RevealedQub (Vísara Applikatiónsstøða)

Ikki raðfest til CBOR. Staðbundið hjá vísaraappini. Bygt eftir væleydnaða avkryptering og verifikatión.

RevealedQub {
    qub_id:              [u8; 32],
    arweave_tx_id:       String,
    visibility:          u8,
    content_type:        u8,
    created_at:          i64,
    unlock_at:           i64,
    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. Kanoniska CBOR-Profilið

Øll SealedQub- og QubEnvelope-raðfesting MÁ samsvara hesum profili. Tveir ímótkomningar, sum fáa sama logiska bygnaðin, MÚGVA framleiða eins bæti.

3.1 Raðfestingarreglur

Regla Fyriskipan
Støðil RFC 8949 §4.2.1 (Core Deterministic Encoding Requirements)
Kortlyklaraðseting Raðað eftir raðfestari bætilongd fyrst (stytri fyri longri), so leksikografiskt (bæti fyri bæti fyri raðfestingar av sömu longd)
Heiltalsraðfesting Stytsta formi: 0–23 í byrjanarbæti; 24–255 í 2 bætum; 256–65535 í 3 bætum; o.s.fr.
Longdarraðfesting Bert ávísar longdir. Ongar óávísar-longdar brár, kort, bætisreinir ella tekstreinir (eyka-upplýsing = 31 er forboðin).
Tag Ongi CBOR-tag (høvuðsslag 6 er forboðið).
Flótipunkt Ongi flótitøl (høvuðsslag 7 virði 0xF9–0xFB eru forboðin).
Tekstreinir UTF-8-raðfestar, NFC-normaliseraðar (Unicode Normalization Form C).
Bætisreinir Rá bæti. Ongin base64-raðfesting á CBOR-laginum.
Tvífaldir lyklar Avvís við feili. Tólkarar MÚGVA IKKI tigandi taka ímóti tvífaldum kortlyklum.
Einføld virði Bert true (0xF5), false (0xF4) og null (0xF6) eru loyvd.
Valfríir teigar Fráverandi valfríir teigar verða slept burtur úr CBOR-kortinum heilt og holt (ikki raðfestir sum null). Tilstaðarverandi valfríir teigar verða tiknir við í raðaðari lyklaraðseting.

3.2 Verifiseraðar Kanoniskar Lyklaraðsetingar

Hesar lyklaraðsetingar eru normativar. Ímótkomningar MÚGVA senda lyklar út í júst hesi raðseting. Avlúsingar-staðfestingar EIGA at verifisera raðsetingina í ikki-útgávubygdum.

QubEnvelope (útgáva 0x01, óundirskrivaður, allir valfríir teigar fráverandi):

"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 (V1.1 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 lyklaraðsetingaravleiðing: hvør lykil er ein CBOR-tekstrein. Raðfest longd = 1 bæti høvur + reinlongd (fyri reinir undir 24 bætum). Raða eftir samlaðari raðfestari longd fyrst, so leksikografiskt fyri lyklar av sömu longd.

SealedQub (útgáva 0x01, alment, eingin móttakari):

"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 (V1.1 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)

PactTerms (pakt-likam, 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 (rað í terms-bránni):

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

PartyIdentifier (party_a / party_b kort):

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

3.3 Bætiraðfestingarúrtak

Slag CBOR-raðfesting Dømi
SHA3-256 stytting (32 bæti) 0x58 0x20 + 32 bæti body_hash, qub_id
Tíðarmerki (i64) Høvuðsslag 0 (positivt) ella 1 (negativt), stytsta raðfesting Unix-sekund
Útgáva (u8, virði 1) 0x01 (eitt bæti)
Innihaldsslag (u8, virði 1) 0x01 (eitt bæti)
sig_alg (u8, virði 0) 0x00 (eitt bæti)
ML-DSA-65 undirskrift (3.309 bæti) 0x59 0x0C 0xED + 3.309 bæti author_signature, cosigner_signature
ML-DSA-65 alment lyklað (1.952 bæti) 0x59 0x07 0xA0 + 1.952 bæti author_pubkey, cosigner_pubkey

4. Normativar Avleiðingar

4.1 qub_id

qub_id eyðmerkir ein qub einstaknliga og bindir QubEnvelope at SealedQub. Hann verður avleiddur deterministiskt úr brævainnihaldinum.

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

Økisskiljara-raðfesting: Reinurin "QUB_ID_V2" er 9 ASCII-bæti. Eitt einstakt 0x00 fyllibæti verður lagt aftanat at náa 10 bæti fyri samrøðing. Ímótkomningar MÚGVA brúka júst hesi 10 bæti: [0x51, 0x55, 0x42, 0x5F, 0x49, 0x44, 0x5F, 0x56, 0x32, 0x00].

outcome_at-raðfesting: V1.1 víðkaði forímyndina úr 92 til 100 bæti fyri at fella tann valfría outcome_at-teigin inn í bindingina. Fráverandi outcome_at verður raðfest sum 8 núll-bæti; protokoll-váttararnir avvísa outcome_at <= 0 allastaðni, so hetta varðveitslin kann ikki rekast saman við einum lógligum virði. Sí §3.2 (tráðasnið) og tað innantrægra tasks/verdict-uplift-plan.md fyri tann dóma-mekanismin, sum krevur hendan teig.

drand_round-raðfesting: V1.2 víðkaði forímyndina úr 100 til 108 bæti fyri at fella drand_round (tann ætlaða drand-rundu, §4.3) inn í bindingina, og økti økisskiljaran til QUB_ID_V2. Hetta bindur tíðarlás-rundina inn í qub-samleikan: ein gátt kann ikki binda dulorðstekstin aftur til eina aðra rundu (t.d. eina longu gingna) enn tað, sum vístu unlock_at ímplikerar. Avlæsingarprotokollurin (§8) váttar harumframt, at tann runda, sum er bakað inn í tlock-dulorðstekstins stanza, samsvarar unlock_round(unlock_at), so tann vístu avlæsingartíðin er prógvanliga tann runda, sum gáttar avkrypteringina.

Eginleikar:

4.2 body_hash

body_hash = SHA3-256(body)

Har body er tann ráa Vec<u8> innihaldsnýttulastin. Fyri tekst-qubbar er hetta tann UTF-8-raðfesta qub-likamið.

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

Har title er tað valfría reintekst-heitið, sum verður víst á vísara-niðurteljingini áðrenn avdúkingina (sí §3.2). NFC-normalisering koyrir á styttingartíðspunkti, so styttingin er støðug yvir sjónliga-javnvirði kodupunkt-raðir. Allir-núll varðveitslin er varðveitt fyri fráverandi førið; ein tómur reinur verður avvístur á kanoniska CBOR-markinum sum ein ikki-kanonisk raðfesting av "fráverandi" (tann kanoniska raðfestingin sleppir teiginum heilt burtur).

4.3 Avlæsingarrunda-Kortlegging

drand_round = ceil((unlock_at - chain_genesis_time) / chain_period_seconds)
Parametur Kelda Dømi
unlock_at Brúkara-valdar Unix-sekund UTC 1735689600 (2025-01-01 00:00:00 UTC)
chain_genesis_time drand keðju-upplýsing (genesis_time) 1595431050
chain_period_seconds drand keðju-upplýsing (period) 30

ceil()-atgerðin velur fyrstu drand-rundu, hvørs avdúkingartíð er ≥ unlock_at. Hetta tryggjar, at qub ikki verður avkrypteranligur, áðrenn tann valda avlæsingartíðin.

Útjaðaraføri: um (unlock_at - chain_genesis_time) er júst deilibart við chain_period_seconds, er úrslitið júst tann runda — qub avlæsist beint á avdúkingartíð teirrar rundu.

Vátting: unlock_at MÁ vera í framtíðini á innsiglingartíð. unlock_at MÁ IKKI vera meira enn 10 ár frá created_at (fyri at avmarka langtíðar drand-veltingarvanda; brúkaramótið EIGUR at vára fyri avlæsingardøgum lengri enn 2 ár burtur).


5. Tráðasniðs-Nýggjslag

Tráðasniðs-nýggjslag veita samanseting-tíðar trygd ímóti at blanda CBOR-bæti saman við JSON, rátt reintekst ella aðrar bætiraðfestingar.

Slag Inniheldur Framleitt av Brúkað av
SealedQubCbor Kanoniskt CBOR av SealedQub serialize_sealed_qub() Varandi-goymslupláss upphalan, vísara-heinting
QubEnvelopeCbor Kanoniskt CBOR av QubEnvelope serialize_qub_envelope() tlock-krypteringar-inntak, tlock-avkrypteringarúttak

5.1 Samanseting-Reglur

// 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 Vátting við Samanseting

from_encoded() EIGUR at vátta, at inntakið byrjar við einum gildugum CBOR-kort-høvri. Full bygnaðarvátting hendir á tólkingartíð, ikki samanseting-tíð, fyri at sleppa undan tvítólking.


6. Innihaldsslags-Skráseting

Virði Slag Mest Likamsstødd Viðmerkingar
0x00 Varðveitt (ógildugt) MÁ IKKI brúkast
0x01 Reintekstur (UTF-8, avmarkað Markdown) 50 KB rindað / 10 KB frítt Sí §10 fyri framsýningarreglur. Frítt / rindað býti verður framfylgt av upphalanartænastuni; harðtakið á protokollaginum er 50 KB.
0x02 Varðveitt (framtíðar) Tillutað fyri eitt framtíðar innihaldsslag; ikki gildugt í v1. Vísarar MÚGVA avvísa tað sambært reglini niðanfyri.
0x03 Pakt (tvíhliða semja, CBOR-likam) 100 KB Likamið er kanoniskt CBOR PactTerms (§6.1). Samundirskrivara-undirskriving sambært §9.7.

Vísarar MÚGVA avvísa ókend innihaldsslag við einum greiðum brúkara-sjónligum feili. Vísarar MÚGVA IKKI royna at framsýna ókend slag sum tekst.

6.1 Pakt-Likam (content_type = 0x03)

Eitt pakt-likam er tann kanoniska CBOR-raðfestingin av einum PactTerms-virði:

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), value: String (≤ 2,000) }   // NFC on both sides
PartyIdentifier{ label: String (≤ 100), contact: Option<String (≤ 320)> }

Kanoniskar CBOR-lyklaraðsetingar fyri øll trý kort eru givnar í §3.2. Samlað raðfest pakt-CBOR MÁ IKKI fara um 100 KB (samsvarar §6).

Skema-skiljari. Fyrsta raðin í terms fyri ein structured/v1-pakt MÁ vera { key: "pact_schema", value: "structured/v1" }. Raðir uttan hesa merking eru "egindefineraðir" paktir og fáa onga bygda vátting ella skema-vitandi framsýning.

Frystir váttanarpláss. structured/v1-paktir bera júst fýra váttanarraðir undir hesum lyklum:

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

value fyri hvønn er ein av átta frystum enskum reinum, vald av (role, kind)-parinum, har role ∈ { seller, buyer, provider, client } og kind ∈ { standard, capacity }. Sjálvir reinirnir eru normativ protokoll-dáta — báðir parta ML-DSA-65-undirskriftir binda seg at júst teimum bætum gjøgnum body_hash. Teir verða IKKI staðbundnir; tann undirskrivaða likamið er málneutralt. Onkur orðingarbroyting krevur eina nýggja skemaútgávu (structured/v2).

Teir átta reinirnir, teirra uppfletting (acknowledgement_for(role, kind)) og grundgevingin fyri hvønn eru fastsett av tilvísingar-ímótkomningini. Samsvarandi ímótkomningar MÚGVA senda út bæti-eins váttanarvirði; gulligrundar SHA3-256 likams-styttingar-roynir, sum fevna um allar fýra hlutverka-samansetingar, fanga onkra reki.

Vísara-framsýningarraðseting. Váttanarreinirnir innihalda orðingar sum "lýst omanfyri", sum áseta, at lýsingar- / umfangsraðir verða framsýndar undan váttanunum. Vísarar MÚGVA framsýna terms-bráina í CBOR-raðseting; umraðseting brýtur prosa-merkingina.

Mótpartsamband. Tá ið Parts B contact er eitt gildugt teldupost-adressu, sendir qub-upphalanartænastan sjálvvirkandi eitt eftirkanningar- / samundirskrivingar-boð á sviðstíð og bindur eventuella samundirskriving at vátting av sama adressu (§9.7). Paktir, hvørs Parts B-samband er fráverandi, kunnu framvegis verða samundirskrivaðir, men bert gjøgnum ein utanteldupost-kanal — tænastan noktar samundirskrivingar-umbønir, sum ikki kunnu framleiða eina samsvarandi 15-minuttu teldupost-váttingarmerking.

6.2 Dóma-Likam (content_type = 0x04)

Eitt dóma-likam er tann kanoniska CBOR-raðfestingin av einum VerdictBody-virði:

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; "hvat broyttist, hvat lærdi tú"
    evidence_url:    Option<String>,      // ≤ 2,048 bytes; bert HTTPS; lyklurin er fráverandi, tá hann er sleptur burtur
}

Kanonisk CBOR-lyklaraðseting:

"outcome"          (8 encoded bytes)
"reflection"       (11 encoded bytes)  ← bert um tað er til staðar
"evidence_url"     (13 encoded bytes)  ← bert um tað er til staðar
"verdict_version"  (16 encoded bytes)

Samlað raðfest dóma-CBOR MÁ IKKI fara um 8 KB (samsvarar skrásetingar-raðnum omanfyri).

Úrslits-enum. Tráðabætið er ætlanar-neutralt; teir fýra bólkarnir Right / Partial / Wrong / Unfalsifiable fevna um úrslits-rúmið hjá hvørjari dóma-berandi ætlan. Per-ætlanar-merkir ("Sá tað fyri" / "Helt tað" / "Sendi avstað" / "Vátta" fyri Right, o.s.fr.) eru ein vísara-sniðs-spurningur, ið verður loystur ímóti ætlanini hjá foreldra-qubinum — tráðurin verður mál- og ætlanar-neutralur. Virði uttan fyri 1..=4 MUGU verða avvíst í avkodingini.

Foreldra-samband. Eitt dóma-qub ber IKKI foreldra-tilvísingina í sínum likami. Arweave-veksil-eyðmerkin hjá foreldra-qubinum verður givin út sum Parent-Tx-Id-goymslumerki á upphaldsstundini (§7 goymslumerkislag). Hetta letur likamið vera eina sjálvberandi undirskrivaða lýsing av sjálvsdøming; eftirlitskeðjan ("rættur um hvat?") verður grundað við Arweave-merkis-uppfletting.

Trygd hjá vitnisburðar-URL (normativt). Tá ið evidence_url er til staðar, MUGU váttararnir (saman­seting-síðan, tráðasíðan, Worker-jaðarin) framfylgja:

  1. Bert HTTPS. Reinurin MÁ byrja við bætirøðini https://. Onkur annar háttur — http, ftp, javascript, data, file, o.s.fr. — verður avvístur.
  2. Longdarmark. ≤ 2.048 bæti (praktiska URL-mark hjá kagaranum).
  3. NFC + fíggindarliga-bætis-kanning. Sama regla sum title og reflection — bidi-yvirskriving / núll-vídd / merkis-blokkur / BOM / C0 / C1-bæti verða avvíst. Skilamarkið samsvarar Rust crate::handle::contains_hostile_text_codepoint og TS workers/api/src/utils/unicode.ts::isHostileCodepoint (haldist í takt).
  4. Onki millumrúm, ongi ASCII-stýristekn. Millumrúm / DEL / sub-0x20-bæti hvar sum helst í URL-num verða avvíst — letur niður tann \n/\t-inntrokings-vektorin, sum bidi-reglan ikki tekur við.
  5. Ikki-tómt vert-stykki. Alt millum https:// og fyrsta /, ? ella # MÁ vera ikki-tómt.

Ongin tænara-síðis heinting. Workeren MÁ IKKI fyriumboða, heinta ella framvísa URL-ina. Protokollin goymir ein streng; framsýningin hendir á vísara-síðuni við rel="nofollow noopener noreferrer" target="_blank" og einum sjónligum verti vístan saman við leinkju-tekstinum.

Umhugsan. Valfrítt umhugsanartekst skrivað av høvundinum ("hvat broyttist, hvat lærdi tú"). Sama NFC + fíggindarliga-bætis-vátting sum title. Tómt / bert-millumrúms inntak fellur saman til fráverandi á samansetingarstundini.

Skema-útgáva. v1 stuðlar bert verdict_version = 0x01. Komandi skema-broytingar økja hetta bætið og koma saman við einari nýggjari protokoll-útgávu sambært §12.


7. Innsiglingarprotokollur

Tann fullkomna innsiglingarrøðin. Hvørt stig er normativt.

 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.
 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 = ceil((unlock_at - chain_genesis_time) / chain_period_seconds).
    (Computed here, before qub_id, because drand_round is bound into the qub_id
    preimage — §4.1, V1.2.)
 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,
    unlock_at, drand_chain_id, drand_round.
12. Serialise SealedQub using canonical CBOR → SealedQubCbor.
12a. Generate K = 32 random bytes (CSPRNG) and N = 12 random bytes (CSPRNG).
     Compute W = wrap_sealed_qub(SealedQubCbor, qub_id=qub_id, key=K, nonce=N)
     per §13. The bytes uploaded to permanent storage are the OuterWrapper CBOR W,
     never the bare SealedQubCbor. K leaves the device only as the URL
     fragment in step 16.
13. Display seal-time disclosure. User confirms.
14. Validate upload eligibility via the qub upload service (bot-detection, entitlement, rate limits).
15. Submit W (the OuterWrapper bytes) to the qub upload service; the service
    signs and uploads to permanent storage. The service is byte-blind to the inner
    SealedQubCbor and never receives K.
16. Receive arweave_tx_id from the service. Construct delivery URL as
    `<origin>/c/<arweave_tx_id>#<base64url(K)>` (or `<origin>/s/<short_code>#<base64url(K)>`
    when a short code is allocated). Browsers do not transmit URL fragments
    to servers, so K is never observed by qub.social or any storage gateway.

Goymslupláss-tag-lag (utanmark). qub-upphalanartænastan leggur eitt við vilja lítið sett av goymslupláss-handilstagum afturat tann umbúgvdu nýttulastini. Content-Type=application/octet-stream er normativt kravt. Tilvísingartænastan leggur harumframt trý valfríi tag afturat, tá ið skaparin velur at vísa tey: Intent (loyvilista-váttað samansetings-ætlan — t.d., quote, reply, commitment), Author (skaparans §9.3 alment-lyklað fingramerki sum 64-tekna lágstavur hex) og Parent-Tx-Id (foreldur-qubsins goymslupláss-handilseyðmerking fyri svarkeðjur, 43-tekna base64url).

Author-tagið er valfrítt fyri hvønn qub: tilvísingar-skaparaappin leggur tað bert afturat, tá ið brúkarin uttrýkiliga loyvir alment-tilskriving á innsiglingartíð. Tá ið skiftarin er av — sum er sjálvsett — verður einki Author-tag skrivað, og qub er ótilskrivaður á keðjuni: einki í varandi goymslupláss bindur upphalanina at einum skapara handli, teldupost ella øðrum qubbum. Tá ið skiftarin er á, loysist Author-fingramerkið upp til skaparans valda @handil gjøgnum §9.5 váttanarkeðjuna. Svarkeðju-sambond og Intent eru ikki-eyðmerkjandi. Tann ytri umbúgvingin (§13) verjir innra likamið móti dulorðs-samanbinding — fyribyrgir, at ein høstari kennir og masseavkrypterar qub-laga upphalanir, eftir at teirra drand-runda verður útgivin.

Tilvísingartænastan leggur við vilja IKKI App-Name-, App-Version- ella Type-tag afturat: nakar slíkur einvirðis-filtur fór at skilað øllum qub-savninum aftur til eina GraphQL-fyrispurning, sum ikki samsvarar umbúgvingarinnar likams-bert loyndarumfang.

Ein samsvarandi verifiserari MÁ IKKI velta á nakað goymslupláss-tag fyri §11 triðjapartsverifikatión; likams-styttingin / qub_id / undirskriftin binda seg bert at innra CBOR, ongantíð at tag-settinum.


8. Avlæsingarprotokollur

Tann fullkomna avlæsingarrøðin. Hvørt stig er normativt.

 1. Viewer opens delivery URL. Extract arweave_tx_id from path AND
    K = base64url_decode(fragment) from the URL fragment. If the fragment
    is absent or malformed → display "this URL is missing its decryption
    key" and stop; the viewer MUST NOT contact the storage gateway
    without K, since fetching wrapped bytes the viewer cannot decrypt
    serves no purpose and only leaks the access attempt.
 2. Check denylist. If tx_id is denylisted → display block message. Stop.
 3. Fetch OuterWrapper bytes from permanent storage (with multi-gateway fallback).
 3a. Unwrap: parse the bytes as OuterWrapper (§13), verify the wrapper
    `version` byte is `0x01`, and compute SealedQubCbor =
    unwrap_sealed_qub(OuterWrapper, key=K). Any AEAD authentication
    failure (wrong K, tampered ciphertext, swapped qub_id-as-AAD,
    swapped nonce) → display "this URL's decryption key does not match
    the stored qub" and stop. Authentication failures are
    indistinguishable to the viewer per §13.5.
 4. Parse SealedQubCbor → SealedQub.
 5. Validate: SealedQub.version is known (0x01). Reject unknown versions.
 6. If current time < SealedQub.unlock_at → display countdown. Poll or wait.
 6a. Round-binding check (V1.2). Recompute expected_round =
    ceil((SealedQub.unlock_at - chain_genesis_time) / chain_period_seconds).
    Reject unless SealedQub.drand_round == expected_round AND the round baked
    into the tlock ciphertext stanza (read via the age/tlock header, no signature
    required) == expected_round. 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.
13. Verify: QubEnvelope.content_type is known and renderable.
    Known values: 0x01 (text), 0x03 (pact). 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 appropriate renderer (see §10 for text, §6 for pact).
17. Construct RevealedQub for display.

9. Høvundaundirskriving

9.1 Grundgeving

qubbar verða goymdir í varandi goymslupláss. Høvundaundirskriftir mugu verða ófalsanligar í alla framtíð, sum er orsøkin til, at v1.0 brúkar tað post-kvantum ML-DSA-65 skemað (FIPS 204) heldur enn eitt klassiskt skema, hvørs trygd kann minka innan qub-sins varandi lívskeið.

9.2 Algoritmu-Skráseting

sig_alg Skema Lyklastødd Undirskriftarstødd
0x00 Eingin undirskrift (óundirskrivað)
0x01 ML-DSA-65 (FIPS 204) 1.952 bæti 3.309 bæti

Vísarar MÚGVA avvísa ókend sig_alg-virði.

9.3 Undirskrivað Forímynda-Bygning

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

signature = Sign(author_secret_key, sig_input)

Økisskiljari: "QUB_AUTHOR_SIG_V1" er 17 ASCII-bæti: [0x51, 0x55, 0x42, 0x5F, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x5F, 0x53, 0x49, 0x47, 0x5F, 0x56, 0x31]. Eingin fylling.

Slóðandi bæti: tað 91. forímynda-bætið MÁ vera 0x00. Tilvísingar-ímótkomningin vísir hetta sum fastvirðið ORG_ID_PRESENT_INDIVIDUAL = 0x00 í crates/qub-core/src/signing.rs; vísarar, sum endurbyggja sig_input fyri verifikatión, MÚGVA senda út sama bæti.

Undirskriftarumfang — hvat er og er ikki fevnt. sig_input bindur seg at fýra brævateigum: version, qub_id, body_hash, unlock_at (umframt tann fasta økisskiljaran og org_id_present-bætið). Trý av hesum fýra eru bygnaðar-stødufeingi: qub_id verður sjálvur avleiddur úr version, content_type, created_at, unlock_at, outcome_at, drand_round og body_hash gjøgnum §4.1-forímyndina, so onkur broyting á hesum teigum framleiðir ein annan qub_id og gerð undirskriftina ógilduga transitivt. Tann beinleiðis-váttaða yvirvøddin er tí:

Teigur Váttaður av undirskrift Hvussu
version Beinleiðis inntak til sig_input
qub_id Beinleiðis inntak
body_hash Beinleiðis inntak
unlock_at Beinleiðis inntak
content_type Transitivt, gjøgnum qub_id-forímynd
created_at Transitivt, gjøgnum qub_id-forímynd
outcome_at Transitivt, gjøgnum qub_id-forímyndina
drand_round Transitivt, gjøgnum qub_id-forímyndina (V1.2)
body Transitivt, gjøgnum body_hash = SHA3-256(body)
author_pubkey — (undirskilt) Lykilin, sum verifiseraði undirskriftina, er høvundurin, sambært skilgreining
sender_label Bert-framsýnandi tekstur; broytiligur uttan undirskriftarbrot
reply_to Tráðingarvísir; broytiligur uttan undirskriftarbrot
cosigner_pubkey / cosigner_signature Sjálvstøðugt undirskrivað yvir sama sig_input (sí §9.7)
drand_chain_id, tlock_ciphertext, visibility Ytri SealedQub-teigar, ikki innan í brævinum — fevndir av teirra egnu bygnaðar-stødufeingjum (runda / keðju-samsvar), men ikki av høvundaundirskriftini. (drand_round er nú bundið transitivt gjøgnum qub_id-forímyndina — sí omanfyri.)

Trygdaravleiðingar av ikki-váttaðum teigum.

Ímótkomningar, sum framsýna sender_label ella reply_to fyri endabrúkarum, MÚGVA vísa tann váttaða samleikan (alment-lyklað fingramerki, váttan) sum tað fremsta samleikasignalið, ikki heitið.

9.4 Verifikatiónsmannagongd

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 (same formula as §9.3).
6. Verify(author_pubkey, sig_input, author_signature).
7. If verification succeeds → display "signed by [key fingerprint]."
8. If verification fails → display "signature verification failed."

Undirskriftarverifikatión er tann dýrasta atgerðin (serliga ML-DSA-65). Hon EIGUR at verða gjørd eftir, at allar bíligari kanningar (stytting, qub_id, unlock_at) eru væleydnaðar.

9.5 Samleika-Váttanir

Samleika-váttanir — kortleggingin av author_pubkey til mennisklig-kennaligar samleikakrøv sum eitt qub-handil, teldupostadressu, sosialt handil ella passlyklareingisbevís — eru ein vísara-síðu progressiv betran og verða ikki kravdar fyri undirskriftarverifikatión. Vísarar, sum loysa váttanir upp til ein framsýningarsamleika, MÚGVA brúka raðfestingina:

handle > email > social > fingerprint

Fingramerki-uppgávan er tann lágstavur hex av SHA3-256(author_pubkey); hon er altíð tøk fyri nakran undirskrivaðan qub. Vísarar KUNNU stytta hana fyri framsýning — tilvísingar-vísarin framsýnir qub: fylgt av tey fyrstu og tey síðstu fýra bætini (qub:<8 hex>…<8 hex>).

Ein samsvarandi verifiserari kann fullføra hvørja kanning í §9.4 uttan at samband við qub-API, uttan nakað net umframt varandi goymslupláss og drand, og uttan nakra ambætara-síðu uppfletting. Váttanarloysing er eitt skilt besta-royndar stig, sum bert verður gjørt eftir, at undirskriftarverifikatión hevur eydnast.

9.6 Støddaráhrørsla

Ed25519 ML-DSA-65
Undirskrift 64 bæti 3.309 bæti
Alment lyklað 32 bæti 1.952 bæti
Tilsamans fyri hvønn qub 96 bæti 5.261 bæti
Goymslupláss-kostnaðarmunur (við ~$5/MB) ~$0.0005 ~$0.026

Fyri ein tekst-qub av 500–2.000 bætum tríðfaldar ML-DSA-65 grovt tann goymdu støddina. Tann absoluti kostnaðurin er ómunaligur.

9.7 Samundirskrivara-Verifikatión (Pakt Tvíhliða Semjur)

Fyri tvíhliða semjur (content_type = 0x03) prógvar eitt annað undirskriftarlag, at báðir partar samtyktu somu treytir.

Brævateigar:

Báðir teigar MÚGVA vera til staðar saman ella báðir fráverandi. Um júst ein er til staðar, MÚGVA vísarar fráboða ein heildarfeil.

Verifikatiónsmannagongd:

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.
5. Verify(cosigner_pubkey, sig_input, cosigner_signature).
6. Success → display "co-signed by [cosigner fingerprint]."
7. Failure → display "co-signature verification failed."

Eginleikar:

Teldupost-bindingar-gátt (rakstrarlig). Tá ið ein sviðsettur paktur ber ein Parts B-teldupostsamband (§6.1), MÁ qub-upphalanartænastan nokta samundirskrivingar-umbønini, uttan so at ein stuttlívd teldupost-váttingarmerking finst, sum samsvarar bæði sviðsetingareyðmerkingini og normaliseraða-teldupost-styttingini av tí sambandinum. Merkingin verður skrivað av /api/v1/auth/verify, tá ið maginlink-teknið ber eitt staging_id og tað verifiseraða adressuið samsvarar SHA-256(normalise_email(party_b.contact)) — har normalise_email(addr) varðveitir lokala-partsins stavstødd og lágstavar bert økispartin (sambært RFC 5321 §2.3.11), og SHA-256 her er NIST FIPS 180-4 styttingin (ymisk frá tí SHA3-256, sum verður brúkt í §4-avleiðingum) — og rennur út 900 sekund (15 minuttir) eftir útgávu. Hetta er ein rakstrarlig anti-eftirlíkingar-gátt, IKKI partur av tí á-keðju qub-prógvi — ein triðjaparts-verifiserari, sum endurspælir §11, tørvar bert varandi goymslupláss og drand, uttan nakra ambætara-síðu uppfletting. Merkingin finst bert ambætara-síðu og er ongantíð partur av tí undirskrivaða likami.

Støddaráhrørsla (ML-DSA-65 høvundur + samundirskrivari):

Eind Stødd
Høvundaundirskrift 3.309 bæti
Høvunda alment lyklað 1.952 bæti
Samundirskrivara-undirskrift 3.309 bæti
Samundirskrivara alment lyklað 1.952 bæti
Tilsamans kryptografisk eyka-byrði 10.522 bæti
Goymslupláss-kostnaðarmunur ~$0.05

10. Markdown Framsýning og Reinsing

Hesin parturin er trygdar-avgerðandi. Vísarin framsýnir tekst-qubbar (content_type = 0x01) við einum avmarkaðum Markdown-undirsetti.

10.1 Loyvd Eind

10.2 Forboðin Eind

Eind Viðgerð
Ráur HTML (<div>, <script>, o.s.fr.) Strikað heilt og holt. Ongin HTML sleppur ígjøgnum.
Myndir (![alt](url)) Strikaðar. Mynda-syntaks verður tikið burtur úr úttaki.
Leinkjur ([text](url)) URL framsýnd sum sjónligur reintekstur. Ikki sjálvleinkjað. Ikki klikkilig uttan uttrýkiliga brúkaraatgerð.
Vandamiklir URL-skemar javascript:, data:, vbscript:, file: — strikaðir.
Iframes, innteknaðir, lutir Strikaðir.
HTML-eindir Avkodaðar til framsýningartekn bert um trygt.

10.3 Ímótkoming

Ímótkomningar MÚGVA brúka ein strangan loyvilista-tólkara, ikki ein avvísingarlista. Tann viðmæltu atgerðin:

  1. Tólka Markdown við pulldown-cmark (ella javnvirði).
  2. Gang gjøgnum AST og slepp nakran node, sum ikki er á loyvilistanum (§10.1).
  3. Fyri leinkju-nodes: send út URL sum sjónligan tekst, ikki sum eitt klikkiligt <a>-element.
  4. Umset tann filtreraða AST til eina slag-defineraða millumframsetting (t.d., ein MarkdownNode-enum við bert tryggum variantum). Ráur HTML er bygnaðarliga ófyriskipanligur í hesi IR.
  5. Framsýn úr tí slag-defineraðu IR til mál-vísarlagið (t.d., reaktiv vísarkomponentir, DOM-nodes). Eingin HTML-rein-samanseting ella innerHTML á nøkrum tíðspunkti.

Avvísingarlista-atgerðir eru veikar, av tí at nýggj Markdown-víðkanir ella tólkara-eyðkenni kunnu innføra ófiltreraðar eindir. Tann slag-defineraða AST-atgerðin gerð XSS bygnaðarliga ómøguligt — har er eingin variantur, sum kann bera tilvildarligan HTML.

10.4 Størri- og Bygnaðarmark


11. Triðjapartsverifikatión

Nakar triðjapartur kann verifisera ein almennan qub uttan qub-samstarv. Verifikatiónsmannagongdin:

1. Obtain arweave_tx_id (from delivery URL or direct knowledge).
2. Fetch SealedQubCbor from any storage gateway.
3. Confirm storage block inclusion (block height, block timestamp).
4. Parse SealedQubCbor → SealedQub.
5. Fetch drand round signature for SealedQub.drand_round.
6. tlock_decrypt(tlock_ciphertext, round_signature) → QubEnvelope CBOR bytes.
7. Parse → QubEnvelope.
8. Verify SHA3-256(body) == body_hash.
9. Verify QubEnvelope.qub_id == SealedQub.qub_id.
10. Verify QubEnvelope.unlock_at == SealedQub.unlock_at.
11. If sig_alg != 0x00: verify author_signature (see §9.4).
12. All checks pass → qub is verified.

Hvat verifikatión prógvar:

Prógv Hvat tað staðfestir
Binding Dulorðið fanst frammanundan goymslupláss-blokk-tíðarmerkinum.
Heild Reintekst-likamið samsvarar tí bundnu styttingini og hevur ikki verið broytt.
Tíðssetan Innihaldið var ólesiligt fram til drand-rundina, sum samsvarar tí valda avlæsingartíðini (treytað av tlock- og drand-trygdarforuttansetingum).

Hvat verifikatión IKKI prógvar:

Ikki-prógv Hví
Høvundaskapur sender_label er pyntandi. Uttan sig_alg0x01 kundi nakar hava innsiglað hetta innihaldið.
Ætlan qub prógvar innihald og tíðsetan, ikki hvat skaparin subjektivt meinti.
Fyri-tiltaks-tíðsetan Goymslupláss-blokk-íroknan kann seinka veruliga upphalan við minuttum. Bindingar-tíðarmerkið er blokk-tíðin, ikki tann løta brúkarin trýsti á "innsigla."

12. Útgávumerking

12.1 Protokollútgáva

version-teigurin (u8) í bæði SealedQub og QubEnvelope eyðmerkir høvuðs-protokollútgávuna.

12.2 Útgávusøga

Útgáva Virði Lýsing
v1 0x01 Almennir tekst-qubbar (content_type 0x01), pakt tvíhliða semjur (0x03, structured/v1-skema, ML-DSA-65 høvundur + samundirskrivari), tlock, SHA3-256

12.3 Framkompatibilitetur

Ein v1-vísari, sum møtir einum QubEnvelope við ókendum valfríum CBOR-kortlyklum (lyklar ikki í §3.2-kanonisku raðsetingini), EIGUR at hjáleiða teir lyklar og halda fram við verifikatión við kendum teigum. Hetta loyvir framtíðar smáar viðbøtur (t.d., nýggj metadáta) uttan at krevja eitt høvuðsútgávulyft.

Ein v1-vísari, sum møtir sig_alg = 0x01 (ML-DSA-65) men manglar ML-DSA-65-verifikatiónsstuðul, EIGUR at framsýna qub-innihaldið við einum "undirskrift til staðar men ikki verifiserandi"-fráboðan, ikki at avvísa qubbin heilt. Tilvísingar-ímótkomningin í dag avvísir hvørt sig_alg-virði annað enn 0x00 og 0x01, av tí at v1-skrásetingin inniheldur ongan annan gildugan algoritm — strangt avvísing og bløyt-feilur eru observatiónsliga eins, fram til ein triði algoritmur verður skrásettur. Tann bløyt-feilar-atferðin omanfyri verður byrðiberandi, tá ið §9.2 sleppir inn eini nýggjari innfeti, og tilvísingar-vísarin verður dagførdur til at bløyt-feila á tí tíðspunkti.

12.4 Ytri Umbúgvingsútgáva

Tann OuterWrapper, sum er lýstur í §13, ber sína egnu version-bæti, óheft av SealedQub.version og QubEnvelope.version. Tey tvey útgávuríini menast hvør sær: ein framtíðar post-kvantum-tryggur symmetriskur avloysari lyftir umbúgvingar-bætið uttan at nerta innra protokollútgávuna, og ein framtíðar protokollag-viðbót (t.d., ein nýggjur brævateigur) lyftir innra útgávuna uttan at nerta umbúgvingar-bætið.

OUTER_WRAPPER_VERSION_* Virði Algoritmur Støða
OUTER_WRAPPER_VERSION_1 0x01 AES-256-GCM við 12-bæti nonce, 16-bæti váttanartag, AAD bundið at qub_id v1 sjálvsett
0x020xFF Varðveitt Framtíð

Vísarar MÚGVA avvísa ókendar umbúgvingsútgávur við einum greiðum feili. Protokollurin heldur við vilja umbúgvingsútgávuríið smátt, fram til ein nakanligur flytingar-fyrisláttur kemur fram (t.d., NIST-vegleiðing, sum yndir ein annan AEAD); eitt 0x02-pláss verður tillutað í somu broyting, sum innførir algoritmin.


13. Ytri Krypteringarumbúgving

13.1 Grundgeving

Protokollagini (QubEnvelope → tlock → SealedQub) gera ein innsiglaðan qub tíðarlæstan: likamið er ólesiligt fram til unlock_at og drand-runda-undirskriftin hevur verið útgivin. Eftir avlæsing er runda-undirskriftin tó alment, og tann kanoniska CBOR-lagin av SealedQub er kennilig, so ein høstari, sum skrásetti varandi-goymslupláss handlar, kundi masseavkrypterað alt qub-savnið.

Tann ytri krypteringarumbúgving stongir tann kanalin við at seta inn eitt eyka symmetriskt AEAD-lag millum tann kanoniska SealedQubCbor og tey bæti, sum verða skrivað til varandi goymslupláss. Tann 256-bita lykilin K livir bert í URL-brotinum av avgreiðslu-URL og á brúkaratóleindum; kagar senda ikki URL-brot til ambætarar, so qub.social, hvør goymslupláss-gátt og hvør CDN framman fyri annaðhvørt eru observatiónsliga blind fyri K. Hvør qub í varandi goymslupláss er tí eitt ógjøgnumskygt dulorð, hvørs reintekstur er ógjenfáanligur uttan tann URL, sum skaparin valdi at deila.

Net-úrslit:

13.2 Lagaseting

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
  ↓ AES-256-GCM(K, nonce, AAD=qub_id) (§7 step 12a, this section)
OuterWrapper CBOR bytes              ← uploaded to permanent storage (§7 step 15)

Innsigling og avlæsing á protokollaginum (§7, §8) eru óbroyttar undir umbúgvingar-markinum; umbúgvingin festist á kallstaðnum hjá seal() og loysist á kallstaðnum hjá unlock().

13.3 OuterWrapper Dátubygnaður

struct OuterWrapper {
    version:    u8,           // 0x01, see §12.4
    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
}

Teig-stødufeingi.

CBOR-raðfesting. Kanoniskt CBOR sambært §3, við somu lyklaraðsetingar-regluni (raðað eftir raðfestari bætilongd vaksandi, so leksikografiskt). Teir fýra lyklarnir eru:

Lykil Raðfest bæti Raðseting
nonce 6 1
qub_id 7 2
version 8 3
ciphertext 11 4

Tað fyrsta bæti av OuterWrapper-CBOR er tí tann ávísa-longdar kort-høvur fyri eitt 4-innfetis kort (0xA4).

13.4 AAD-Binding at qub_id

Umbúgvingin bindur qub_id sum AEAD eyka váttaða dáta. Hetta er tann byrðiberandi bygnaðarliga vørnin móti trimum sløgum av álopum:

Álop Vørn
Flyt dulorð undir ein annan qub_id-teig í umbúgvingini AAD-misrætt → AEAD-vátting dettur
Blanda URL-brotið av qub A við varandi-goymslupláss bætini av qub B AAD-misrætt → AEAD-vátting dettur
Manipulera qub_id-teigin í umbúgvingini eftir upphalan AAD-misrætt → AEAD-vátting dettur

At bera qub_id í umbúgvingar-reintekstinum veikir ikki uppteljingar-ónæmi munandi — qub_id er sjálvur ein SHA3-256-stytting av §4.1-forímyndini uttan nakra endurfáanliga forímynd úr styttingini, og ein uppteljari, sum longu hevur høstað umbúgvingar-bætini, lærir einki av tí sjónliga qub_id, sum hann ikki kundi sluttað sær til frá tilveruni av sjálvari upphalanini.

13.5 Umbúgvingar- og Avumbúgvingar-Algoritmar

wrap_sealed_qub(SealedQubCbor S, qub_id Q, key K, nonce N):
    require K.len() == 32 and N.len() == 12 and Q.len() == 32
    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.4
    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
    return P                            // P is the inner SealedQubCbor

Feilstøðu-samanfall. Skeivur K, skeivt nonce, AAD-misrætt og manipulerað dulorð framleiða øll sama DECRYPT_FAILED-feil. Hetta er ein viljaður AEAD-eginleiki: at skilja feilstøðuna fór at gjørt eina síðukanal, sum ein fjar-álopsmaður kundi probað við at senda misformaðar umbúgvingar og taka tíð á svarinum. Tilvísingar-ímótkomningar MÚGVA samanfella allar AEAD-feilir til eina einasta feil-formi.

13.6 Lyklatilfar og Útbýti

Umbúgvingar-lykilin K er eitt 256-bita javnt tilvildarvirði, framleitt fyri hvønn qub av einum CSPRNG. Tilvísingar-ímótkomningarnar fáa hann frá:

Útbýti: K MÁ verða raðfest sum URL-trygt base64 (RFC 4648 §5, eingin fylling) og lagt afturat avgreiðslu-URL sum brot-eindina:

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

Brotið verður ongantíð sent til nakan ambætara av einum samsvarandi kaga. Endurfáanarkanalar (ambætara-síðu søguskráseting, valfríur teldupost-sjálvsending), sum varðveita tann fulla avgreiðslu-URL — íroknað brotið — út um brúkarans tóleind, eru eitt skilt skifti móti tí sjálvsettu krypto-smildru-støðuni og MÚGVA verða gátta á uttrýkiligu brúkarasamtykki.

Brot-tap. Um ein brúkari missir URL-brotið og hevur ongan endurfáanarkanal, er qub ólesiligur. Hetta er tað byrðiberandi skiftið í sniðnum og MÁ verða greitt frá fyri brúkaranum á innsiglingartíð. MVP styrkir innsiglingartíðar-frágreiðingina við uttrýkiligum "goym hendan URL"-tekst og einum verifiseraðum-teldupost endurfáanarkanali fyri brúkarar, sum velja tað.

13.7 Utanmark fyri Hendan Partin

13.8 Almennir qubbar (umbúgvingar-burturlating)

Tann ytri umbúgvingin er valfrí á avgreiðslulaginum. Ein skapari kann innsigla ein qub sum almennan, og í tí føri verður tann kanoniski SealedQubCbor skrivaður til varandi goymslupláss beinleiðis, uttan nakað OuterWrapper-lag og uttan nakran lykil K:

SealedQubCbor bytes  ──(public)──▶  uploaded to permanent storage as-is
SealedQubCbor bytes  ──(private)─▶  AES-256-GCM(K, …) ▶ OuterWrapper ▶ uploaded

Ein almennur qub er tíðarlæstur men ikki leinkju-stýrdur: hann verður verandi ólesiligur fram til drand-runda hansara verður útgivin (tlock-lagið er óbroytt), men eftir avlæsing kann hvør, sum hevur arweave_tx_id, avkryptera hann — eingin URL-brot-eind er kravd, tí einki K er. Hetta er tað viljaða skiftið fyri yvirbríkar, sum ambætarin má dríva: avdúkingar-fráboðanar-teldupostar, triðjamanna-embeds og ríkari eftir-avdúkingar-SEO krevja øll eina leinkju, sum riggar uttan ein loyndarleynd, sum ambætarin ongantíð heldur (§13.6).

Avleiðingar, sum ein framleiðari MÁ taka hædd fyri:

Privatur (umbúgvdur) verður verandi sjálvsettur; almennur er eitt uttrýkiligt skapara-val fyri hvønn qub.


14. Royndarvektorir

14.1 qub_id Avleiðing

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  = 4695445  (= (1736294400 - 1595431050) / 30, 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 — V1.2):
  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)
  0x000000000047A595  ||  // drand_round as u64 big-endian (4695445)
  body_hash           ||  // 32 bytes
  title_hash              // 32 bytes (all-zeros sentinel; title absent)

Expected output:
  qub_id = SHA3-256(preimage)
         = 3a9fcb31b750d985c262fada6d4f777f
           d6a28be831d941d85c131f5a4bbaf8a4

Ímótkomningar MÚGVA framleiða eins body_hash- og qub_id-virði fyri hetta inntakið. Hesin royndarvektorin EIGUR at vera tann fyrsta eindarroyndin, sum verður skrivað. Tey kanonisku virðini omanfyri vórðu roknað av tilvísingar-ímótkomningini og MÚGVA samsvara bita fyri bita. Søguligar forímynd-skipanir (fyrr-byrjan — eingir livandi qubbar veltu á hesum): tann 92-bæta V1.0 qub_id var 3d9fc2390eab043d38a1669ed3b71be76f9eefe872b9569ab1aaa027b88392b0; tann 100-bæta V1.1 qub_id (eftir at outcome_at_or_zero varð felt inn) var b0d032898ad629795150fdcb3f84e518f59ed05b7a2a82bc24ebdb87f52144ed. V1.2 fellir drand_round inn og økir økisskiljaran til QUB_ID_V2.

14.2 Avlæsingarrunda-Kortlegging

Input:
  unlock_at           = 1735689600
  chain_genesis_time  = 1595431050
  chain_period_seconds = 30

Calculation:
  (1735689600 - 1595431050) / 30 = 4675285.0
  ceil(4675285.0) = 4675285

drand_round = 4675285

14.3 Kanoniskt CBOR Hringferð

Ímótkomningar MÚGVA vátta, at serialize(parse(serialize(qub))) == serialize(qub) fyri øll gildug inntøk. Hetta er ein eginleikaroynd, ikki ein einstakur vektorur.

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)

Tey kanonisku CBOR-bætini og SHA3-256 body_hash verða roknað av tilvísingar-ímótkomningini. Ímótkomningar MÚGVA framleiða bæti-eins CBOR fyri hetta inntakið.

Ímótkomningar MÚGVA eisini vátta, at serialize(parse(serialize(pact))) == serialize(pact) fyri øll gildug PactTerms-inntøk (eginleikaroynd).

14.5 Ytri Umbúgving Tvørmáls-Vektorir

Tann ytri umbúgvingin (§13) hevur eina sjálvstøðuga kanoniska grundgrein á crates/qub-core/tests/vectors/wrapper_v1.json. Hvørt føri fastsetur eitt (key, nonce, qub_id, sealed_cbor)-tupul sum ógjøgnumskygd hex-inntøk og áseta eitt ávíst expected_wrapper_hex-úttak. Báðar tilvísingar-ímótkomningarnar nýta sama JSON-fílu:

Grundgreinin fastsetur fyri tíðina trý føri:

Føri Fevjing
basic-text-public Minsta veruliga SealedQub-lagin; ongir valfríir teigar. Áseta tann kanoniska umbúgvingar-lagin fyri ein v1.0-vanligan qub.
with-recipient-pubkey SealedQub við recipient_pubkey settum (Stig 2 leið). Ymiskt innra CBOR-lyklasett, ymiskt qub_id.
longer-body ~4 KiB likam — royna fleirbæti CBOR-longdar-forskriftir innan í bæði innra brævinum og ytra dulorðinum.

Ímótkomningar MÚGVA framleiða bæti-eins expected_wrapper_hex fyri tey skrásettu inntøkini. At endurgenera grundgreinina krevur QUB_REGEN_VECTORS=1 cargo test -p qub-core --test wrapper_vectors og er varðveitt fyri skildar snið-broytingar.


15. Krypto-Profil Stýring (Framtíð)

Hesin parturin er upplýsandi fyri v1 og verður normativur fyrstu ferð, eitt annað algoritmur fer inn í nakra av qubs kryptografisku grundleggjandi eindunum.

15.1 Núverandi Støða

Protokollur v1 bindur júst ein algoritm fyri hvørt grundleggjandi eind:

Verifiserarar fastkoda í dag lykla- og undirskriftarlongdir fyri hvørt grundleggjandi eind. Eingin smidugleika-yvirvødd verður víst av tráðasniðnum.

15.2 Ætlaða Lag

Tá ið eitt annað algoritmur fer inn í protokollin, verður verifiserarin settur upp fyri ein nevndan CryptoProfile (t.d., ExqubV1), sum listir tað júst settið av loyvdum virðum fyri hvørt grundleggjandi eind — sig_algs, drand-keðjur, umbúgvingsútgávur, innihaldsslag. Profilið er fastsett á verifikatiónstíð, ongantíð samhandlað í-band. Hvørt virði uttanfyri tað virkna profilið verður avvíst.

Hetta tryggjar, at at leggja ML-DSA-87 afturat ella at virkja Ed25519 kann ikki afturvirkandi veikja tilstaðarverandi verifiserara-uppsetingar: ein v1-verifiserari verður verandi ein v1-verifiserari, sjálvt eftir at eitt v2-profil er útgivið.

15.3 Útloysingartreytir

Lyft §15 til normativa støðu, tá ið nakað av tí fylgjandi verður fyriskotið:

Til tá er §15 ein staðhaldari, sum fastsetur flytingar-lagið, so framtíðar PRar lenda móti einum kendum máli heldur enn at endurmeta samhandlingar-yvirvøddina frá byrjan.