qub प्रोटोकॉल विनिर्देश

qub क्रिप्टोग्राफिक कालिक प्रतिबद्धताओं के लिए एक प्रोटोकॉल है: एक प्रणाली जो शब्दों को भविष्य की तारीख पर मुहर लगाती है और जब वह तारीख आती है, तो ठीक-ठीक प्रमाणित करती है कि क्या कहा गया था और कब।

तीन आदिम तत्व इसे कार्यान्वित करते हैं। drand एक विकेन्द्रीकृत यादृच्छिकता बीकन है — प्रकटीकरण की तारीख भौतिकी द्वारा प्रवर्तनीय है, किसी पक्ष की सद्भावना से नहीं। स्थायी सार्वजनिक संग्रहण एक छेड़छाड़-रोधी सार्वजनिक भंडार है — एक बार मुहरबंद होने के बाद कोई भी पक्ष qub को संपादित या हटा नहीं सकता। ML-DSA-65 एक उत्तर-क्वांटम डिजिटल हस्ताक्षर है — प्रत्येक qub एक कुंजी जोड़े से बंधा है जिसकी गुप्त कुंजी कभी भी लेखक के डिवाइस को नहीं छोड़ती।

मिलकर ये आदिम तत्व एक ऐसा कथन बनाते हैं जो समय-बद्ध, छेड़छाड़-स्पष्ट और श्रेय-योग्य है — एक रसीद जिसका मूल्य तब बढ़ता है जब दुनिया की अतीत को गढ़ने की क्षमता में सुधार होता है।

इस दस्तावेज़ का शेष भाग अंतर-संचालनीय कार्यान्वयनों के लिए आवश्यक मानक विनिर्देशन है।


qub प्रोटोकॉल विनिर्देशन

क्षेत्र मान
संस्करण 1.0 (प्रोटोकॉल संस्करण 0x01, बाहरी आवरण संस्करण 0x01)
तारीख 2026-05-01
स्थिति मसौदा
समीक्षा-तिथि तक 2026-05-01

यह दस्तावेज़ qub समयबद्ध प्रतिबद्धता प्रणाली के लिए मानक प्रोटोकॉल विनिर्देशन है। यह डेटा संरचनाओं, क्रमबद्धता नियमों, व्युत्पत्ति सूत्रों और सत्यापन प्रक्रियाओं को परिभाषित करता है जो अंतर-संचालनीय कार्यान्वयनों के लिए आवश्यक हैं।

कार्यक्षेत्र: प्रोटोकॉल परत जानबूझकर भाषा-तटस्थ है — qub का बॉडी अपारदर्शी प्लेनटेक्स्ट / मार्कडाउन / संधि बाइट्स है, और लोकेल-संवेदी रेंडरिंग दर्शक की जिम्मेदारी है (qub.social वेब ऐप, <qub-embed> iframe, MCP क्लाइंट, इत्यादि)।


1. संकेतन और परिपाटियाँ

संकेतन अर्थ
u8, u64, i64 निर्दिष्ट बिट चौड़ाई के अहस्ताक्षरित/हस्ताक्षरित पूर्णांक
[u8; N] N बाइट्स की स्थिर-लंबाई बाइट सरणी
Vec<u8> परिवर्तनशील-लंबाई बाइट सरणी
Option<T> प्रकार T का मान, या अनुपस्थित
String UTF-8 टेक्स्ट स्ट्रिंग, NFC सामान्यीकृत
`
SHA3-256(x) बाइट स्ट्रिंग x का NIST SHA3-256 हैश (FIPS 202)
ceil(x) सीलिंग फलन: सबसे छोटा पूर्णांक ≥ x
CBOR Concise Binary Object Representation (RFC 8949)
big-endian सबसे महत्वपूर्ण बाइट पहले

प्रीइमेज निर्माणों में सभी पूर्णांक big-endian स्थिर-चौड़ाई बाइट सरणियों के रूप में एन्कोड किए जाते हैं (i64 → 8 बाइट्स, u8 → 1 बाइट), जब तक अन्यथा निर्दिष्ट न हो।

सभी टाइमस्टैम्प UTC में Unix सेकंड हैं।


2. डेटा संरचनाएँ

2.1 ComposeQub (रचयिता की इन-मेमोरी स्थिति)

CBOR में क्रमबद्ध नहीं। स्थायी संग्रहण में नहीं लिखा गया। रचयिता ऐप के लिए स्थानीय।

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 (डिक्रिप्ट किया गया पेलोड)

कैनोनिकल CBOR (§3) का उपयोग करके क्रमबद्ध। SealedQub के अंदर एन्क्रिप्ट किया गया। यह वह संरचना है जो डिक्रिप्शन के बाद सामग्री अखंडता को प्रमाणित करती है।

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 — जब वास्तविकता निर्णय प्रदान करती है (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
}

आधार रेखा (अहस्ताक्षरित टेक्स्ट qub): version = 0x01, content_type = 0x01, sig_alg = 0x00, सभी Option क्षेत्र अनुपस्थित।

अन्य v1 कॉन्फ़िगरेशन: content_type = 0x03 (संधि बॉडी, देखें §6.1); sig_alg = 0x01 (ML-DSA-65) author_signature और author_pubkey मौजूद के साथ (देखें §9.3); सह-हस्ताक्षरित संधियों के लिए cosigner_pubkey और cosigner_signature एक साथ उपस्थित (देखें §9.7); उत्तर-शृंखला qubs के लिए reply_to मूल qub के qub_id पर सेट (हस्ताक्षर दायरे के निहितार्थ के लिए §9.3 देखें)।

2.3 SealedQub (कैनोनिकल वायर प्रारूप)

कैनोनिकल CBOR (§3) का उपयोग करके क्रमबद्ध। स्थायी संग्रहण में लिखा जाता है। यह ऑन-चेन कलाकृति है।

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 — प्रकट होने से पहले verdict-watch CTA पर
                                        //   प्रदर्शित; QubEnvelope.outcome_at का दर्पण;
                                        //   §4.1 प्रीइमेज के माध्यम से qub_id से बंधा।
    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 (दर्शक एप्लिकेशन स्थिति)

CBOR में क्रमबद्ध नहीं। दर्शक ऐप के लिए स्थानीय। सफल डिक्रिप्शन और सत्यापन के बाद निर्मित।

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. कैनोनिकल CBOR प्रोफ़ाइल

सभी SealedQub और QubEnvelope क्रमबद्धता इस प्रोफ़ाइल के अनुरूप होनी MUST। दिए गए समान तार्किक संरचना के साथ दो कार्यान्वयन समान बाइट्स उत्पन्न करने MUST।

3.1 एन्कोडिंग नियम

नियम विनिर्देशन
मानक RFC 8949 §4.2.1 (Core Deterministic Encoding Requirements)
मानचित्र कुंजी क्रम पहले एन्कोडेड बाइट लंबाई से क्रमबद्ध (छोटे से लंबे), फिर शब्दकोश क्रम (समान-लंबाई एन्कोडिंग के लिए बाइट-दर-बाइट)
पूर्णांक एन्कोडिंग सबसे छोटा रूप: 0–23 प्रारंभिक बाइट में; 24–255 2 बाइट्स में; 256–65535 3 बाइट्स में; आदि।
लंबाई एन्कोडिंग केवल निश्चित लंबाई। कोई अनिश्चित-लंबाई सरणियाँ, मानचित्र, बाइट स्ट्रिंग, या टेक्स्ट स्ट्रिंग नहीं (additional info = 31 निषिद्ध है)।
टैग कोई CBOR टैग नहीं (मेजर टाइप 6 निषिद्ध है)।
फ्लोटिंग-पॉइंट कोई फ्लोट नहीं (मेजर टाइप 7 मान 0xF9–0xFB निषिद्ध हैं)।
टेक्स्ट स्ट्रिंग UTF-8 एन्कोडेड, NFC सामान्यीकृत (Unicode Normalization Form C)।
बाइट स्ट्रिंग कच्चे बाइट्स। CBOR परत पर कोई base64 एन्कोडिंग नहीं।
डुप्लिकेट कुंजियाँ त्रुटि के साथ अस्वीकार करें। पार्सर्स डुप्लिकेट मानचित्र कुंजियों को चुपचाप स्वीकार MUST NOT करें।
अज्ञात कुंजियाँ त्रुटि के साथ अस्वीकार करें। पार्सर्स टाइप के कैनोनिकल कुंजी सेट से बाहर की मानचित्र कुंजियों को सहन MUST NOT करें — दो भिन्न कैनोनिकल बाइट स्ट्रिंग्स को कभी भी एक ही मान में डिकोड नहीं होना चाहिए (encode(decode(x)) == x), और हस्ताक्षरित पेलोड के लिए एक अतिरिक्त कुंजी ऐसी छिपी सामग्री बन जाती जिसके लिए दोनों हस्ताक्षर प्रतिबद्ध होते हैं। योजना का विकास version के माध्यम से होता है, कभी अतिरिक्त कुंजियों के माध्यम से नहीं।
सरल मान केवल true (0xF5), false (0xF4), और null (0xF6) की अनुमति है।
वैकल्पिक क्षेत्र अनुपस्थित वैकल्पिक क्षेत्र CBOR मानचित्र से पूरी तरह से छोड़ दिए जाते हैं (null के रूप में एन्कोड नहीं किए जाते)। उपस्थित वैकल्पिक क्षेत्र क्रमबद्ध कुंजी क्रम में शामिल किए जाते हैं।

3.2 सत्यापित कैनोनिकल कुंजी क्रम

ये कुंजी क्रम मानक हैं। कार्यान्वयन ठीक इसी क्रम में कुंजियाँ उत्सर्जित करना MUST। डिबग दावे गैर-रिलीज़ बिल्ड्स में क्रमण को सत्यापित करना SHOULD।

QubEnvelope (संस्करण 0x01, अहस्ताक्षरित, सभी वैकल्पिक क्षेत्र अनुपस्थित):

"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 कुंजी क्रम व्युत्पत्ति: प्रत्येक कुंजी एक CBOR टेक्स्ट स्ट्रिंग है। एन्कोडेड लंबाई = 1 बाइट हेडर + स्ट्रिंग लंबाई (24 बाइट्स से कम की स्ट्रिंग के लिए)। पहले कुल एन्कोडेड लंबाई से क्रमबद्ध करें, फिर समान-लंबाई की कुंजियों के लिए शब्दकोश क्रम से।

SealedQub (संस्करण 0x01, सार्वजनिक, कोई प्राप्तकर्ता नहीं):

"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 (संधि बॉडी, 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 (terms सरणी की पंक्ति):

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

PartyIdentifier (party_a / party_b मानचित्र):

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

3.3 बाइट एन्कोडिंग संदर्भ

प्रकार CBOR एन्कोडिंग उदाहरण
SHA3-256 हैश (32 बाइट्स) 0x58 0x20 + 32 बाइट्स body_hash, qub_id
टाइमस्टैम्प (i64) मेजर टाइप 0 (धनात्मक) या 1 (ऋणात्मक), सबसे छोटा एन्कोडिंग Unix सेकंड
संस्करण (u8, मान 1) 0x01 (एकल बाइट)
सामग्री प्रकार (u8, मान 1) 0x01 (एकल बाइट)
sig_alg (u8, मान 0) 0x00 (एकल बाइट)
ML-DSA-65 हस्ताक्षर (3,309 बाइट्स) 0x59 0x0C 0xED + 3,309 बाइट्स author_signature, cosigner_signature
ML-DSA-65 सार्वजनिक कुंजी (1,952 बाइट्स) 0x59 0x07 0xA0 + 1,952 बाइट्स author_pubkey, cosigner_pubkey

4. मानक व्युत्पत्तियाँ

4.1 qub_id

qub_id विशिष्ट रूप से एक qub की पहचान करता है और QubEnvelope को SealedQub से बांधता है। यह एनवेलप सामग्री से नियतात्मक रूप से व्युत्पन्न किया जाता है।

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

डोमेन विभाजक एन्कोडिंग: स्ट्रिंग "QUB_ID_V2" 9 ASCII बाइट्स है। संरेखण के लिए 10 बाइट्स तक पहुँचने के लिए एक 0x00 पैडिंग बाइट जोड़ा जाता है। कार्यान्वयन ठीक इन 10 बाइट्स का उपयोग करना MUST: [0x51, 0x55, 0x42, 0x5F, 0x49, 0x44, 0x5F, 0x56, 0x32, 0x00]

outcome_at एन्कोडिंग: V1.1 ने वैकल्पिक outcome_at क्षेत्र को बंधन में मोड़ने के लिए प्रीइमेज को 92 से 100 बाइट्स तक बढ़ाया। अनुपस्थित outcome_at 8 शून्य बाइट्स के रूप में एन्कोड किया जाता है; प्रोटोकॉल सत्यापनकर्ता हर जगह outcome_at <= 0 को अस्वीकार करते हैं, इसलिए यह सेंटिनल किसी वैध मान से टकरा नहीं सकता। देखें §3.2 (वायर प्रारूप) और verdict तंत्र के लिए इन-ट्री tasks/verdict-uplift-plan.md जो इस क्षेत्र को प्रेरित करता है।

drand_round एन्कोडिंग: V1.2 ने drand_round (लक्ष्य drand राउंड, §4.3) को बंधन में मोड़ने के लिए प्रीइमेज को 100 से 108 बाइट्स तक बढ़ाया, और डोमेन विभाजक को QUB_ID_V2 तक बढ़ाया। यह टाइमलॉक राउंड को qub पहचान में बांधता है: एक गेटवे सिफरटेक्स्ट को प्रदर्शित unlock_at द्वारा निहित राउंड से भिन्न (उदा. पहले ही बीत चुके) राउंड से दोबारा नहीं बांध सकता। अनलॉक प्रक्रिया (§8) अतिरिक्त रूप से सत्यापित करती है कि tlock सिफरटेक्स्ट स्टैन्ज़ा में पकाया गया राउंड unlock_round(unlock_at) से मेल खाता है, इसलिए प्रदर्शित अनलॉक समय प्रमाण्य रूप से वही राउंड है जो डिक्रिप्शन को नियंत्रित करता है।

गुण:

4.2 body_hash

body_hash = SHA3-256(body)

जहाँ body कच्चा Vec<u8> सामग्री पेलोड है। टेक्स्ट qubs के लिए, यह UTF-8 एन्कोडेड qub बॉडी है।

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

जहाँ title वैकल्पिक प्लेनटेक्स्ट शीर्षक है जो प्रकट करने से पहले दर्शक की उलटी गिनती पर सतह पर आता है (देखें §3.2)। NFC सामान्यीकरण हैश समय पर चलता है ताकि डाइजेस्ट दृश्य रूप से समकक्ष कोड-पॉइंट अनुक्रमों में स्थिर हो। सभी-शून्य सेंटीनेल अनुपस्थित मामले के लिए आरक्षित है; एक खाली स्ट्रिंग कैनोनिकल CBOR सीमा पर "अनुपस्थित" के गैर-कैनोनिकल एन्कोडिंग के रूप में अस्वीकार की जाती है (कैनोनिकल एन्कोडिंग क्षेत्र को पूरी तरह से छोड़ देता है)।

4.3 Unlock-Round मानचित्रण

drand_round = ceil((unlock_at - chain_genesis_time) / chain_period_seconds)
पैरामीटर स्रोत उदाहरण
unlock_at उपयोगकर्ता-चयनित Unix सेकंड UTC 1735689600 (2025-01-01 00:00:00 UTC)
chain_genesis_time drand चेन जानकारी (genesis_time) 1595431050
chain_period_seconds drand चेन जानकारी (period) 30

ceil() ऑपरेशन पहला drand राउंड चुनता है जिसका रिवील समय ≥ unlock_at है। यह सुनिश्चित करता है कि qub चुने गए अनलॉक समय से पहले डिक्रिप्ट करने योग्य नहीं होता।

किनारा मामला: यदि (unlock_at - chain_genesis_time) chain_period_seconds से ठीक विभाज्य है, तो परिणाम ठीक वह राउंड है — qub उस राउंड के रिवील समय पर ठीक-ठीक अनलॉक होता है।

सत्यापन: unlock_at मुहरबंदी के समय भविष्य में होना MUST। unlock_at created_at से 10 वर्षों से अधिक नहीं होना MUST NOT (लंबे-क्षितिज drand निर्भरता जोखिम को सीमित करने के लिए; UI को 2 वर्षों से अधिक अनलॉक तिथियों के लिए चेतावनी देनी SHOULD)।


5. वायर प्रारूप न्यूटाइप्स

वायर प्रारूप न्यूटाइप्स CBOR बाइट्स को JSON, कच्चे प्लेनटेक्स्ट, या अन्य बाइट एन्कोडिंग के साथ भ्रमित होने से कंपाइल-टाइम सुरक्षा प्रदान करते हैं।

प्रकार समाहित करता है उत्पादित उपभोग
SealedQubCbor SealedQub का कैनोनिकल CBOR serialize_sealed_qub() स्थायी-संग्रहण अपलोड, दर्शक फ़ेच
QubEnvelopeCbor QubEnvelope का कैनोनिकल CBOR serialize_qub_envelope() tlock एन्क्रिप्ट इनपुट, tlock डिक्रिप्ट आउटपुट

5.1 निर्माण नियम

// 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 निर्माण पर सत्यापन

from_encoded() को सत्यापित करना SHOULD कि इनपुट एक मान्य CBOR मानचित्र हेडर से शुरू होता है। पूर्ण संरचनात्मक सत्यापन पार्स समय पर होता है, निर्माण समय पर नहीं, ताकि दोहरी-पार्सिंग से बचा जा सके।


6. सामग्री प्रकार रजिस्ट्री

मान प्रकार अधिकतम बॉडी आकार टिप्पणियाँ
0x00 आरक्षित (अमान्य) उपयोग MUST NOT
0x01 सादा टेक्स्ट (UTF-8, प्रतिबंधित मार्कडाउन) 50 KB सशुल्क / 10 KB मुफ़्त रेंडरिंग नियमों के लिए §10 देखें। मुफ़्त / सशुल्क विभाजन अपलोड सेवा द्वारा लागू किया जाता है; प्रोटोकॉल-परत कठोर सीमा 50 KB है।
0x02 आरक्षित (भविष्य) भविष्य के सामग्री प्रकार के लिए आवंटित; v1 में मान्य नहीं। दर्शक नीचे दिए गए नियम के अनुसार इसे अस्वीकार करना MUST।
0x03 संधि (द्विपक्षीय समझौता, CBOR बॉडी) 100 KB बॉडी कैनोनिकल CBOR PactTerms (§6.1) है। सह-हस्ताक्षर §9.7 के अनुसार।

दर्शक अज्ञात सामग्री प्रकारों को एक स्पष्ट उपयोगकर्ता-दृश्य त्रुटि के साथ अस्वीकार करना MUST। दर्शक अज्ञात प्रकारों को टेक्स्ट के रूप में रेंडर करने का प्रयास MUST NOT।

6.1 संधि बॉडी (content_type = 0x03)

संधि बॉडी PactTerms मान का कैनोनिकल CBOR एन्कोडिंग है:

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)> }

तीनों मानचित्रों के लिए कैनोनिकल CBOR कुंजी क्रम §3.2 में दिए गए हैं। कुल क्रमबद्ध संधि CBOR 100 KB से अधिक MUST NOT (§6 से मेल खाता है)।

योजना विभेदक। structured/v1 संधि के लिए terms में पहली पंक्ति { key: "pact_schema", value: "structured/v1" } होनी MUST। इस मार्कर के बिना पंक्तियाँ "कस्टम" संधियाँ हैं और कोई संरचित सत्यापन या योजना-संवेदी रेंडरिंग प्राप्त नहीं करतीं।

स्थिर स्वीकृति स्लॉट। structured/v1 संधियाँ इन कुंजियों के अंतर्गत ठीक चार स्वीकृति पंक्तियाँ ले जाती हैं:

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

प्रत्येक के लिए value (role, kind) जोड़ी द्वारा चुनी गई आठ स्थिर अंग्रेज़ी स्ट्रिंग्स में से एक है, जहाँ role ∈ { seller, buyer, provider, client } और kind ∈ { standard, capacity }। स्ट्रिंग्स स्वयं मानक प्रोटोकॉल डेटा हैं — दोनों पक्षों के ML-DSA-65 हस्ताक्षर body_hash के माध्यम से सटीक बाइट्स के लिए प्रतिबद्ध होते हैं। उन्हें स्थानीयकृत नहीं किया जाता; हस्ताक्षरित बॉडी भाषा-तटस्थ है। किसी भी शब्दावली परिवर्तन के लिए एक नया योजना संस्करण (structured/v2) आवश्यक है।

आठ स्ट्रिंग्स, उनकी खोज (acknowledgement_for(role, kind)), और प्रत्येक के लिए तर्क संदर्भ कार्यान्वयन द्वारा पिन किए गए हैं। अनुरूप कार्यान्वयन बाइट-समान स्वीकृति मान उत्सर्जित करना MUST; सभी चार भूमिका संयोजनों को कवर करने वाले स्वर्ण-फ़िक्स्चर SHA3-256 बॉडी-हैश परीक्षण किसी भी विचलन को पकड़ते हैं।

दर्शक प्रदर्शन क्रम। स्वीकृति स्ट्रिंग्स में "described above" जैसे वाक्यांश होते हैं, जो मानते हैं कि विवरण / दायरा पंक्तियाँ स्वीकृतियों से पहले रेंडर होती हैं। दर्शक terms सरणी को CBOR क्रम में रेंडर करना MUST; पुनः क्रमबद्ध करने से प्रोज़ अर्थ-विज्ञान टूट जाता है।

प्रति-पक्ष संपर्क। जब पक्ष B का contact एक मान्य ईमेल पता होता है, तो qub अपलोड सेवा स्टेज समय पर एक समीक्षा / सह-हस्ताक्षर निमंत्रण ईमेल स्वतः-भेजती है और अंततः सह-हस्ताक्षर को उसी पते के सत्यापन से बांधती है (§9.7)। जिन संधियों में पक्ष B संपर्क अनुपस्थित है, उन पर अभी भी सह-हस्ताक्षर किए जा सकते हैं, लेकिन केवल बैंड-से-बाहर चैनल के माध्यम से — सेवा सह-हस्ताक्षर अनुरोधों को अस्वीकार करती है जो एक मेल खाते 15-मिनट के ईमेल-सत्यापन मार्कर का उत्पादन नहीं कर सकते।

6.2 फ़ैसला बॉडी (content_type = 0x04)

फ़ैसला बॉडी VerdictBody मान का कैनोनिकल CBOR एन्कोडिंग है:

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
}

कैनोनिकल CBOR कुंजी क्रम:

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

कुल क्रमबद्ध फ़ैसला CBOR 8 KB से अधिक MUST NOT (ऊपर दी गई रजिस्ट्री पंक्ति से मेल खाता है)।

परिणाम एनम। वायर बाइट इंटेंट-तटस्थ है; चार बकेट Right / Partial / Wrong / Unfalsifiable हर फ़ैसला-वहन करने वाले इंटेंट के परिणाम-अंतराल को कवर करते हैं। प्रति-इंटेंट लेबल (Right के लिए "सही कहा था" / "निभाया" / "जारी हुआ" / "पुष्टि हुई", आदि) एक दर्शक-पक्ष रेंडरिंग चिंता है जो मूल qub के इंटेंट के विरुद्ध हल की जाती है — वायर भाषा- और इंटेंट-तटस्थ रहती है। 1..=4 से बाहर के मान डिकोड पर अस्वीकार किए जाने MUST।

मूल संबंध। एक फ़ैसला qub अपनी बॉडी में मूल संदर्भ नहीं ले जाता। मूल qub की Arweave लेन-देन id अपलोड समय पर Parent-Tx-Id संग्रहण टैग के रूप में उत्सर्जित की जाती है (§7 संग्रहण-टैग परत)। यह बॉडी को स्व-आँकलन का एक स्व-निहित हस्ताक्षरित कथन रखता है; ऑडिट श्रृंखला ("किसके बारे में सही?") Arweave-टैग लुकअप के माध्यम से स्थापित होती है।

साक्ष्य URL सुरक्षा (मानक)। जब evidence_url उपस्थित होता है, सत्यापनकर्ता (कंपोज़-पक्ष, वायर-पक्ष, Worker एज) निम्न लागू करना MUST:

  1. केवल HTTPS। स्ट्रिंग बाइट अनुक्रम https:// से शुरू होनी MUST। कोई अन्य योजना — http, ftp, javascript, data, file, आदि — अस्वीकार की जाती है।
  2. लंबाई सीमा। ≤ 2,048 बाइट्स (ब्राउज़र URL व्यावहारिक सीमा)।
  3. NFC + शत्रुतापूर्ण-कोडपॉइंट जाँच। title और reflection के समान नियम — bidi-override / zero-width / tag-block / BOM / C0 / C1 कोडपॉइंट अस्वीकार किए जाते हैं। परिभाषा Rust crate::handle::contains_hostile_text_codepoint और TS workers/api/src/utils/unicode.ts::isHostileCodepoint से मेल खाती है (लॉकस्टेप में रखें)।
  4. कोई व्हाइटस्पेस नहीं, कोई ASCII नियंत्रण नहीं। URL में कहीं भी व्हाइटस्पेस / DEL / सब-0x20 बाइट्स अस्वीकार किए जाते हैं — \n/\t इंजेक्शन वेक्टर को बंद करता है जिसे bidi नियम कवर नहीं करता।
  5. गैर-खाली होस्ट खंड। https:// और पहले /, ?, या # के बीच सब कुछ गैर-खाली होना MUST।

कोई सर्वर-पक्ष फ़ेचिंग नहीं। Worker URL को प्रॉक्सी, फ़ेच, या प्रीव्यू MUST NOT। प्रोटोकॉल एक स्ट्रिंग संग्रहित करता है; रेंडरिंग दर्शक-पक्ष पर rel="nofollow noopener noreferrer" target="_blank" और लिंक टेक्स्ट के साथ प्रदर्शित एक दृश्य होस्ट के साथ होती है।

चिंतन। वैकल्पिक रचयिता-लिखित चिंतन टेक्स्ट ("क्या बदला, आपने क्या सीखा")। title के समान NFC + शत्रुतापूर्ण-कोडपॉइंट सत्यापन। खाली / केवल-व्हाइटस्पेस इनपुट निर्माण समय पर अनुपस्थित में मुड़ जाता है।

योजना संस्करण। v1 केवल verdict_version = 0x01 का समर्थन करता है। भविष्य की योजना संशोधन इस बाइट को बढ़ाते हैं और §12 के अनुसार एक नए प्रोटोकॉल संस्करण के साथ आते हैं।


7. मुहरबंदी प्रोटोकॉल

पूर्ण मुहरबंदी अनुक्रम। प्रत्येक चरण मानक है।

 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.

संग्रहण टैग परत (बैंड-से-बाहर)। qub अपलोड सेवा रैप किए गए पेलोड के साथ संग्रहण लेन-देन टैग्स का जानबूझकर छोटा सेट संलग्न करती है। Content-Type=application/octet-stream मानक रूप से आवश्यक है। संदर्भ सेवा अतिरिक्त रूप से तीन वैकल्पिक टैग संलग्न करती है जब रचयिता उन्हें सतह पर लाना चुनता है: Intent (allowlist-सत्यापित compose intent — उदा. quote, reply, commitment), Author (रचयिता की §9.3 पबकी फ़िंगरप्रिंट 64-वर्ण लोअरकेस हेक्स के रूप में), और Parent-Tx-Id (उत्तर शृंखलाओं के लिए मूल qub का संग्रहण लेन-देन ID, 43-वर्ण base64url)।

Author टैग प्रति qub ऑप्ट-इन है: संदर्भ रचयिता ऐप इसे केवल तब संलग्न करता है जब उपयोगकर्ता मुहरबंदी समय पर स्पष्ट रूप से सार्वजनिक श्रेय सक्षम करता है। जब टॉगल बंद होता है — डिफ़ॉल्ट — कोई Author टैग नहीं लिखा जाता और qub चेन पर बिना श्रेय वाला होता है: स्थायी संग्रहण में कुछ भी अपलोड को किसी रचयिता के हैंडल, ईमेल, या अन्य qubs से नहीं जोड़ता। जब टॉगल चालू होता है, Author फ़िंगरप्रिंट §9.5 अनुप्रमाणन शृंखला के माध्यम से रचयिता के चुने हुए @handle से हल हो जाता है। उत्तर-शृंखला संबंध और Intent गैर-पहचानने वाले होते हैं। बाहरी आवरण (§13) सिफरटेक्स्ट सहसंबंध से आंतरिक बॉडी की रक्षा करता है — एक हार्वेस्टर को drand राउंड प्रकाशित होने के बाद qub-आकार के अपलोड को पहचानने और थोक-डिक्रिप्ट करने से रोकता है।

संदर्भ सेवा जानबूझकर App-Name, App-Version, या Type टैग संलग्न नहीं करती: किसी भी ऐसे एकल-मान फ़िल्टर से GraphQL क्वेरी को संपूर्ण qub कॉर्पस वापस मिल जाएगा, जो आवरण के बॉडी-केवल गोपनीयता दायरे के साथ असंगत है।

एक अनुरूप सत्यापनकर्ता §11 तृतीय-पक्ष सत्यापन के लिए किसी भी संग्रहण टैग पर निर्भर MUST NOT; बॉडी हैश / qub_id / हस्ताक्षर केवल आंतरिक CBOR के लिए प्रतिबद्ध होते हैं, टैग सेट के लिए कभी नहीं।


8. अनलॉक प्रोटोकॉल

पूर्ण अनलॉक अनुक्रम। प्रत्येक चरण मानक है।

 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. लेखकत्व हस्ताक्षर

9.1 तर्क

qubs स्थायी संग्रहण में संग्रहीत किए जाते हैं। लेखकत्व हस्ताक्षरों को अनिश्चित काल तक अजेय बने रहना चाहिए, यही कारण है कि v1.0 शास्त्रीय योजना के बजाय उत्तर-क्वांटम ML-DSA-65 योजना (FIPS 204) का उपयोग करता है जिसकी सुरक्षा qub के स्थायी जीवनकाल के भीतर ख़राब हो सकती है।

9.2 एल्गोरिथम रजिस्ट्री

sig_alg योजना कुंजी आकार हस्ताक्षर आकार
0x00 कोई हस्ताक्षर नहीं (अहस्ताक्षरित)
0x01 ML-DSA-65 (FIPS 204) 1,952 बाइट्स 3,309 बाइट्स

दर्शक अज्ञात sig_alg मानों को अस्वीकार करना MUST।

9.3 हस्ताक्षरित प्रीइमेज निर्माण

दो प्रीइमेज संस्करण अस्तित्व में रहे हैं। सभी हस्ताक्षर V2 का उपयोग करना MUST, और सत्यापनकर्ता केवल V2 स्वीकार करना MUST। पूर्ववर्ती V1 प्रीइमेज (ऐतिहासिक संदर्भ के लिए नीचे प्रलेखित) को V2 माइग्रेशन के दौरान केवल-सत्यापन फ़ॉलबैक के रूप में स्वीकार किया जाता था; उस फ़ॉलबैक को वापस ले लिया गया है और अब केवल-V1 हस्ताक्षर अस्वीकार किया जाता है।

V2 (वर्तमान — सभी नए लेखक हस्ताक्षर द्वारा, और संधि स्टेजिंग / सह-हस्ताक्षर प्रवाह के दोनों हस्ताक्षरों द्वारा उत्पन्न):

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)

sender_label_hash वही अनुपस्थित-सेंटिनल परिपाटी का पालन करता है जो title_hash (§4.2.1) करता है: 32 शून्य बाइट्स एक वैध SHA3-256 आउटपुट नहीं हैं, इसलिए "अनुपस्थित" कभी भी किसी उपस्थित लेबल से टकरा नहीं सकता। सभी क्षेत्र निश्चित-चौड़ाई के हैं, इसलिए प्रीइमेज लंबाई उपसर्गों के बिना असंदिग्ध है।

V1 (पूर्ववर्ती — वापस लिया गया; अब उत्पन्न नहीं किया जाता और सत्यापन पर अब स्वीकार नहीं किया जाता):

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

V1 प्रीइमेज ने sender_label और reply_to को छोड़ दिया था। इसे V2 में माइग्रेशन के दौरान केवल-सत्यापन फ़ॉलबैक के रूप में स्वीकार किया जाता था; तब से उस फ़ॉलबैक को वापस ले लिया गया है — सत्यापनकर्ता केवल V2 प्रीइमेज स्वीकार करना MUST। परिभाषा यहाँ ऐतिहासिक संदर्भ के लिए और नीचे दिए गए डोमेन विभाजक को समझाने के लिए बनाए रखी गई है। जो हस्ताक्षर केवल V1 के विरुद्ध सत्यापित होता है, उसे सत्यापन विफलता के रूप में माना जाना MUST।

डोमेन विभाजक: "QUB_AUTHOR_SIG_V1" / "QUB_AUTHOR_SIG_V2" प्रत्येक 17 ASCII बाइट्स हैं ([0x51, 0x55, 0x42, 0x5F, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x5F, 0x53, 0x49, 0x47, 0x5F, 0x56, 0x31/0x32])। कोई पैडिंग नहीं। भिन्न विभाजक दोनों निर्माणों को डोमेन-पृथक करता है, इसलिए एक प्रीइमेज पर किया गया हस्ताक्षर कभी भी दूसरे के रूप में सत्यापित नहीं हो सकता।

org_id_present बाइट: unlock_at के बाद आने वाला बाइट 0x00 होना MUST। संदर्भ कार्यान्वयन इसे crates/qub-core/src/signing.rs में स्थिर ORG_ID_PRESENT_INDIVIDUAL = 0x00 के रूप में उजागर करता है; सत्यापन के लिए sig_input का पुनर्निर्माण करने वाले दर्शक उसी बाइट को उत्सर्जित करना MUST।

हस्ताक्षर दायरा — क्या कवर है और क्या नहीं। V2 sig_input सीधे version, qub_id, body_hash, unlock_at, sender_label, और reply_to के लिए प्रतिबद्ध होता है (साथ ही स्थिर डोमेन विभाजक और org_id_present बाइट)। qub_id स्वयं §4.1 प्रीइमेज के माध्यम से version, content_type, created_at, unlock_at, outcome_at, drand_round, और body_hash से व्युत्पन्न होता है, इसलिए उन क्षेत्रों में कोई भी परिवर्तन एक अलग qub_id उत्पन्न करता है और सकर्मक रूप से हस्ताक्षर को अमान्य कर देता है। इसलिए प्रमाणित सतह है:

क्षेत्र हस्ताक्षर द्वारा प्रमाणित कैसे
version sig_input के लिए सीधा इनपुट
qub_id सीधा इनपुट
body_hash सीधा इनपुट
unlock_at सीधा इनपुट
sender_label sender_label_hash के माध्यम से सीधा इनपुट (V2 प्रीइमेज — एकमात्र स्वीकृत रूप)
reply_to reply_to_or_zero के माध्यम से सीधा इनपुट (V2 प्रीइमेज — एकमात्र स्वीकृत रूप)
content_type सकर्मक रूप से, qub_id प्रीइमेज के माध्यम से
created_at सकर्मक रूप से, qub_id प्रीइमेज के माध्यम से
outcome_at सकर्मक रूप से, qub_id प्रीइमेज के माध्यम से
drand_round सकर्मक रूप से, qub_id प्रीइमेज के माध्यम से (V1.2)
body सकर्मक रूप से, body_hash = SHA3-256(body) के माध्यम से
author_pubkey — (निहित) हस्ताक्षर सत्यापित करने वाली कुंजी ही परिभाषा के अनुसार लेखक है
cosigner_pubkey / cosigner_signature उसी sig_input पर स्वतंत्र रूप से हस्ताक्षरित (देखें §9.7)
drand_chain_id, tlock_ciphertext, visibility बाहरी SealedQub क्षेत्र, एनवेलप के अंदर नहीं — अपने स्वयं के संरचनात्मक अपरिवर्तनीयों (राउंड / चेन संगति) द्वारा कवर, लेकिन लेखक हस्ताक्षर द्वारा नहीं। (drand_round अब qub_id प्रीइमेज के माध्यम से सकर्मक रूप से बंधा है — ऊपर देखें।)

V2 ही एकमात्र स्वीकृत प्रीइमेज क्यों है।

जो कार्यान्वयन अंतिम उपयोगकर्ताओं को sender_label या reply_to प्रदर्शित करते हैं, उन्हें प्राथमिक पहचान संकेत के रूप में प्रमाणित पहचान (पबकी फ़िंगरप्रिंट, अनुप्रमाणन) को सतह पर लाना MUST, लेबल को नहीं।

9.4 सत्यापन प्रक्रिया

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."

हस्ताक्षर सत्यापन सबसे महंगा ऑपरेशन है (विशेष रूप से ML-DSA-65)। इसे सभी सस्ती जाँचों (हैश, qub_id, unlock_at) के पारित होने के बाद ही किया जाना SHOULD।

9.5 पहचान अनुप्रमाणन

पहचान अनुप्रमाणन — author_pubkey का मानव-पहचानने योग्य पहचान दावों जैसे qub हैंडल, ईमेल पता, सोशल हैंडल, या पासकी क्रेडेंशियल से मानचित्रण — एक दर्शक-पक्ष प्रगतिशील संवर्धन है और हस्ताक्षर सत्यापन के लिए आवश्यक नहीं है। प्रदर्शन पहचान के लिए अनुप्रमाणन हल करने वाले दर्शक वरीयता क्रम लागू करना MUST:

handle > email > social > fingerprint

फ़िंगरप्रिंट फ़ॉलबैक SHA3-256(author_pubkey) का लोअरकेस हेक्स है; यह किसी भी हस्ताक्षरित qub के लिए हमेशा उपलब्ध है। दर्शक प्रदर्शन के लिए इसे संक्षिप्त करना MAY — संदर्भ दर्शक qub: के बाद पहले और अंतिम चार बाइट्स (qub:<8 hex>…<8 hex>) रेंडर करता है।

एक अनुरूप सत्यापनकर्ता qub API से संपर्क किए बिना, स्थायी संग्रहण और drand से परे किसी भी नेटवर्क के बिना, और किसी भी सर्वर-साइड लुकअप के बिना §9.4 में हर जाँच पूरी कर सकता है। अनुप्रमाणन समाधान केवल हस्ताक्षर सत्यापन सफल होने के बाद किया गया एक अलग सर्वोत्तम-प्रयास चरण है।

9.6 आकार प्रभाव

Ed25519 ML-DSA-65
हस्ताक्षर 64 बाइट्स 3,309 बाइट्स
सार्वजनिक कुंजी 32 बाइट्स 1,952 बाइट्स
प्रति qub कुल 96 बाइट्स 5,261 बाइट्स
संग्रहण लागत अंतर (~$5/MB पर) ~$0.0005 ~$0.026

500–2,000 बाइट्स के टेक्स्ट qub के लिए, ML-DSA-65 लगभग संग्रहीत आकार को तिगुना कर देता है। निरपेक्ष लागत नगण्य है।

9.7 सह-हस्ताक्षरकर्ता सत्यापन (संधि द्विपक्षीय समझौते)

द्विपक्षीय समझौतों (content_type = 0x03) के लिए, एक दूसरी हस्ताक्षर परत प्रमाणित करती है कि दोनों पक्षों ने समान शर्तों के लिए सहमति दी।

एनवेलप क्षेत्र:

दोनों क्षेत्र एक साथ उपस्थित MUST या दोनों अनुपस्थित। यदि ठीक एक उपस्थित है, तो दर्शक अखंडता त्रुटि की रिपोर्ट करना MUST।

सत्यापन प्रक्रिया:

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."

गुण:

ईमेल-बंधन गेट (परिचालन)। जब एक स्टेज की गई संधि एक पक्ष B ईमेल संपर्क (§6.1) ले जाती है, तो qub अपलोड सेवा सह-हस्ताक्षर अनुरोध को अस्वीकार करना MUST जब तक कि एक अल्पकालिक ईमेल-सत्यापन मार्कर मौजूद न हो जो स्टेजिंग id और उस संपर्क के सामान्यीकृत-ईमेल हैश दोनों से मेल खाता हो। मार्कर /api/v1/auth/verify द्वारा लिखा जाता है जब मैजिक-लिंक टोकन staging_id ले जाता है और सत्यापित पता SHA-256(normalise_email(party_b.contact)) से मेल खाता है — जहाँ normalise_email(addr) स्थानीय-भाग के केस को संरक्षित करता है और केवल डोमेन भाग को लोअरकेस करता है (RFC 5321 §2.3.11 के अनुसार), और SHA-256 यहाँ NIST FIPS 180-4 हैश है (§4 व्युत्पत्तियों में उपयोग किए जाने वाले SHA3-256 से अलग) — और जारी होने के 900 सेकंड (15 मिनट) बाद समाप्त हो जाता है। यह एक परिचालन प्रति-प्रतिरूपण गेट है, ऑन-चेन qub प्रमाण का हिस्सा NOT — एक तृतीय-पक्ष सत्यापनकर्ता जो §11 को रिप्ले कर रहा है, उसे केवल स्थायी संग्रहण और drand की आवश्यकता होती है, बिना किसी सर्वर-साइड लुकअप के। मार्कर केवल सर्वर-साइड मौजूद है और हस्ताक्षरित बॉडी का हिस्सा कभी नहीं होता।

आकार प्रभाव (ML-DSA-65 लेखक + सह-हस्ताक्षरकर्ता):

घटक आकार
लेखक हस्ताक्षर 3,309 बाइट्स
लेखक सार्वजनिक कुंजी 1,952 बाइट्स
सह-हस्ताक्षरकर्ता हस्ताक्षर 3,309 बाइट्स
सह-हस्ताक्षरकर्ता सार्वजनिक कुंजी 1,952 बाइट्स
कुल क्रिप्टो ओवरहेड 10,522 बाइट्स
संग्रहण लागत अंतर ~$0.05

10. मार्कडाउन रेंडरिंग और स्वच्छीकरण

यह अनुभाग सुरक्षा-गंभीर है। दर्शक एक प्रतिबंधित मार्कडाउन उपसमुच्चय का उपयोग करके टेक्स्ट qubs (content_type = 0x01) को रेंडर करता है।

10.1 अनुमत तत्व

10.2 निषिद्ध तत्व

तत्व संभालन
कच्चा HTML (<div>, <script>, इत्यादि) पूरी तरह से हटा दिया जाता है। कोई HTML पास नहीं होता।
छवियाँ (![alt](url)) हटा दी जाती हैं। आउटपुट से छवि सिंटैक्स हटा दिया जाता है।
लिंक ([text](url)) URL दृश्यमान सादा टेक्स्ट के रूप में रेंडर किया जाता है। ऑटो-लिंक नहीं। स्पष्ट उपयोगकर्ता क्रिया के बिना क्लिक करने योग्य नहीं।
खतरनाक URL योजनाएँ javascript:, data:, vbscript:, file: — हटा दिए जाते हैं।
Iframes, embeds, objects हटा दिए जाते हैं।
HTML इकाइयाँ केवल सुरक्षित होने पर प्रदर्शन वर्णों में डिकोड की जाती हैं।

10.3 कार्यान्वयन

कार्यान्वयन एक सख्त अनुमति-सूची पार्सर का उपयोग करना MUST, अवरुद्ध-सूची का नहीं। अनुशंसित दृष्टिकोण:

  1. pulldown-cmark (या समकक्ष) का उपयोग करके मार्कडाउन पार्स करें।
  2. AST के माध्यम से चलें और अनुमति-सूची (§10.1) में नहीं किसी भी नोड को छोड़ दें।
  3. लिंक नोड्स के लिए: URL को दृश्यमान टेक्स्ट के रूप में उत्सर्जित करें, क्लिक करने योग्य <a> तत्व के रूप में नहीं।
  4. फ़िल्टर किए गए AST को एक टाइप्ड मध्यवर्ती प्रतिनिधित्व (उदा. केवल सुरक्षित वैरिएंट्स के साथ एक MarkdownNode enum) में परिवर्तित करें। इस IR में कच्चा HTML संरचनात्मक रूप से अप्रतिनिधित्व योग्य है।
  5. टाइप्ड IR से लक्ष्य व्यू परत (उदा. प्रतिक्रियाशील व्यू घटक, DOM नोड्स) में रेंडर करें। किसी भी बिंदु पर कोई HTML स्ट्रिंग संयोजन या innerHTML नहीं।

अवरुद्ध-सूची दृष्टिकोण नाजुक हैं क्योंकि नए मार्कडाउन एक्सटेंशन या पार्सर विचित्रताएँ अनफ़िल्टर्ड तत्वों को पेश कर सकती हैं। टाइप्ड-AST दृष्टिकोण XSS को संरचनात्मक रूप से असंभव बनाता है — कोई वैरिएंट नहीं है जो मनमाने HTML को ले जा सके।

10.4 आकार और संरचना सीमाएँ


11. तृतीय-पक्ष सत्यापन

कोई भी तृतीय पक्ष qub सहयोग के बिना सार्वजनिक qub को सत्यापित कर सकता है। सत्यापन प्रक्रिया:

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.

सत्यापन क्या प्रमाणित करता है:

प्रमाण यह क्या स्थापित करता है
प्रतिबद्धता संग्रहण ब्लॉक टाइमस्टैम्प द्वारा सिफरटेक्स्ट मौजूद था।
अखंडता प्लेनटेक्स्ट बॉडी प्रतिबद्ध हैश से मेल खाती है और बदली नहीं गई है।
समय सामग्री drand राउंड तक अपठनीय थी, जो चुने हुए अनलॉक समय (tlock और drand सुरक्षा धारणाओं के अधीन) से मेल खाती है।

सत्यापन क्या प्रमाणित नहीं करता:

गैर-प्रमाण क्यों
लेखकत्व sender_label सजावटी है। sig_alg0x01 के बिना, कोई भी इस सामग्री को मुहरबंद कर सकता था।
इरादा qub सामग्री और समय प्रमाणित करता है, यह नहीं कि रचयिता ने व्यक्तिपरक रूप से क्या मतलब किया।
पूर्व-घटना समय संग्रहण ब्लॉक समावेशन वास्तविक अपलोड से मिनटों से पीछे हो सकता है। प्रतिबद्धता टाइमस्टैम्प ब्लॉक समय है, उस क्षण नहीं जब उपयोगकर्ता ने "मुहर लगाएँ" दबाया।

12. संस्करण

12.1 प्रोटोकॉल संस्करण

SealedQub और QubEnvelope दोनों में version क्षेत्र (u8) मुख्य प्रोटोकॉल संस्करण की पहचान करता है।

12.2 संस्करण इतिहास

संस्करण मान विवरण
v1 0x01 सार्वजनिक टेक्स्ट qubs (content_type 0x01), संधि द्विपक्षीय समझौते (0x03, structured/v1 योजना, ML-DSA-65 लेखक + सह-हस्ताक्षरकर्ता), tlock, SHA3-256

12.3 फ़ॉरवर्ड संगति

एक v1 दर्शक जो अज्ञात CBOR मानचित्र कुंजियों (§3.2 कैनोनिकल क्रम में नहीं की कुंजियाँ) के साथ QubEnvelope का सामना करता है, उसे एक डिकोड त्रुटि के साथ अस्वीकार करना MUST (§3.1)। फ़ॉरवर्ड संगति version क्षेत्र पर टिकी है, कुंजी सहनशीलता पर नहीं: भविष्य के जोड़ — छोटे मेटाडेटा भी — एक नए version मान के तहत आते हैं, जिसे एक v1 दर्शक एक स्पष्ट "नया प्रोटोकॉल" त्रुटि के साथ अस्वीकार करता है — बजाय इसके कि वह उस सामग्री को चुपचाप गिरा दे जिसके लिए हस्ताक्षर प्रतिबद्ध होते हैं।

एक v1 दर्शक जो sig_alg = 0x01 (ML-DSA-65) का सामना करता है लेकिन ML-DSA-65 सत्यापन समर्थन की कमी है, qub सामग्री को "हस्ताक्षर उपस्थित लेकिन सत्यापन योग्य नहीं" सूचना के साथ प्रदर्शित करना SHOULD, qub को पूरी तरह से अस्वीकार नहीं करना। संदर्भ कार्यान्वयन आज 0x00 और 0x01 के अलावा हर sig_alg मान को अस्वीकार करता है क्योंकि v1 रजिस्ट्री में कोई अन्य मान्य एल्गोरिथम नहीं है — सख्त अस्वीकृति और सॉफ्ट-फ़ेल तब तक अवलोकनात्मक रूप से समान हैं जब तक कि एक तीसरा एल्गोरिथम पंजीकृत न हो। ऊपर का सॉफ्ट-फ़ेल व्यवहार तब भार-वहन करने वाला हो जाता है जब §9.2 एक नई प्रविष्टि स्वीकार करता है, और संदर्भ दर्शक उस बिंदु पर सॉफ्ट-फ़ेल करने के लिए अद्यतन किया जाएगा।

12.4 बाहरी आवरण संस्करण

§13 में वर्णित OuterWrapper अपना स्वयं का version बाइट ले जाता है, स्वतंत्र SealedQub.version और QubEnvelope.version से। दो संस्करण स्थान अलग-अलग विकसित होते हैं: एक भविष्य का उत्तर-क्वांटम-सुरक्षित सममित प्रतिस्थापन आंतरिक प्रोटोकॉल संस्करण को छुए बिना आवरण बाइट को उछालता है, और एक भविष्य का प्रोटोकॉल-परत जोड़ (उदा. एक नया एनवेलप क्षेत्र) आवरण बाइट को छुए बिना आंतरिक संस्करण को उछालता है।

OUTER_WRAPPER_VERSION_* मान एल्गोरिथम स्थिति
OUTER_WRAPPER_VERSION_1 0x01 AES-256-GCM 12-बाइट nonce, 16-बाइट प्रमाणीकरण टैग, AAD qub_id से बंधा v1 डिफ़ॉल्ट
0x020xFF आरक्षित भविष्य

दर्शक अज्ञात आवरण संस्करणों को एक स्पष्ट त्रुटि के साथ अस्वीकार करना MUST। प्रोटोकॉल जानबूझकर आवरण संस्करण स्थान को संकीर्ण रखता है जब तक कि एक ठोस माइग्रेशन चालक प्रकट नहीं होता (उदा. एक अलग AEAD के पक्ष में NIST मार्गदर्शन); एक 0x02 स्लॉट उसी संशोधन में आवंटित किया जाएगा जो एल्गोरिथम का परिचय देता है।


13. बाहरी एन्क्रिप्शन आवरण

13.1 तर्क

प्रोटोकॉल परतें (QubEnvelope → tlock → SealedQub) एक मुहरबंद qub को समय-बद्ध बनाती हैं: बॉडी unlock_at तक अपठनीय है और drand राउंड हस्ताक्षर प्रकाशित हो चुका है। हालाँकि, अनलॉक के बाद, राउंड हस्ताक्षर सार्वजनिक है और SealedQub का कैनोनिकल CBOR आकार पहचानने योग्य है, इसलिए एक हार्वेस्टर जिसने स्थायी-संग्रहण लेन-देन को अनुक्रमित किया है, संपूर्ण qub कॉर्पस को थोक-डिक्रिप्ट कर सकता है।

बाहरी एन्क्रिप्शन आवरण कैनोनिकल SealedQubCbor और स्थायी संग्रहण में लिखे गए बाइट्स के बीच एक अतिरिक्त सममित AEAD परत डालकर उस चैनल को बंद कर देता है। 256-बिट कुंजी K डिलीवरी URL के URL फ़्रैगमेंट में और उपयोगकर्ता डिवाइसों पर केवल रहती है; ब्राउज़र URL फ़्रैगमेंट सर्वर को संचारित नहीं करते, इसलिए qub.social, हर संग्रहण गेटवे, और दोनों के सामने हर CDN K के लिए अवलोकनात्मक रूप से अंधे हैं। स्थायी संग्रहण में हर qub इसलिए एक अपारदर्शी सिफरटेक्स्ट है जिसका प्लेनटेक्स्ट उस URL के बिना अप्राप्य है जिसे रचयिता ने साझा करने के लिए चुना।

शुद्ध प्रभाव:

13.2 परतीकरण

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)

प्रोटोकॉल परत (§7, §8) पर मुहरबंदी और अनलॉक आवरण सीमा के नीचे अपरिवर्तित हैं; आवरण seal() के कॉल साइट पर जुड़ता है और unlock() के कॉल साइट पर अलग होता है।

13.3 OuterWrapper डेटा संरचना

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
}

क्षेत्र अपरिवर्तनीय।

CBOR एन्कोडिंग। §3 के अनुसार कैनोनिकल CBOR, उसी कुंजी-क्रम नियम के साथ (एन्कोडेड बाइट लंबाई आरोही द्वारा क्रमबद्ध, फिर शब्दकोश)। चार कुंजियाँ हैं:

कुंजी एन्कोडेड बाइट्स क्रम
nonce 6 1
qub_id 7 2
version 8 3
ciphertext 11 4

OuterWrapper CBOR का पहला बाइट इसलिए 4-प्रविष्टि मानचित्र (0xA4) के लिए निश्चित-लंबाई मानचित्र हेडर है।

13.4 qub_id के लिए AAD बंधन

आवरण qub_id को AEAD अतिरिक्त प्रमाणित डेटा के रूप में बांधता है। यह तीन वर्ग के हमलों के विरुद्ध भार-वहन करने वाली संरचनात्मक रक्षा है:

हमला रक्षा
आवरण में एक अलग qub_id क्षेत्र के तहत सिफरटेक्स्ट स्थानांतरित करें AAD बेमेल → AEAD प्रमाणीकरण विफल
qub A के URL फ़्रैगमेंट को qub B के स्थायी-संग्रहण बाइट्स के साथ मिलाएँ AAD बेमेल → AEAD प्रमाणीकरण विफल
अपलोड के बाद आवरण के qub_id क्षेत्र से छेड़छाड़ करें AAD बेमेल → AEAD प्रमाणीकरण विफल

आवरण प्लेनटेक्स्ट में qub_id ले जाना गणन प्रतिरक्षा को सार्थक रूप से कमज़ोर नहीं करता — qub_id स्वयं §4.1 प्रीइमेज का SHA3-256 हैश है जिसमें डाइजेस्ट से कोई पुनर्प्राप्ति योग्य प्रीइमेज नहीं है, और एक गणक जिसने पहले से आवरण बाइट्स को काटा है, दृश्यमान qub_id से कुछ नहीं सीखता जो वे अपलोड के अस्तित्व से अनुमान नहीं लगा सकते।

13.5 रैप और अनरैप एल्गोरिथम

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

विफलता-मोड पतन। ग़लत K, ग़लत nonce, AAD बेमेल, और छेड़छाड़ किया गया सिफरटेक्स्ट सभी एक ही DECRYPT_FAILED त्रुटि उत्पन्न करते हैं। यह एक जानबूझकर AEAD गुण है: विफलता मोड को अलग करने से एक साइड चैनल बनेगा जिसे एक दूरस्थ हमलावर विकृत आवरण भेजकर और प्रतिक्रिया को समयित करके जाँच सकता है। संदर्भ कार्यान्वयन सभी AEAD विफलताओं को एकल त्रुटि आकार में संक्षेपित करना MUST।

13.6 कुंजी सामग्री और वितरण

रैपिंग कुंजी K एक प्रति-qub CSPRNG द्वारा उत्पन्न एक 256-बिट समान यादृच्छिक मान है। संदर्भ कार्यान्वयन इसे यहाँ से प्राप्त करते हैं:

वितरण: K को URL-सुरक्षित base64 (RFC 4648 §5, कोई पैडिंग नहीं) के रूप में एन्कोड किया जाना MUST और फ़्रैगमेंट घटक के रूप में डिलीवरी URL में जोड़ा जाना MUST:

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

फ़्रैगमेंट को किसी भी सर्वर को एक अनुरूप ब्राउज़र द्वारा कभी संचारित नहीं किया जाता। पुनर्प्राप्ति चैनल (सर्वर-साइड इतिहास सूचकांक, ऑप्ट-इन ईमेल ऑटो-सेंड) जो उपयोगकर्ता डिवाइस से परे पूर्ण डिलीवरी URL — फ़्रैगमेंट सहित — को बनाए रखते हैं, डिफ़ॉल्ट क्रिप्टो-श्रेडिंग मुद्रा के विरुद्ध एक स्पष्ट व्यापार हैं और स्पष्ट उपयोगकर्ता सहमति पर गेट किए जाने MUST।

फ़्रैगमेंट हानि। यदि एक उपयोगकर्ता URL फ़्रैगमेंट खो देता है और कोई पुनर्प्राप्ति चैनल नहीं है, तो qub अपठनीय है। यह डिज़ाइन का भार-वहन करने वाला व्यापार है और मुहरबंदी समय पर उपयोगकर्ता को प्रकट किया जाना MUST। MVP मुहरबंदी-समय प्रकटीकरण को स्पष्ट "इस URL को सहेजें" प्रति और ऑप्ट-इन करने वाले उपयोगकर्ताओं के लिए एक सत्यापित-ईमेल पुनर्प्राप्ति चैनल के साथ मज़बूत करता है।

13.7 इस अनुभाग के लिए दायरे से बाहर

13.8 सार्वजनिक qubs (आवरण लोप)

बाहरी आवरण वितरण परत पर वैकल्पिक है। एक रचयिता एक qub को सार्वजनिक के रूप में मुहरबंद कर सकता है, जिस स्थिति में कैनोनिकल SealedQubCbor को स्थायी संग्रहण में सीधे लिखा जाता है, बिना किसी OuterWrapper परत और बिना कुंजी K के:

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

एक सार्वजनिक qub समय-बद्ध है लेकिन लिंक-नियंत्रित नहीं: यह तब तक अपठनीय रहता है जब तक इसका drand राउंड प्रकाशित नहीं हो जाता (tlock परत अपरिवर्तित है), लेकिन अनलॉक के बाद कोई भी जिसके पास arweave_tx_id है इसे डिक्रिप्ट कर सकता है — किसी URL फ़्रैगमेंट की आवश्यकता नहीं, क्योंकि कोई K नहीं है। यह उन सतहों के लिए जानबूझकर किया गया व्यापार है जिन्हें सर्वर को चलाना MUST: प्रकट-समय अधिसूचना ईमेल, तृतीय-पक्ष एम्बेड, और समृद्ध प्रकट-के-बाद SEO सभी को एक ऐसे लिंक की आवश्यकता है जो उस रहस्य के बिना काम करे जिसे सर्वर कभी धारण नहीं करता (§13.6)।

परिणाम जिनके लिए एक उत्पादक को MUST हिसाब रखना:

निजी (रैप किया हुआ) डिफ़ॉल्ट बना रहता है; सार्वजनिक एक स्पष्ट प्रति-qub रचयिता विकल्प है।


14. परीक्षण सदिश

14.1 qub_id व्युत्पत्ति

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

कार्यान्वयन इस इनपुट के लिए समान body_hash और qub_id मान उत्पन्न करना MUST। यह परीक्षण सदिश पहली यूनिट परीक्षण के रूप में लिखा जाना SHOULD। ऊपर कैनोनिकल मान संदर्भ कार्यान्वयन द्वारा गणना किए गए थे और बिट-दर-बिट मेल खाना MUST। ऐतिहासिक प्रीइमेज विन्यास (प्री-लॉन्च — कोई जीवित qubs इन पर निर्भर नहीं थे): 92-बाइट V1.0 qub_id 3d9fc2390eab043d38a1669ed3b71be76f9eefe872b9569ab1aaa027b88392b0 था; 100-बाइट V1.1 qub_id (outcome_at_or_zero मोड़ने के बाद) b0d032898ad629795150fdcb3f84e518f59ed05b7a2a82bc24ebdb87f52144ed था। V1.2 drand_round को मोड़ता है और डोमेन विभाजक को QUB_ID_V2 तक बढ़ाता है।

14.2 Unlock-Round मानचित्रण

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 कैनोनिकल CBOR राउंड-ट्रिप

कार्यान्वयन सत्यापित करना MUST कि सभी मान्य इनपुट्स के लिए serialize(parse(serialize(qub))) == serialize(qub)। यह एक गुण परीक्षण है, एकल सदिश नहीं।

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)

कैनोनिकल CBOR बाइट्स और SHA3-256 body_hash संदर्भ कार्यान्वयन द्वारा गणना किए जाते हैं। कार्यान्वयन इस इनपुट के लिए बाइट-समान CBOR उत्पन्न करना MUST।

कार्यान्वयन यह भी सत्यापित करना MUST कि सभी मान्य PactTerms इनपुट्स के लिए serialize(parse(serialize(pact))) == serialize(pact) (गुण परीक्षण)।

14.5 बाहरी आवरण क्रॉस-भाषा सदिश

बाहरी आवरण (§13) का crates/qub-core/tests/vectors/wrapper_v1.json पर एक अलग कैनोनिकल फ़िक्स्चर है। प्रत्येक मामला अपारदर्शी हेक्स इनपुट्स के रूप में एक (key, nonce, qub_id, sealed_cbor) टपल को स्थिर करता है और एक विशिष्ट expected_wrapper_hex आउटपुट पर ज़ोर देता है। दोनों संदर्भ कार्यान्वयन समान JSON फ़ाइल का उपभोग करते हैं:

फ़िक्स्चर वर्तमान में तीन मामलों को पिन करता है:

मामला कवरेज
basic-text-public सबसे छोटा यथार्थवादी SealedQub आकार; कोई वैकल्पिक क्षेत्र नहीं। एक v1.0-विशिष्ट qub के लिए कैनोनिकल आवरण आकार स्थापित करता है।
with-recipient-pubkey recipient_pubkey सेट के साथ SealedQub (चरण 2 पथ)। अलग आंतरिक CBOR कुंजी सेट, अलग qub_id
longer-body ~4 KiB बॉडी — आंतरिक एनवेलप और बाहरी सिफरटेक्स्ट दोनों के अंदर मल्टी-बाइट CBOR लंबाई उपसर्ग का अभ्यास करता है।

कार्यान्वयन रिकॉर्ड किए गए इनपुट्स के लिए बाइट-समान expected_wrapper_hex उत्पन्न करना MUST। फ़िक्स्चर का पुनर्जनन QUB_REGEN_VECTORS=1 cargo test -p qub-core --test wrapper_vectors की आवश्यकता है और जानबूझकर प्रारूप परिवर्तनों के लिए आरक्षित है।


15. क्रिप्टो प्रोफ़ाइल शासन (भविष्य)

यह अनुभाग v1 के लिए सूचनात्मक है और तब मानक बनता है जब पहली बार qub के किसी क्रिप्टोग्राफ़िक आदिम में दूसरा एल्गोरिथम प्रवेश करता है।

15.1 वर्तमान मुद्रा

प्रोटोकॉल v1 प्रति आदिम ठीक एक एल्गोरिथम बांधता है:

सत्यापनकर्ता वर्तमान में प्रति आदिम कुंजी और हस्ताक्षर लंबाइयों को हार्डकोड करते हैं। वायर प्रारूप द्वारा कोई चपलता सतह उजागर नहीं की गई है।

15.2 अभिप्रेत आकार

जब एक दूसरा एल्गोरिथम प्रोटोकॉल में प्रवेश करता है, तो सत्यापनकर्ता को एक नामित CryptoProfile (उदा. ExqubV1) के लिए कॉन्फ़िगर किया जाएगा जो प्रति आदिम अनुमत मानों के सटीक सेट को सूचीबद्ध करता है — sig_algs, drand चेन, आवरण संस्करण, सामग्री प्रकार। प्रोफ़ाइल सत्यापन समय पर तय की जाती है, कभी इन-बैंड बातचीत नहीं की जाती। सक्रिय प्रोफ़ाइल के बाहर का कोई भी मान अस्वीकार कर दिया जाता है।

यह सुनिश्चित करता है कि ML-DSA-87 जोड़ना या Ed25519 सक्रिय करना मौजूदा सत्यापनकर्ता कॉन्फ़िगरेशन को पीछे की ओर कमज़ोर नहीं कर सकता: एक v1 सत्यापनकर्ता एक v2 प्रोफ़ाइल प्रकाशित होने के बाद भी v1 सत्यापनकर्ता ही रहता है।

15.3 ट्रिगर शर्तें

§15 को मानक स्थिति में पदोन्नत करें जब निम्नलिखित में से कोई प्रस्तावित हो:

तब तक §15 एक प्लेसहोल्डर है जो माइग्रेशन आकार को स्थिर करता है ताकि भविष्य के PRs बातचीत सतह को नए सिरे से पुनः-निर्धारित करने के बजाय एक ज्ञात लक्ष्य के विरुद्ध उतरें।


16. पारदर्शिता लॉग और स्थायित्व स्तर (डिज़ाइन — समीक्षा पूर्ण)

स्थिति. यह अनुभाग एक डिज़ाइन विनिर्देश है। नीचे दिए गए वायर प्रारूप, हैशिंग, और विश्वास मॉडल कार्यान्वयन के लिए मानक हैं, लेकिन अभी तक कोई पारदर्शिता-लॉग कोड शिप नहीं हुआ है। W5 बाहरी समीक्षा पूर्ण है: §16.15 हल किए गए निर्णयों और उससे निकली बाध्यकारी लॉन्च बाधाओं को दर्ज करता है। कार्यान्वयन उन बाधाओं के तहत आगे बढ़ सकता है। §16 उसी अर्थ में दूरदर्शी रहता है जैसे §15 — यह लक्ष्य को तय करता है ताकि कार्यान्वयन कोड समीक्षा में विश्वास मॉडल को नए सिरे से व्युत्पन्न करने के बजाय एक तय किए गए डिज़ाइन के विरुद्ध उतरे। यह कड़ाई से योगात्मक है — हर मौजूदा qub अपना व्यक्तिगत स्थायी-संग्रहण लेन-देन रखता है और SealedQub / QubEnvelope वायर प्रारूप में कोई परिवर्तन नहीं है।

16.1 तर्क और स्थायित्व स्तर

आज एक qub का स्थायित्व और उसकी समयबद्ध प्रतिबद्धता दोनों एक एकल प्रति-qub स्थायी-संग्रहण लेन-देन (§11) पर टिके हैं। यह मुहरबंदी विलंबता को स्थायी-संग्रहण अंतिमता से जोड़ता है, प्रति-qub अपलोड को एक उत्पाद लागत सीमा (ARWEAVE_DAILY_CEILING) बनाता है, और qubs के बीच कोई छेड़छाड़-स्पष्ट क्रम नहीं देता। पारदर्शिता लॉग उस एकल स्तर के नीचे और चारों ओर दो परतें जोड़ता है:

स्तर नाम गारंटी कब
T1 R2-प्रथम तुल्यकालिक ack स्थायित्व तल — मुहरबंदी लौटने से पहले मुहरबंद बाइट्स टिकाऊ संग्रहण में लिखे जाते हैं (< 300 ms p95)। हर qub, तुल्यकालिक रूप से (§16.10)।
T2 बैच की गई पारदर्शिता-लॉग समावेशन सार्वभौमिक केवल-संलग्न, छेड़छाड़-स्पष्ट प्रतिबद्धता + संपूर्ण क्रम, स्थायी संग्रहण से एंकर किया गया। हर qub, स्थगित + बैच किया गया (§16.5–16.7)।
T3 प्रति-qub स्थायी-संग्रहण स्थायित्व qub के लिए एक व्यक्तिगत स्थायी-संग्रहण लेन-देन। सशुल्क अपसेल, और स्थायी-संग्रहण-अनुपलब्धता फ़ॉलबैक (§16.8)।

T2 प्रति-qub स्थायी संग्रहण को एकमात्र स्थायित्व पथ के बजाय एक विकल्प (T3) बनाता है। ARWEAVE_DAILY_CEILING को एक उत्पाद सीमा के रूप में सेवानिवृत्त किया जाता है और केवल समर्पित एंकर वॉलेट पर एक सर्किट ब्रेकर के रूप में पदावनत किया जाता है (§16.7); उपयोगकर्ता मुहरबंदियाँ इसे पार करने के लिए कभी अस्वीकार नहीं की जातीं।

स्थायित्व ईमानदारी (हल — §16.15 Q6)। स्थायित्व पीछे नहीं हटता: T1 R2 लेखन तुल्यकालिक और एक-बार-लेखन है, इसलिए एक मुफ़्त-स्तरीय qub जिसने T3 नहीं खरीदा, मुहरबंदी लौटते ही पूरी तरह टिकाऊ है। जो मोटा होता है वह सिद्ध करने योग्य ऊपरी-सीमा प्रतिबद्धता समय है: एक मुफ़्त qub के लिए यह प्रति-qub लेन-देन ब्लॉक समय के बजाय एंकर ब्लॉक समय बन जाता है। कम मात्रा पर — यथार्थवादी प्रारंभिक-लॉन्च और ऑफ़-पीक स्थिति — पूर्ण दैनिक ताल विशिष्ट तल है, एक दुर्लभ किनारा नहीं। इसलिए उत्पाद फ़्रेमिंग कोई प्रतिबद्ध संख्यात्मक विलंबता रहित एक ऊपरी सीमा है — "अभी मुहरबंद और टिकाऊ; अगले लॉग एंकर पर एक स्वतंत्र सार्वजनिक टाइमस्टैम्प जोड़ा जाता है (आमतौर पर दैनिक)" — और सटीक-घंटा प्रतिबद्धता प्रमाण एक सशुल्क T3 गुण है, जो स्तर-तुलना सतह पर और शर्तों में प्रकट किया जाता है (§16.11, §16.15 Q6)। कोई भी समय सीमा केवल एक आंतरिक SLO है, कभी एक विपणित SLA नहीं।

16.2 LogLeaf संरचना (दो प्रतिबद्ध आकार)

एक लॉग प्रविष्टि एक LogLeaf है, §3.1 प्रोफ़ाइल के तहत हाथ से लिखे कैनोनिकल CBOR के रूप में एन्कोड की गई (निश्चित-लंबाई, कोई टैग नहीं, कोई फ़्लोट नहीं, सबसे-छोटे-रूप पूर्णांक, NFC टेक्स्ट, अनुपस्थित होने पर वैकल्पिक क्षेत्र लोप, कुंजियाँ एन्कोडेड-बाइट लंबाई आरोही फिर शब्दकोश से क्रमबद्ध)। §3.1 parse → re-encode → compare कैनोनिकल गार्ड हैशिंग से पहले एन्कोड पथ पर लागू किया जाता है (केवल डिकोड पर नहीं), इसलिए दो कार्यान्वयन एक पूर्णांक-चौड़ाई या कुंजी-क्रम अंतर के माध्यम से लीफ़ बाइट्स पर असहमत नहीं हो सकते। सभी पूर्णांक u8 / u64 / i64 हैं; सभी डाइजेस्ट 32-बाइट बाइट स्ट्रिंग्स (bstr[32]) हैं। एक संग्रहीत स्थायी-संग्रहण लेन-देन आईडी एक कच्चा 32-बाइट SHA-256 डाइजेस्ट है जो bstr[32] के रूप में वहन किया जाता है, कभी एक base64url टेक्स्ट स्ट्रिंग नहीं (§3.3 से मेल खाता है)।

लीफ़ के एक kind बाइट द्वारा चुने गए दो आकार हैं, क्योंकि डिफ़ॉल्ट अपलोड पथ पर वर्कर बाइट-अंधा है: POST /api/v1/upload केवल qub_id और unlock_at को अविश्वसनीय क्लाइंट दावों के रूप में प्राप्त करता है — body_hash, drand_round, created_at, और drand_chain_version सभी §13 बाहरी आवरण के अंदर मुहरबंद हैं, जिसकी कुंजी वर्कर कभी नहीं रखता। केवल सर्वर-सील पथ (POST /api/v1/seal) प्लेनटेक्स्ट से body_hash / drand_round व्युत्पन्न करता है। body_hash + drand_round वहन करने वाला एक एकल लीफ़ आकार इसलिए ऐसे मान प्रतिबद्ध करेगा जिन्हें ऑपरेटर ने वास्तविक qubs के बहुमत के लिए कभी सत्यापित नहीं किया। यह विभाजन हर प्रतिबद्ध मान को ईमानदार रखता है:

कुंजी एन्क. लंबाई प्रकार उपस्थिति अर्थ
seq 4 u64 आवश्यक वैश्विक 0-आधारित लीफ़ सूचकांक; वह स्थिति जिसके लिए समावेशन प्रमाण प्रतिबद्ध होता है।
kind 5 u8 आवश्यक 0x01 प्रमाणित (सर्वर-सील) या 0x02 दावाकृत (क्लाइंट-सील / बाइट-अंधा अपलोड)।
ref 4 bstr[32] आवश्यक लीफ़ संदर्भ आईडी। प्रमाणित → कच्चा qub_id। दावाकृत → ब्लाइंड की गई आईडी SHA3-256(qub_id ‖ log_blind_secret) (§16.2.1)।
chash 6 bstr[32] आवश्यक सामग्री पता SHA3-256(stored_bytes) — एकमात्र सामग्री संबंध जिसे वर्कर हमेशा ईमानदारी से, दोनों पथों पर, गणना कर सकता है।
unlock_at 10 i64 आवश्यक प्रतिलिपि (प्रमाणित) या दावाकृत (दावाकृत); लीफ़ में प्रवेश करने से पहले > 0 सत्यापित।
received_at 12 i64 आवश्यक R2-ack पर वर्कर वॉल-क्लॉक। गैर-साक्ष्यात्मक (ऑपरेटर-दावाकृत; §16.6)। स्व-विवरण के लिए उपस्थित, कभी एक प्रमाण नहीं। > 0 सत्यापित।
body_hash 10 bstr[32] केवल kind=0x01 0x02 पर लोप — §13 के तहत वर्कर के पास यह नहीं है।
drand_round 12 u64 केवल kind=0x01 0x02 पर लोप।

एक kind=0x02 लीफ़ जानबूझकर न तो body_hash न ही drand_round प्रतिबद्ध करता है: यह सामग्री-पता chash पर एक अपारदर्शी सिफरटेक्स्ट की प्रतिबद्धता और क्रम को प्रमाणित करता है, qub_id और unlock_at का दावा करते हुए — न कि इसके प्लेनटेक्स्ट या राउंड को। एक दावाकृत qub के लिए प्लेनटेक्स्ट/राउंड पाद मौजूदा §11 .qub-बंडल सत्यापन से आते हैं, लॉग से नहीं (§16.11)। drand_chain_version लीफ़ में नहीं है (यह डिफ़ॉल्ट पथ पर आवरण के अंदर है); चेन ग्रैन्युलैरिटी एंकर पर रहती है (§16.7)। एन्कोडर अनुशासन: एक सर्व-शून्य ref या chash अस्वीकार करें, और गैर-धनात्मक unlock_at / received_at अस्वीकार करें, cbor.rs में outcome_at > 0 सेंटिनल गार्ड को प्रतिबिंबित करते हुए।

16.2.1 निजी-qub ब्लाइंडिंग

लॉग को वह गणन ऑरेकल नहीं बनना चाहिए जिसे रोकने के लिए §13 बाहरी आवरण मौजूद है (§13.1)। एक निजी (रैप की गई) qub के लिए asserted लीफ़ ब्लाइंड किया गया पहचानकर्ता SHA3-256(qub_id ‖ log_blind_secret) प्रतिबद्ध करता है, जहाँ log_blind_secret एक सर्वर-धारित गुप्त है, और body_hash लोप करता है। एक तृतीय पक्ष ऐसे लीफ़ को एक विशिष्ट qub_id से नहीं जोड़ सकता; qub का धारक, जिसके पास डिलीवरी URL और इसलिए qub_id है, अपने स्वयं के समावेशन की पुष्टि करने के लिए ब्लाइंड की पुनर्गणना कर सकता है। एक सार्वजनिक qub (पहले से गणनीय, पहले से §13.8 के अनुसार Visibility: public स्थायी-संग्रहण टैग वहन करती हुई) कच्चा qub_id प्रतिबद्ध करती है। यह एकमात्र स्थान है जहाँ स्वतंत्र सत्यापन-योग्यता जानबूझकर एक भार-वहन करने वाले गोपनीयता अपरिवर्तनीय के आगे झुकती है; निजी qubs के लिए स्वतंत्र संबंध chash है (§16.9)।

log_blind_secret अभिरक्षा (हल — §16.15 Q4)। ब्लाइंड लीफ़ अ-संबंधनीयता की रक्षा करता है, प्लेनटेक्स्ट गोपनीयता की नहीं (§13 आवरण उसे स्वतंत्र रूप से धारित करता है)। log_blind_secret समझौते पर, किसी भी qub_id के लिए जो विरोधी पहले से धारित करता है या पुनर्निर्मित कर सकता है (हर qub जिसका बंडल/URL उसके पास है, साथ ही कोई भी कम-एन्ट्रॉपी या सार्वजनिक qub_id) वह एक हैश में लीफ़ ref की पुनर्गणना करता है और उसे जोड़ता है — यह एक ज्ञात जनसंख्या का प्रत्यक्ष संबंधन है, एक अज्ञात स्थान पर ब्रूट-फ़ोर्स नहीं। log_blind_secret को अन्य सर्वर गुप्तों के समान अभिरक्षा स्तर में एक सहसंबंध/Sybil-स्तरीय गुप्त के रूप में वर्गीकृत करें, और केवल आगे की ओर घुमाएँ (एक घुमाव भविष्य के लीफ़ों को पुनः-ब्लाइंड करता है; यह पहले से एंकर किए गए लीफ़ों को पूर्वव्यापी रूप से अ-संबंधित नहीं कर सकता)।

16.3 लीफ़ और नोड हैशिंग

RFC 6962 §2.1 डोमेन-पृथक्कृत हैशिंग जिसमें SHA-256 को SHA3-256 से प्रतिस्थापित किया गया है:

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

डोमेन उपसर्ग बाइट्स 0x02 (प्रविष्टि श्रृंखला, §16.4) और 0x03 (STH हैश, §16.6) आरक्षित हैं और इनसे असंयुक्त हैं। वे एकल बाइट्स हैं और इसलिए मौजूदा 10-बाइट ASCII डोमेन विभाजकों (QUB_ID_V2, आदि) से टकरा नहीं सकते। वृक्ष RFC 6962 वाम-पूर्ण असंतुलित वृक्ष है (प्रत्येक आंतरिक विभाजन सबट्री लीफ़ गणना से कड़ाई से कम दो की सबसे बड़ी घात पर), जो समावेशन और संगति प्रमाणों को एक ऑडिट-पथ एल्गोरिथम साझा करने देता है। संदर्भ विनिर्देश स्पष्ट वाम/दक्षिण व्युत्पत्ति स्यूडोकोड वहन करता है और एक गैर-दो-की-घात (5-लीफ़) परीक्षण सदिश पिन करता है ताकि दक्षिण-किनारा प्रोत्साहन मामला — जिसे एक 4-लीफ़ सदिश छिपा देता है — अभ्यास किया जाए।

16.4 हैश श्रृंखलन (आंतरिक)

LogDO केवल क्रैश-संगति के लिए एक आंतरिक प्रविष्टि श्रृंखला बनाए रखता है। यह कभी प्रकाशित नहीं होती और कभी सत्यापनकर्ता-सम्मुख नहीं होती:

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

प्रकाशित केवल-संलग्न प्राधिकरण संचयी Merkle रूट + उसका एंकर (§16.5–16.6) है, कभी वह कच्चा क्रम नहीं जिसमें ऑपरेटर संयोगवश लीफ़ परोसता है: श्रृंखला किसी भी परोसे गए क्रम के लिए पुनर्गणना करती है, इसलिए केवल एंकर किया गया रूट कैनोनिकल स्थिति पिन करता है।

16.5 संचयी Merkle वृक्ष और बैचिंग

seq क्रम में सभी लीफ़ों पर एक सदा-बढ़ता RFC 6962 वृक्ष है — पृथक प्रति-बैच वृक्ष नहीं। (एक कैरी-लीफ़-श्रृंखलित प्रति-बैच निर्माण अस्वीकार कर दिया गया था: यह एक सच्चा उपसर्ग संबंध नहीं है, इसलिए इसके "संगति प्रमाण" अध्वनित हैं।) संचयी वृक्ष वास्तविक RFC 9162 संगति प्रमाण देता है और एक एकल हालिया एंकर को किसी भी पुराने qub के लिए समावेशन सिद्ध करने देता है।

LogDO Durable Object एकल लेखक है (blockConcurrencyWhile, QuotaDO / EntitlementDO को प्रतिबिंबित करते हुए) — एक साझा लॉग में संलग्न करना साझा स्थिति पर पढ़ें-संशोधित-लिखें है और इसलिए एक DO के माध्यम से जाना MUST, कभी KV नहीं। यह वृक्ष के दक्षिण-किनारा फ़्रंटियर (O(log n) हैश) को कैश करता है इसलिए एक बैच बंद करना O(batch) है। एक बैच एक साथ एंकर किए गए लीफ़ों का समुच्चय है; इसके ट्रिगर विन्यास-योग्य हैं, प्रोटोकॉल-स्थिर नहीं: कम-से-कम LOG_BATCH_MAX_LEAVES (डिफ़ॉल्ट 4096) का एक tree_size अग्रिम, या आयु एंकर ताल तक पहुँचना, या एक सशुल्क T3 मुहरबंदी उतरने पर एक बाध्य फ़्लश। root_i लीफ़ों 0 .. tree_size_i पर संचयी Merkle Tree Hash है।

16.6 स्थायी-संग्रहण एंकर के माध्यम से Signed Tree Head

स्थायी-संग्रहण एंकर लेन-देन ही Signed Tree Head है और वृक्ष शीर्ष के लिए ही एक ऑपरेटर हस्ताक्षर को प्रतिस्थापित करता है: दैनिक एंकर को किसी qub कुंजी की आवश्यकता नहीं क्योंकि स्थायी-संग्रहण लेन-देन का owner हस्ताक्षर है। मोट थीसिस कायम रहती है — अपरिवर्तनीय सबस्ट्रेट, न कि एक qub-धारित गुप्त, एंकर किए गए रूट के लिए भार-वहन करने वाला है।

डिज़ाइन में ठीक एक गर्म qub हस्ताक्षर कुंजी है, और यह पिन की गई है: प्रति-मुहरबंदी रसीद कुंजी (§16.10)। इसकी सार्वजनिक कुंजी LogProfile में प्रतिबद्ध है (सत्यापनकर्ता के साथ वितरित) और anchor_owner द्वारा क्रॉस-हस्ताक्षरित है, इसलिए एक सत्यापनकर्ता एक रसीद को एंकर के उसी पिन किए गए रूट के विरुद्ध मान्य करता है। यह §16.15 Q2 का समाधान है — एक अनपिन की गई, ऑपरेटर-घुमाने-योग्य रसीद कुंजी अस्वीकार्य होगी (ऑपरेटर अस्वीकार कर सकता था कि कुंजी उसकी थी), जो रसीद के उत्तरदायित्व मूल्य को उस ऑपरेटर-स्तरीय विरोधी के विरुद्ध शून्य कर देगा जिसे रोकने के लिए रसीद मौजूद है। इसलिए: qub कोई अनपिन की गई लॉग-हस्ताक्षर कुंजी नहीं रखता; रसीद कुंजी पिन की गई और anchor_owner-क्रॉस-हस्ताक्षरित है।

SignedTreeHead कैनोनिकल CBOR है (कुंजियाँ एन्कोडेड लंबाई से): size:u64, root:bstr[32], batch:u64, prev:bstr[32] (पूर्व sth_hash; जेनेसिस = 32 शून्य बाइट्स), log_id:bstr[32], first_seq:u64, anchored_at:i64। इसका हैश sth_hash = SHA3-256(0x03 || canonical_cbor(SignedTreeHead)) है।

पिन किया गया विश्वास रूट। log_id = SHA3-256("QUB_TLOG_V1" || anchor_owner_address)। एक अनुरूप सत्यापनकर्ता anchor_tx.owner == LogProfile.anchor_owner की माँग करना MUST, जहाँ anchor_owner (और रसीद-कुंजी सार्वजनिक कुंजी) LogProfile के रूप में qub_core में बेक किया गया है — DrandTimelockProvider::quicknet() में पहले से मौजूद quicknet स्थिरांकों के साथ — और सत्यापनकर्ता बाइनरी के साथ वितरित किया गया है। सत्यापनकर्ता एक गेटवे /raw/ प्रतिक्रिया पर भरोसा करने के बजाय स्थायी-संग्रहण लेन-देन डेटा → tx_id बंधन को स्थानीय रूप से सत्यापित करना भी MUST। यह दुष्ट-वॉलेट इक्विवोकेशन छेद को बंद करता है: "स्थायी संग्रहण पर एंकर किया गया" तब तक अर्थहीन है जब तक सत्यापनकर्ता पिन न करे कि कौन सा वॉलेट।

घुमाव एक §15 शासन विस्तार है, पुनः-उपयोग नहीं (हल — §16.15 Q3)। §15.2 की प्रोफ़ाइल सतह वर्तमान में केवल sig_algs / drand चेन / आवरण संस्करण / सामग्री प्रकार सूचीबद्ध करती है, और §15.3 के ट्रिगर इनमें से कोई नहीं सूचीबद्ध करते — LogProfile / anchor_owner अभी तक §15 की सतह में नहीं है। इसलिए घुमाव शासन को बनाया जाना चाहिए: §15.3 को (नीचे) LogProfile ट्रिगर जोड़ने के लिए विस्तारित किया गया है, और एक घुमाव एक सत्यापनकर्ता अद्यतन में शिप किया गया एक हस्ताक्षरित LogProfile उछाल है। एक नियोजित घुमाव एक निवर्तमान → आगमनशील क्रॉस-हस्ताक्षर वहन करता है; एक समझौता-चालित घुमाव नहीं कर सकता (निवर्तमान कुंजी ठीक तभी अविश्वसनीय/अनुपलब्ध होती है) और §15-शासित उछाल पर फ़ॉलबैक करता है, अंतरिम में नुकसान को सीमित करने वाली पूर्व-एंकर फ़ोर्क जाँच (नीचे) के साथ।

इक्विवोकेशन विंडो (प्रथम-श्रेणी विश्वास पैरामीटर)। एक लीफ़ इक्विवोकेशन-प्रतिरोधी केवल तभी होता है जब उसका आवरण करने वाला एंकर स्थायी-संग्रहण-पुष्ट हो। विंडो received_at → एंकर पुष्टि है (≤ ताल + स्थायी-संग्रहण अंतिमता)। इसके भीतर एकमात्र गारंटियाँ पिन की गई मुहरबंदी रसीद (§16.10) और qub की परिचालन अखंडता हैं। तीन उत्तरदायित्व कलाकृतियाँ इसे हाथ-लहराए जाने के बजाय ईमानदार बनाती हैं (साक्षी मॉडल §16.15 Q2 का समाधान है):

  1. पिन की गई हस्ताक्षरित मुहरबंदी रसीद — अपलोड प्रतिक्रिया में लौटाया गया SCT एनालॉग (§16.10), पिन की गई, anchor_owner-क्रॉस-हस्ताक्षरित रसीद कुंजी द्वारा हस्ताक्षरित। अपने एंकर से पहले गिराया गया एक लीफ़ पीड़ित को प्रकाशित करने के लिए एक गैर-अस्वीकार्य रसीद छोड़ता है, मौन-लोप छेद को बंद करते हुए।
  2. प्रकाशित मॉनिटर पद्धति + पूर्व-श्रृंखला चहलकदमी — एंकर prev श्रृंखला शीर्ष→जेनेसिस चली जाती है; एक फ़ोर्क (एक size पर भिन्न root के साथ दो एंकर, या एक टूटा हुआ prev) कदाचार का प्रकाशन-योग्य प्रमाण है। इक्विवोकेशन पहचान एक घोषित परिचालन प्रतिबद्धता है, एक मौन धारणा नहीं।
  3. दोहरे स्व-प्रकाशित शीर्ष — प्रत्येक नया शीर्ष {sth_hash, tree_size} एक समर्पित qub-स्वामित्व वाली सार्वजनिक, केवल-संलग्न GitHub रिपॉज़िटरी (भार-वहन करने वाला छेड़छाड़-स्पष्ट स्व-प्रकाशन पाद) पर पोस्ट किया जाता है, केवल सर्वोत्तम-प्रयास सहसंबोधन के रूप में एक सामाजिक पोस्ट के साथ। एक विफल पोस्टिंग पेज करना MUST (मौन विफल नहीं)।

ईमानदारी सीमा (बाध्यकारी बाधा)। क्योंकि qub दोनों पोस्टिंग सतहों को नियंत्रित करता है, यह स्व-प्रकाशित है, स्वतंत्र रूप से साक्षीकृत नहीं। कोई भी उत्पाद, विपणन, या कानूनी सतह यह दावा नहीं कर सकती कि लॉग "स्वतंत्र रूप से साक्षीकृत" है; अनुमत दावा यह है कि इक्विवोकेशन पता लगाने योग्य है और एक गैर-अस्वीकार्य रसीद छोड़ता है। एक सच्चा स्वतंत्र तृतीय-पक्ष साक्षी एक भविष्य के §15 शासन उछाल पर स्थगित है।

received_at ऑपरेटर-दावाकृत है और कोई दावा इस पर निर्भर नहीं हो सकता — इसे किसी भी उत्पाद / कानूनी / API / प्रमाण-प्रतिपादन सतह पर कभी प्रमाण के रूप में या विवाद सहसंबोधन के रूप में सामने नहीं लाया जाता। स्थायी-संग्रहण एंकर ब्लॉक समय T एकमात्र भरोसा-रहित टाइमस्टैम्प है ("तक लॉग किया गया" पर एक ऊपरी सीमा)। received_at पर कोई भी मॉनिटर समझदारी जाँच T के विरुद्ध तुलना करना MUST, ऑपरेटर-नियंत्रित anchored_at STH क्षेत्र के विरुद्ध नहीं; ऐसी जाँच केवल एक ईमानदार ऑपरेटर के घड़ी बग के विरुद्ध एक गार्ड है, एक दुर्भावनापूर्ण ऑपरेटर के विरुद्ध एक उत्तरदायित्व नियंत्रण नहीं (§16.15 Q5)।

16.7 एंकर लेन-देन प्रारूप और ताल

AnchorBundle कैनोनिकल-CBOR स्थायी-संग्रहण लेन-देन बॉडी है, §16.8 बंडलर के माध्यम से लिखी गई: ver:u8, sth:bstr (कैनोनिकल SignedTreeHead बाइट्स), prev_anchor:bstr (पूर्व एंकर लेन-देन आईडी कच्चे बाइट्स; जेनेसिस पर लोप), chain_hash:tstr (प्रभाव में drand चेन — quicknet), और seq क्रम में बैच की लीफ़-CBOR धारा ताकि एंकर स्व-निहित हो: एक मॉनिटर शून्य qub निर्भरता के साथ बॉडी से root पुनः-व्युत्पन्न करता है। (यदि लीफ़ धारा उच्च मात्रा पर बड़ी हो जाती है, तो एक भविष्य का संशोधन संदर्भ द्वारा केवल एक लीफ़ श्रेणी प्रतिबद्ध कर सकता है; नोट किया गया, v1 में अपनाया नहीं गया।)

स्थायी-संग्रहण टैग जानबूझकर गणनीय हैं — लॉग को पाया जाना है, निजी qubs के विपरीत: App-Name: qub-tlog, Anchor-Format: 1, Log-Id: <hex>, Batch: <n>, Tree-Size: <n>, Root: <hex>, Prev-Anchor: <tx>, Content-Type: application/cbor। टैग अविश्वसनीय संकेत हैं; CBOR बॉडी एकमात्र प्राधिकरण है।

ताल: डिफ़ॉल्ट रूप से दैनिक, मात्रा के साथ पुनर्विचारित (आकार ट्रिगर भार के तहत प्रभावी ताल को स्वतः छोटा करता है); एक सशुल्क T3 मुहरबंदी एक एंकर को बाध्य करती है ताकि भुगतान करने वाले ग्राहक कभी एक दिन प्रतीक्षा न करें। एंकर वॉलेट समर्पित और कम-वेग वाला है, अपलोड वॉलेट से अलग — यह अपना स्वयं का JWK होना MUST (एक भिन्न कुंजी, अपलोड वॉलेट पर एक तार्किक भूमिका नहीं) ताकि एक अपलोड-वॉलेट समझौता एंकर जाली न बना सके — एक कठोर प्रति-दिन एंकर-लेन-देन बजट के साथ (पदावनत ARWEAVE_DAILY_CEILING)। अभिरक्षा मुद्रा स्पष्ट रूप से बताई गई है: एक संकीर्ण-दायरा गर्म कुंजी एक कसे सर्किट ब्रेकर और कम शेष के साथ, "ठंडी" नहीं — एक वॉलेट जो दैनिक स्वतः-हस्ताक्षर करता है, ठंडा नहीं हो सकता, और विनिर्देश इसका दिखावा नहीं करता।

16.8 ANS-104 बंडलर

एक इन-हाउस ANS-104 DataItem एन्कोडर और डीप-हैश हस्ताक्षरकर्ता, लगभग 300 लाइनें, केवल Web Crypto, शून्य npm निर्भरताएँ (दोनों Turbo SDK npm ci --ignore-scripts आपूर्ति-श्रृंखला गेट को विफल करते हैं)। DataItem बाइट लेआउट:

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

हस्ताक्षर स्थायी-संग्रहण deepHash है — ["dataitem", "1", sig_type, owner, target, anchor, encoded_tags, data] पर एक पुनरावर्ती SHA-384 डाइजेस्ट (स्थायी-संग्रहण की वायर आवश्यकता, crypto.subtle.digest("SHA-384")) — फिर वॉलेट JWK के साथ crypto.subtle के माध्यम से डीप हैश पर RSA-PSS; id = base64url(SHA-256(signature))। यहाँ SHA-384 को एक स्थायी-संग्रहण-वायर-केवल आदिम के रूप में पृथक रखा गया है, कभी एक qub विश्वास आदिम नहीं (§15 बाड़ दर्ज करता है; qub विश्वास हैशिंग पूरे SHA3-256 है)।

एक कोड पथ तीन उपभोक्ताओं को सेवा देता है: सशुल्क T3 प्रति-qub स्थायित्व, स्थायी-संग्रहण-अनुपलब्धता फ़ॉलबैक (DataItem को कतारबद्ध करें, R2-प्रथम ack फिर भी लौटाएँ — यह वर्तमान ARWEAVE_UNAVAILABLE 503 मृत-अंत को बंद करता है), और AnchorBundle लिखना। हस्ताक्षर योजना (हल — §16.15 Q8): v1 RSA-PSS (हस्ताक्षर प्रकार 1) से हस्ताक्षर करता है मौजूदा स्थायी-संग्रहण वॉलेट JWK तंत्र का पुन: उपयोग करते हुए (शून्य नई दीर्घ-जीवी कुंजी अभिरक्षा, "एक कम गुप्त" थीसिस की सेवा करते हुए); Ed25519 §15 PQ-माइग्रेशन पथ पर स्थगित है।

हाथ से बनाया गया डीप हैश W5 में सबसे-उच्च-जोखिम, सबसे-कम-प्राकृतिक-कवरेज कोड है, इसलिए इसका गेटिंग गैर-परक्राम्य है (§16.15 Q8):

  1. क्रॉस-भाषा फ़िक्स्चर tlog_v1.json (Rust + TS, §14.5 wrapper_v1.json पैटर्न) डीप-हैश, DataItem बाइट्स + आईडी, लीफ़ हैश, एक 5-लीफ़ रूट + ऑडिट पथ, एक STH हैश, एक समावेशन प्रमाण, और एक संगति प्रमाण को कवर करता है — हस्ताक्षर और सत्यापन दोनों दिशाओं में (सत्यापन दिशा मायने रखती है क्योंकि §16.6 की स्थानीय लेन-देन → tx_id जाँच डीप हैश को हर स्वतंत्र सत्यापनकर्ता में खींचती है, न कि केवल लेखक में)।
  2. एक संदर्भ ANS-104 बंडलर के माध्यम से एक-बार का इंटरऑप राउंड-ट्रिप, केवल स्थिर परीक्षण डेटा के रूप में उपभोग किया गया — कभी एक npm रनटाइम निर्भरता नहीं (केवल-Web-Crypto / कोई-इंस्टॉल-स्क्रिप्ट मुद्रा कायम रहती है)।
  3. डीप-हैश + RSA-PSS पथ को उन्हीं crypto.subtle आदिमों के माध्यम से राउंड-ट्रिप करना चाहिए जिन्हें उत्पादन उपयोग करता है, ताकि इन-हाउस एन्कोडर बाइट-संगत हो।
  4. एक चालू बंडल-पश्चात स्वीकृति मॉनिटर पुष्टि करता है कि प्रत्येक एंकर / फ़ॉलबैक DataItem वास्तव में स्थायी-संग्रहण स्वीकृति प्राप्त करता है, एक अलार्म + सर्किट ब्रेकर के साथ — क्योंकि डीप हैश स्थायी-संग्रहण-अनुपलब्धता फ़ॉलबैक कतार को भी सेवा देता है, इसलिए एक मौन प्रतिगमन उस कतार को नेटवर्क-अस्वीकृत वस्तुओं से ठीक उस आउटेज के दौरान भर देगा जिसे कवर करने के लिए यह मौजूद है।

16.9 समावेशन और संगति प्रमाण

दोनों RFC 9162, SHA3-256, कैनोनिकल CBOR के रूप में परोसे गए हैं।

InclusionProofGET /api/v1/qub/:tx_id/proof: ver:u8, leaf:bstr (सटीक लीफ़ CBOR — सत्यापनकर्ता स्वयं leaf_hash की पुनर्गणना करता है और कभी एक आपूर्तित हैश पर भरोसा नहीं करता), 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 }

ConsistencyProofGET /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। एक एकल असंदिग्ध कुंजी सूची, परीक्षण सदिश द्वारा पिन की गई।

स्वतंत्र सत्यापन (कोई qub सर्वर नहीं, §11 का विस्तार करता है):

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).

प्रमाण-परोसने वाला संग्रहण समन्वय-कुंजीबद्ध होना MUST (हल — §16.15 Q7, अवरोधक पूर्वशर्त)। ठंडे-लीफ़ प्रमाण उत्पादन शुद्धता-तटस्थ है केवल तभी जब R2 ऑडिट सामग्री एक पूर्ण वृक्ष समन्वय (level, index) द्वारा कुंजीबद्ध स्थायी Merkle-नोड संग्रह हो — न कि प्रति-batch नोड डेल्टा। एक समन्वय-कुंजीबद्ध संग्रह के साथ, कोई भी (leaf i, size N) ऑडिट पथ बैच सीमाओं के पार बिना पुनर्गणना के O(log N) प्रत्यक्ष R2 GET का एक समुच्चय है; एक बैच-कुंजीबद्ध संग्रह के साथ यह नहीं है, जो वह संग्रह-लेआउट अंतराल है जिसे यह समाधान बंद करता है। लीफ़ बॉडी इसी तरह seq द्वारा सामग्री-पता-योग्य हैं। एक W5 परीक्षण सदिश केवल R2 + स्थायी संग्रहण का उपयोग करते हुए LogDO संग्रहण मिटाए जाने के साथ एक जेनेसिस-युग ठंडे लीफ़ को एक बहुत-बाद के रूट के विरुद्ध सिद्ध करना MUST, ताकि §16.13 में पुनर्ग्रहण-सुरक्षा दावा दावा किए जाने के बजाय समर्थित हो। O(log N) अनुक्रमिक R2 GET केवल अतुल्यकालिक प्रमाण एंडपॉइंट पर हैं — कभी मुहरबंदी गर्म पथ (§16.10) या एक प्रति-टिक क्रॉन पर नहीं।

16.10 R2-प्रथम ack क्रम

POST /api/v1/upload अनुक्रम बन जाता है:

  1. फ़्रंट-हाफ़ गेट (auth, सत्यापन, idempotency शार्ड कुंजी) — अपरिवर्तित।
  2. तुल्यकालिक रूप से await QUB_CACHE.put(qub-cache/<tx_id>, wrappedBytes) — स्थायित्व तल; W1 की precache रेस को भी बंद करता है (पूर्व में स्थायी-संग्रहण सबमिट के बाद एक ctx.waitUntil)।
  3. तुल्यकालिक रूप से await LogDO.append(leaf) — एक इन-कोलो DO RPC; एकल लेखक seq निर्दिष्ट करता है, प्रविष्टि श्रृंखला विस्तारित करता है, और फ़्रंटियर अद्यतन करता है। (साझा स्थिति पर RMW → DO, कभी KV नहीं।) append RPC केवल वही करता है — O(batch) Merkle बैच-बंद कार्य इस RPC से हटकर LogDO अलार्म पर चलता है, अन्यथा append p95 हर LOG_BATCH_MAX_LEAVES-वें मुहरबंदी पर बढ़ता है।
  4. अब ack लौटाएँ — मुहरबंदी रसीद (पिन की गई रसीद कुंजी, §16.6 द्वारा हस्ताक्षरित) और { tx_id, log_seq, anchor_status: "pending" } के साथ। बहु-सेकंड स्थायी-संग्रहण फ़ैन-आउट क्रिटिकल पथ से हटा दिया गया है।
  5. एक ctx.waitUntil स्थगित कार्य को कतारबद्ध करता है: प्रति-qub स्थायी-संग्रहण सबमिट (अब सर्वोत्तम-प्रयास / सशुल्क; विफलता पर यह उपयोगकर्ता को 503 करने के बजाय बंडलर फ़ॉलबैक कतार में मार्ग देता है) साथ ही मौजूदा अनंतिम-मेटा लेखन। बैच बंद और एंकरिंग LogDO अलार्म और दैनिक एंकर क्रॉन से स्वतंत्र रूप से चलते हैं। एक लूप के अंदर कोई ctx.waitUntil नहीं; मौजूदा idempotency शार्ड कुंजी संरक्षित है।

विलंबता बजट (हल — §16.15 Q7)। < 300 ms p95 लक्ष्य एक मापा गया लॉन्च गेट है, एक धारणा नहीं। ईमानदार क्रिटिकल पथ फ़्रंट-हाफ़ KV पठन + एक R2 PUT + दो क्रमबद्ध Durable Objects है — मौजूदा QuotaDO मुहरबंदी-कोटा डेबिट और नया LogDO append — इसलिए बजट को दो इन-कोलो DO राउंड-ट्रिप का हिसाब रखना चाहिए, एक का नहीं। QuotaDO को प्रतिबिंबित करने वाला एक LogDO विलंबता अलार्म शिप करें और एक p95 प्रतिगमन को एक रिलीज़ अवरोधक मानें।

16.11 विश्वास मॉडल — सटीक दावा, लीफ़ kind द्वारा परिक्षेत्रित

kind=0x01 (प्रमाणित): "यह सामग्री — body_hash से मेल खाती बॉडी, qub_id द्वारा पहचानी गई — स्थिति seq पर qub के केवल-संलग्न लॉग में प्रतिबद्ध की गई थी और स्थायी-संग्रहण ब्लॉक समय T से बाद में नहीं मौजूद थी; यह drand राउंड R = unlock_round(unlock_at) तक क्रिप्टोग्राफ़िक रूप से अपठनीय थी।" यह पूर्ण {tlock राउंड बंधन + Merkle समावेशन + एंकर किया गया रूट} त्रिक है।

kind=0x02 (दावाकृत, डिफ़ॉल्ट): "सामग्री-पता chash के साथ एक अपारदर्शी सिफरटेक्स्ट, qub_id और unlock_at का दावा करते हुए, स्थिति seq पर केवल-संलग्न लॉग में प्रतिबद्ध किया गया था और स्थायी-संग्रहण ब्लॉक समय T से बाद में नहीं मौजूद था।" राउंड और बॉडी पाद मौजूदा §11 .qub-बंडल सत्यापन (qub_core::unlock) द्वारा आपूर्तित हैं, लॉग द्वारा नहीं; एक नंगे प्रति-qub लेन-देन के ऊपर लॉग जो जोड़ता है वह छेड़छाड़-स्पष्ट क्रम, एक भरोसा-रहित ऊपरी-सीमा प्रतिबद्धता समय, और इक्विवोकेशन प्रतिरोध है।

दोनों दावे §11 के अनुसार बाहर रखते हैं: sig_alg ≥ 0x01 के बिना लेखकत्व, इरादा, और उप-एंकर-ग्रैन्युलैरिटी समय। न ही कोई दावा received_at पर निर्भर होने देता है।

दावा सीमा (बाध्यकारी लॉन्च बाधा — हल §16.15 Q1)। मुफ़्त / डिफ़ॉल्ट (kind=0x02) qubs के लिए, ऊपर दिया गया परिक्षेत्रित kind=0x02 दावा वह सीमा है जो किसी भी उत्पाद, विपणन, शर्तें, या प्रमाण-प्रतिपादन सतह द्वारा दावा की जा सकती है। कोई भी सतह यह नहीं बता सकती या निहित नहीं कर सकती कि लॉग एक डिफ़ॉल्ट qub की सामग्री या अनलॉक राउंड सिद्ध करता है — लॉग एक अपारदर्शी सिफरटेक्स्ट का क्रम + एक भरोसा-रहित ऊपरी-सीमा प्रतिबद्धता समय सिद्ध करता है। सामग्री और राउंड प्रमाण विशेष रूप से मौजूदा §11 .qub-बंडल सत्यापन से आते हैं, जो लॉग-स्वतंत्र है। यह कॉपी पर एक कठोर लॉन्च अवरोधक है, एक शैलीगत वरीयता नहीं; यह वह समाधान है जो बाइट-अंधा डिफ़ॉल्ट पथ को ईमानदार रखता है।

16.12 संस्करण और W3 समन्वय

कोई SealedQub वायर उछाल नहीं है और इसलिए कोई प्रोटोकॉल-संस्करण उछाल नहीं (§12.1): लॉग एक साइडकार है जो मौजूदा क्षेत्रों और बाइट्स के लिए प्रतिबद्ध होता है, इसलिए यह §12.2 प्रोटोकॉल-संस्करण इतिहास में प्रवेश नहीं करता। W3 का वैकल्पिक drand_chain_version अछूता है और एकमात्र वैकल्पिक SealedQub क्षेत्र रहता है। इसके बजाय लॉग अपने स्वयं के स्वतंत्र संस्करण स्थान प्रस्तुत करता है — LOG_VERSION_1, ANCHOR_FORMAT_1, InclusionProof.ver — §12.4 आवरण-संस्करण स्वतंत्रता को प्रतिबिंबित करते हुए (आवरण प्रोटोकॉल संस्करण से स्वतंत्र एक संस्करण बाइट वहन करता है, और लॉग संस्करण उसी पृथक्करण का अनुसरण करते हैं)।

प्रमाण वितरण डिफ़ॉल्ट रूप से फ़ेच किया जाता है, एक वैकल्पिक राइड-अलॉन्ग के साथ। एक प्रमाण मुहरबंदी समय पर मौजूद नहीं हो सकता (एंकर अभी तक नहीं लिखा गया है), इसलिए मुहरबंदी-समय .qub बंडल प्रमाण-मुक्त रहता है। W7 का सत्यापनकर्ता GET …/proof एक बार फ़ेच करता है, या पूरी तरह-ऑफ़लाइन मोड में Log-Id पर एक स्थायी-संग्रहण क्वेरी के माध्यम से सार्वजनिक AnchorBundle से प्रमाण पुनर्निर्मित करता है। .qub बंडल (W7) एक वैकल्पिक inclusion_proof सदस्य आरक्षित करता है — मुहरबंदी पर अनुपस्थित, ठंडे अभिलेखन के लिए एक एंकर-पश्चात पुनः-निर्यात द्वारा आबाद — W3 के drand_chain_version के समान "वैकल्पिक, डिफ़ॉल्ट रूप से लोप, योगात्मक" पैटर्न का अनुसरण करते हुए।

16.13 प्रतिधारण

LogDO खुली पूँछ, R2 प्रमाण-परोसने वाले सबस्ट्रेट, एंकर सर्किट-ब्रेकर काउंटरों, और बंडलर फ़ॉलबैक कतार के लिए प्रतिधारण विंडो docs/DATA-RETENTION.md में निर्दिष्ट हैं। सिद्धांत: लॉग का गर्म प्रति-प्रविष्टि संग्रहण (LogDO) एंकर-पश्चात पुनर्ग्रहण-योग्य है; इसकी ऑडिट सामग्री — समन्वय-कुंजीबद्ध (level, index) Merkle-नोड संग्रह + seq-पता-योग्य लीफ़ बॉडी (§16.9) + स्थायी-संग्रहण एंकर — स्थायी है। DO से एक ठंडे लीफ़ को पुनर्ग्रहण करना एक जारी किए गए प्रमाण को कभी अमान्य नहीं करता, क्योंकि एक प्रमाण उस स्थायी R2 नोड संग्रह और स्थायी-संग्रहण एंकर के विरुद्ध हल होता है, DO के विरुद्ध नहीं (और §16.9 मिटाए-गए-DO परीक्षण सदिश इसे सिद्ध करता है)।

16.14 परीक्षण सदिश

W5 क्रॉस-भाषा फ़िक्स्चर tlog_v1.json (§16.8) के साथ-साथ कार्यान्वित सदिश शिप करता है: एक kind=0x01 और एक kind=0x02 लीफ़ → leaf_hash; 5-लीफ़ संचयी रूट; एक समावेशन प्रमाण; एक संगति प्रमाण; एक AnchorBundle; और एक DataItem आईडी। ये §14.5 बाहरी-आवरण सदिशों के साथ रहते हैं और Rust (qub-core) और TypeScript (वर्कर) दोनों कार्यान्वयनों द्वारा अभ्यास किए जाते हैं।

16.15 समीक्षा निर्णय (W5 — हल)

W5 बाहरी समीक्षा (एक विरोधात्मक डिज़ाइन पास + स्वामी साइन-ऑफ़) पूर्ण है। नीचे का प्रत्येक निर्णय तय है और ऊपर §16 टेक्स्ट में प्रतिबिंबित है; बाध्यकारी लॉन्च बाधाएँ अंत में पुनः-कथित हैं। कार्यान्वयन उनके तहत आगे बढ़ सकता है।

  1. डिफ़ॉल्ट-पथ (kind=0x02) लीफ़ ईमानदारी — हल। दो-लीफ़-kind विभाजन को निर्दिष्ट के अनुसार शिप करें: kind=0x02 न तो body_hash न ही drand_round प्रतिबद्ध करता है। बाइट-अंधे पथ पर कोई *_body_hash क्षेत्र नहीं (यह एकीकरणकर्ताओं के लिए सबसे सुपाठ्य झूठा "सत्यापित" संकेत होगा और एक सुविधा है जो §11 पहले से बंडल से प्रदान करता है)। लॉग-प्रमाणित qubs के लिए सर्वर-सील की आवश्यकता रखें (यह वर्कर के माध्यम से प्लेनटेक्स्ट को बाध्य करेगा और क्रिप्टो-श्रेडिंग मोट को नष्ट करेगा)। कोई भी स्व-वर्णन शॉर्ट-सर्किट .qub बंडल / प्रमाण आवरण में एक सत्यापनकर्ता-पुनर्गणित क्षेत्र के रूप में है, कभी एक लीफ़ क्षेत्र नहीं। स्वामी-पुष्ट दावा सीमा: §16.11।
  2. इक्विवोकेशन / लोप उत्तरदायित्व — हल। मुहरबंदी-रसीद कुंजी LogProfile में पिन की गई + anchor_owner-क्रॉस-हस्ताक्षरित है (पूर्व "कोई हस्ताक्षर कुंजी नहीं" विरोधाभास को बंद करते हुए; §16.6)। लॉन्च साक्षी मॉडल: पिन की गई रसीद + मॉनिटर पद्धति + पूर्व-श्रृंखला चहलकदमी + दोहरे स्व-प्रकाशित शीर्ष (qub-स्वामित्व वाली सार्वजनिक GitHub रिपॉज़िटरी, सामाजिक सर्वोत्तम-प्रयास), पता लगाने योग्य + रसीदित के रूप में विपणित, कभी स्वतंत्र रूप से साक्षीकृत नहीं। एक सच्चा तृतीय-पक्ष साक्षी एक §15 शासन उछाल पर स्थगित है।
  3. पिन किया गया एंकर-स्वामी विश्वास रूट + घुमाव — हल। LogProfile पिन अपनाएँ (§16.6); सत्यापनकर्ता anchor_tx.owner == anchor_owner जाँचता है और लेन-देन डेटा → tx_id बंधन को स्थानीय रूप से सत्यापित करता है। घुमाव शासन एक §15 बनाने योग्य विस्तार है (§15.3 ट्रिगर जोड़ा गया), पुनः-उपयोग नहीं; नियोजित घुमाव क्रॉस-हस्ताक्षर करते हैं, समझौता-चालित घुमाव नुकसान को सीमित करने वाली फ़ोर्क जाँच के साथ §15 उछाल पर फ़ॉलबैक करते हैं।
  4. निजी-qub लीफ़ ब्लाइंडिंग — हल। निजी qubs के लिए ब्लाइंडिंग रखें (ref = SHA3-256(qub_id ‖ log_blind_secret)), सार्वजनिक qubs के लिए कच्चा qub_id (पहले से §16.2.1), chash स्वतंत्र संबंध के रूप में। log_blind_secret एक सहसंबंध/Sybil-स्तरीय गुप्त है, केवल आगे-घुमाव (§16.2.1)।
  5. received_at — हल। इसे लीफ़ में रखें, प्रतिबद्ध लेकिन स्पष्ट रूप से गैर-साक्ष्यात्मक; कभी किसी भी सतह पर प्रमाण के रूप में या विवाद सहसंबोधन के रूप में सामने नहीं लाया गया। कोई भी मॉनिटर समझदारी जाँच स्थायी-संग्रहण ब्लॉक समय T के विरुद्ध तुलना करती है, ऑपरेटर-नियंत्रित anchored_at के विरुद्ध नहीं (§16.6)।
  6. मुफ़्त-स्तरीय सिद्ध-करने-योग्य-समय — हल (स्वामी साइन-ऑफ़)। स्थायित्व पीछे नहीं हटता; केवल सिद्ध करने योग्य ऊपरी-सीमा प्रतिबद्धता समय एंकर ब्लॉक समय तक मोटा होता है। मुफ़्त-स्तरीय कॉपी कोई संख्यात्मक SLA उपयोग नहीं करती ("…अगले लॉग एंकर पर जोड़ा गया, आमतौर पर दैनिक"); सटीक-घंटा प्रमाण एक सशुल्क T3 गुण है, जो स्तर-तुलना सतह पर + शर्तों में प्रकट किया जाता है (§16.1)।
  7. Workers पर संचयी वृक्ष — हल। एकल संचयी RFC 9162 वृक्ष + फ़्रंटियर-कैश किया गया एकल-लेखक LogDO (~1k लेखन/सेकंड DO सीमा बनाम आरामदायक हेडरूम; इसके निकट तक Merkle-of-shard-roots शार्डिंग स्थगित करें)। अवरोधक पूर्वशर्त: समन्वय-कुंजीबद्ध (level, index) R2 नोड संग्रह + मिटाए-गए-DO ठंडे-लीफ़ परीक्षण सदिश (§16.9); < 300 ms दो क्रमबद्ध DOs पर एक मापा गया लॉन्च गेट है (§16.10)।
  8. ANS-104 हस्ताक्षर योजना + डीप-हैश — हल। RSA-PSS (sig प्रकार 1, समर्पित एंकर-वॉलेट JWK का पुन: उपयोग करते हुए); Ed25519 §15 PQ पथ पर स्थगित। हाथ से बनाया गया SHA-384 डीप हैश दोनों-दिशाओं क्रॉस-impl फ़िक्स्चर, एक केवल-स्थिर संदर्भ-बंडलर इंटरऑप जाँच, साझा-crypto.subtle राउंड-ट्रिप, और बंडल-पश्चात स्थायी-संग्रहण-स्वीकृति मॉनिटर पर गेट किया गया है (§16.8)।

बाध्यकारी लॉन्च बाधाएँ (कार्यान्वयन + उत्पाद/कानूनी समीक्षा में ले जाएँ):