qub Protokol Spesifikasyonu
qub, kriptografik zamansal taahhütler için bir protokoldür: sözleri gelecekteki bir tarihe mühürlemek ve o tarih geldiğinde tam olarak ne söylendiğini ve ne zaman söylendiğini kanıtlamak için bir sistem.
Bunu mümkün kılan üç ilkel öğe vardır. drand, merkezsiz bir rastgelelik işaretçisidir — açıklama tarihi herhangi bir tarafın iyi niyetiyle değil, fizik tarafından uygulanır. Kalıcı herkese açık depolama, kurcalanamaz bir kamu deposudur — bir qub mühürlendikten sonra hiçbir taraf onu düzenleyemez veya silemez. ML-DSA-65, post-kuantum bir dijital imzadır — her qub, gizli anahtarı yazarın cihazından asla çıkmayan bir anahtar çiftine bağlıdır.
Bu ilkel öğeler birlikte, zamana kilitli, kurcalama kanıtlı ve atfedilebilir bir ifade oluşturur — dünyanın geçmişi uydurma yeteneği geliştikçe değeri artan bir makbuz.
Bu belgenin geri kalanı, birlikte çalışabilir uygulamalar için gerekli olan normatif spesifikasyondur.
qub Protokol Spesifikasyonu
| Alan | Değer |
|---|---|
| Sürüm | 1.0 (protokol sürümü 0x01, dış sarmalayıcı sürümü 0x01) |
| Tarih | 2026-05-01 |
| Durum | Taslak |
| İncelendiği tarih | 2026-05-01 |
Bu belge, qub zamanlı taahhüt sistemi için normatif protokol spesifikasyonudur. Birlikte çalışabilir uygulamalar için gerekli olan veri yapılarını, serileştirme kurallarını, türetme formüllerini ve doğrulama prosedürlerini tanımlar.
Kapsam: protokol katmanı kasıtlı olarak dilden bağımsızdır — qub gövdesi opak düz metin / markdown / pakt baytlarıdır ve yerel ayarlara duyarlı sunum izleyicinin sorumluluğundadır (qub.social web uygulaması, <qub-embed> iframe'i, MCP istemcileri, vb.).
1. Gösterim ve sözleşmeler
| Gösterim | Anlam |
|---|---|
u8, u64, i64 |
Belirtilen bit genişliğinde işaretsiz/işaretli tam sayılar |
[u8; N] |
N bayttan oluşan sabit uzunluklu bayt dizisi |
Vec<u8> |
Değişken uzunluklu bayt dizisi |
Option<T> |
T türünde değer veya yok |
String |
UTF-8 metin dizesi, NFC normalleştirilmiş |
| ` | |
SHA3-256(x) |
x bayt dizisinin NIST SHA3-256 özeti (FIPS 202) |
ceil(x) |
Tavan fonksiyonu: x'ten büyük veya eşit en küçük tam sayı |
| CBOR | Concise Binary Object Representation (RFC 8949) |
| big-endian | En anlamlı bayt önce |
Ön görüntü yapılarındaki tüm tam sayılar, aksi belirtilmedikçe big-endian sabit genişlikli bayt dizileri olarak kodlanır (i64 → 8 bayt, u8 → 1 bayt).
Tüm zaman damgaları UTC cinsinden Unix saniyeleridir.
2. Veri yapıları
2.1 ComposeQub (Yaratıcının bellek içi durumu)
CBOR'a serileştirilmez. Kalıcı depolamada saklanmaz. Yaratıcı uygulamasına yereldir.
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 (Şifresi çözülmüş yük)
Kanonik CBOR (§3) kullanılarak serileştirilir. SealedQub içinde şifrelenir. Bu, şifre çözüldükten sonra içerik bütünlüğünü kanıtlayan yapıdır.
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
}
Temel hat (imzasız metin qub): version = 0x01, content_type = 0x01, sig_alg = 0x00, tüm Option alanları yok.
Diğer v1 yapılandırmaları: content_type = 0x03 (pakt gövdesi, bkz. §6.1); author_signature ve author_pubkey mevcut olarak sig_alg = 0x01 (ML-DSA-65) (bkz. §9.3); birlikte imzalanan paktlar için cosigner_pubkey ve cosigner_signature birlikte mevcut (bkz. §9.7); yanıt zinciri qub'ları için reply_to, üst qub'un qub_id'sine ayarlanır (imza kapsamı sonuçları için bkz. §9.3).
2.3 SealedQub (Kanonik aktarım biçimi)
Kanonik CBOR (§3) kullanılarak serileştirilir. Kalıcı depolamaya yazılır. Bu, zincir üzerindeki artefakttır.
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 (İzleyici uygulama durumu)
CBOR'a serileştirilmez. İzleyici uygulamasına yereldir. Başarılı şifre çözme ve doğrulamadan sonra inşa edilir.
RevealedQub {
qub_id: [u8; 32],
arweave_tx_id: String,
visibility: u8,
content_type: u8,
created_at: i64,
unlock_at: i64,
outcome_at: Option<i64>, // V1.1 — QubEnvelope.outcome_at / SealedQub.outcome_at'tan taşınır; açıklama sayfasındaki karar-izleme bloğunu sürer (verdict-uplift-plan §5.1)
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. Kanonik CBOR profili
Tüm SealedQub ve QubEnvelope serileştirme bu profille uyumlu OLMALIDIR. Aynı mantıksal yapı verildiğinde iki uygulama aynı baytları üretmek ZORUNDADIR.
3.1 Kodlama kuralları
| Kural | Spesifikasyon |
|---|---|
| Standart | RFC 8949 §4.2.1 (Çekirdek Deterministik Kodlama Gereksinimleri) |
| Harita anahtarı sıralaması | Önce kodlanmış bayt uzunluğuna göre sıralanır (kısa olan önce gelir), sonra sözlüksel olarak (aynı uzunluktaki kodlamalar için bayt bayt) |
| Tam sayı kodlaması | En kısa biçim: ilk baytta 0–23; 2 baytta 24–255; 3 baytta 256–65535; vb. |
| Uzunluk kodlaması | Yalnızca kesin uzunluklar. Belirsiz uzunluklu diziler, haritalar, bayt dizileri veya metin dizeleri yoktur (ek bilgi = 31 yasaktır). |
| Etiketler | CBOR etiketi yoktur (ana tür 6 yasaktır). |
| Kayan nokta | Kayan nokta yoktur (ana tür 7, 0xF9–0xFB değerleri yasaktır). |
| Metin dizeleri | UTF-8 kodlamalı, NFC normalleştirilmiş (Unicode Normalleştirme Formu C). |
| Bayt dizeleri | Ham baytlar. CBOR katmanında base64 kodlaması yoktur. |
| Yinelenen anahtarlar | Hata ile reddet. Ayrıştırıcılar yinelenen harita anahtarlarını sessizce kabul ETMEMELİDİR. |
| Bilinmeyen anahtarlar | Hata ile reddet. Ayrıştırıcılar, türün kanonik anahtar kümesi dışındaki harita anahtarlarını tolere ETMEMELİDİR — iki farklı kanonik bayt dizesinin kodu asla aynı değere çözülmemelidir (encode(decode(x)) == x) ve imzalı yükler için fazladan bir anahtar, her iki imzanın da taahhüt ettiği gizli içerik olurdu. Şema evrimi version üzerinden ilerler, asla fazladan anahtarlar üzerinden değil. |
| Basit değerler | Yalnızca true (0xF5), false (0xF4) ve null (0xF6) izin verilir. |
| İsteğe bağlı alanlar | Mevcut olmayan isteğe bağlı alanlar CBOR haritasından tamamen çıkarılır (null olarak kodlanmaz). Mevcut isteğe bağlı alanlar sıralı anahtar düzeninde dahil edilir. |
3.2 Doğrulanmış kanonik anahtar sıraları
Bu anahtar sıraları normatiftir. Uygulamalar anahtarları tam olarak bu sırayla yaymak ZORUNDADIR. Hata ayıklama onaylamaları, üretim dışı yapılarda sıralamayı doğrulamalıdır (SHOULD).
QubEnvelope (sürüm 0x01, imzasız, tüm isteğe bağlı alanlar yok):
"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 anahtar sırası türetmesi: her anahtar bir CBOR metin dizesidir. Kodlanmış uzunluk = 1 baytlık başlık + dize uzunluğu (24 bayttan kısa dizeler için). Önce toplam kodlanmış uzunluğa göre, aynı uzunluktaki anahtarlar için sözlüksel olarak sıralayın.
SealedQub (sürüm 0x01, herkese açık, alıcı yok):
"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 gövdesi, 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 dizisinin satırı):
"key" (4 encoded bytes)
"value" (6 encoded bytes)
PartyIdentifier (party_a / party_b haritası):
"label" (6 encoded bytes)
"contact" (8 encoded bytes) ← only if present
3.3 Bayt kodlama referansı
| Tür | CBOR kodlaması | Örnek |
|---|---|---|
| SHA3-256 özeti (32 bayt) | 0x58 0x20 + 32 bayt |
body_hash, qub_id |
| Zaman damgaları (i64) | Ana tür 0 (pozitif) veya 1 (negatif), en kısa kodlama | Unix saniyeleri |
| Sürüm (u8, değer 1) | 0x01 (tek bayt) |
|
| İçerik türü (u8, değer 1) | 0x01 (tek bayt) |
|
| sig_alg (u8, değer 0) | 0x00 (tek bayt) |
|
| ML-DSA-65 imzası (3.309 bayt) | 0x59 0x0C 0xED + 3.309 bayt |
author_signature, cosigner_signature |
| ML-DSA-65 açık anahtarı (1.952 bayt) | 0x59 0x07 0xA0 + 1.952 bayt |
author_pubkey, cosigner_pubkey |
4. Normatif türetmeler
4.1 qub_id
qub_id, bir qub'u benzersiz şekilde tanımlar ve QubEnvelope'u SealedQub'a bağlar. Zarf içeriğinden deterministik olarak türetilir.
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
Etki alanı ayırıcı kodlaması: "QUB_ID_V2" dizesi 9 ASCII bayttır. Hizalama için 10 bayta ulaşmak amacıyla tek bir 0x00 dolgu baytı eklenir. Uygulamalar tam olarak bu 10 baytı kullanmak ZORUNDADIR: [0x51, 0x55, 0x42, 0x5F, 0x49, 0x44, 0x5F, 0x56, 0x32, 0x00].
outcome_at kodlaması: V1.1, isteğe bağlı outcome_at alanını bağlamaya katmak için ön görüntüyü 92 bayttan 100 bayta genişletti. Yok olan outcome_at, 8 sıfır bayt olarak kodlanır; protokol doğrulayıcıları her yerde outcome_at <= 0 değerini reddeder, böylece bu nöbetçi değer meşru bir değerle çakışamaz. Bkz. §3.2 (aktarım biçimi) ve bu alanı motive eden hüküm mekaniği için ağaç içi tasks/verdict-uplift-plan.md.
drand_round kodlaması: V1.2, drand_round'u (hedef drand turu, §4.3) bağlamaya katmak için ön görüntüyü 100 bayttan 108 bayta genişletti ve etki alanı ayırıcısını QUB_ID_V2'ye yükseltti. Bu, zaman kilidi turunu qub kimliğine bağlar: bir ağ geçidi, şifreli metni gösterilen unlock_at'ın ima ettiğinden farklı bir tura (örneğin halihazırda geçmiş bir tura) yeniden bağlayamaz. Açılma yordamı (§8) ayrıca tlock şifreli metin stanzasına gömülü turun unlock_round(unlock_at) ile eşleştiğini doğrular, böylece gösterilen açılma zamanının, şifre çözmeyi kapılayan tur olduğu kanıtlanabilir.
Özellikler:
- QubEnvelope'daki herhangi bir alanı (gövde, zaman damgaları, içerik türü, sürüm) değiştirmek farklı bir qub_id üretir.
- qub_id, şifrelemeden önce hesaplanır. Hem QubEnvelope hem de SealedQub aynı qub_id'yi taşır. İzleyici, şifre çözmeden sonra eşleştiklerini doğrular.
- qub_id,
sender_label,author_signatureveyaauthor_pubkey'e bağlı değildir. Bu, aynı zamanda mühürlenen aynı içeriğin, onu kimin imzaladığına bakılmaksızın aynı qub_id'yi üreteceği anlamına gelir. - SealedQub
title'ını değiştirmek (diğer her şey sabit kalırken),title_hasharacılığıylaqub_id'yi değiştirir (§4.1). Bu nedenle bir ağ geçidi, qub kimliğini geçersiz kılmadan geri sayımda gösterilen düz metin başlığı değiştiremez. - SealedQub
outcome_at'ını değiştirmek (diğer her şey sabit kalırken), ön görüntü aracılığıylaqub_id'yi değiştirir. Bir ağ geçidi, qub kimliğini geçersiz kılmadan geri sayımda gösterilen açıklama öncesi hüküm tarihini değiştiremez. drand_round'u değiştirmek (diğer her şey sabit kalırken), ön görüntü aracılığıylaqub_id'yi değiştirir. Bir ağ geçidi, qub kimliğini geçersiz kılmadan zaman kilidi şifreli metnini farklı bir tura yeniden bağlayamaz; §8 açılma zamanı stanza-tur kontrolüyle birleştiğinde, gösterilenunlock_at, şifre çözmeyi gerçekten kapılayan turdur.
4.2 body_hash
body_hash = SHA3-256(body)
Burada body, ham Vec<u8> içerik yüküdür. Metin qub'ları için bu, UTF-8 kodlamalı qub gövdesidir.
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
Burada title, açıklama öncesinde izleyici geri sayımında gösterilen isteğe bağlı düz metin başlığıdır (bkz. §3.2). NFC normalleştirme, özetin görsel olarak eşdeğer kod-nokta dizileri arasında kararlı olması için özet zamanında çalışır. Tümü sıfır olan işaretçi, yok durumu için ayrılmıştır; boş bir dize, kanonik CBOR sınırında "yok"un kanonik olmayan kodlaması olarak reddedilir (kanonik kodlama alanı tamamen çıkarır).
4.3 Açılma turu eşleştirmesi
drand_round = ceil((unlock_at - chain_genesis_time) / chain_period_seconds)
| Parametre | Kaynak | Örnek |
|---|---|---|
unlock_at |
Kullanıcı tarafından seçilen UTC Unix saniyeleri | 1735689600 (2025-01-01 00:00:00 UTC) |
chain_genesis_time |
drand zincir bilgisi (genesis_time) |
1595431050 |
chain_period_seconds |
drand zincir bilgisi (period) |
30 |
ceil() işlemi, açıklama zamanı ≥ unlock_at olan ilk drand turunu seçer. Bu, qub'un seçilen açılma zamanından önce şifresinin çözülememesini sağlar.
Sınır durumu: (unlock_at - chain_genesis_time) tam olarak chain_period_seconds'a bölünebiliyorsa, sonuç tam olarak o turdur — qub o turun açıklama zamanında tam olarak açılır.
Doğrulama: unlock_at, mühürleme anında gelecekte olmak ZORUNDADIR. unlock_at, created_at'tan en fazla 10 yıl uzakta olmak ZORUNDADIR (uzun ufuklu drand bağımlılık riskini sınırlamak için; arayüz 2 yılın ötesindeki açılma tarihleri için uyarı vermelidir — SHOULD).
5. Aktarım biçimi yeni tipleri
Aktarım biçimi yeni tipleri (newtypes), CBOR baytlarını JSON, ham düz metin veya diğer bayt kodlamalarıyla karıştırmaya karşı derleme zamanı güvenliği sağlar.
| Tür | İçerir | Üreten | Tüketen |
|---|---|---|---|
SealedQubCbor |
SealedQub'ın kanonik CBOR'u | serialize_sealed_qub() |
Kalıcı depolama yüklemesi, izleyici alımı |
QubEnvelopeCbor |
QubEnvelope'un kanonik CBOR'u | serialize_qub_envelope() |
tlock şifreleme girdisi, tlock şifre çözme çıktısı |
5.1 İnşa kuralları
// 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 İnşada doğrulama
from_encoded(), çift ayrıştırmayı önlemek için girdinin geçerli bir CBOR harita başlığıyla başladığını doğrulamalıdır (SHOULD). Tam yapısal doğrulama inşa zamanında değil, ayrıştırma zamanında gerçekleşir.
6. İçerik türü kayıt defteri
| Değer | Tür | Maksimum gövde boyutu | Notlar |
|---|---|---|---|
0x00 |
Ayrılmış (geçersiz) | — | Kullanılmamalıdır (MUST NOT) |
0x01 |
Düz metin (UTF-8, kısıtlı Markdown) | 50 KB ücretli / 10 KB ücretsiz | Sunum kuralları için bkz. §10. Ücretsiz / ücretli ayrımı yükleme hizmeti tarafından uygulanır; protokol katmanı kesin tavanı 50 KB'dir. |
0x02 |
Ayrılmış (gelecek) | — | Gelecekteki bir içerik türü için ayrılmıştır; v1'de geçerli değildir. İzleyiciler aşağıdaki kural uyarınca reddetmek ZORUNDADIR. |
0x03 |
Pakt (ikili anlaşma, CBOR gövdesi) | 100 KB | Gövde kanonik CBOR PactTerms'tür (§6.1). §9.7 uyarınca birlikte imzalayan imzalama. |
0x04 |
Karar (yaratıcı öz-değerlendirmesi, CBOR gövdesi) | 8 KB | Gövde kanonik CBOR VerdictBody'dir (§6.2). Yalnızca sistem tarafı verdict niyeti tarafından yayılır. Üst ilişki, gövdede değil, Parent-Tx-Id Arweave etiketindedir. Bkz. verdict-uplift-plan §3.4. |
İzleyiciler bilinmeyen içerik türlerini açık bir kullanıcıya görünür hata ile reddetmek ZORUNDADIR. İzleyiciler bilinmeyen türleri metin olarak sunmaya çalışMAMALIDIR.
6.1 Pakt gövdesi (content_type = 0x03)
Bir pakt gövdesi, bir PactTerms değerinin kanonik CBOR kodlamasıdır:
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)> }
Üç harita için kanonik CBOR anahtar sıraları §3.2'de verilmiştir. Toplam serileştirilmiş pakt CBOR 100 KB'yi aşMAMALIDIR (§6 ile eşleşir).
Şema ayırt edicisi. Bir structured/v1 paktında terms'teki ilk satır { key: "pact_schema", value: "structured/v1" } OLMALIDIR. Bu işareti olmayan satırlar "özel" paktlardır ve yapılandırılmış doğrulama veya şemaya duyarlı sunum almazlar.
Donmuş onay yuvaları. structured/v1 paktları bu anahtarlar altında tam olarak dört onay satırı taşır:
"initiator_standard_terms"
"initiator_capacity_terms"
"counterparty_standard_terms"
"counterparty_capacity_terms"
Her birinin value'su, (role, kind) çifti ile seçilen sekiz donmuş İngilizce dizeden biridir; burada role ∈ { seller, buyer, provider, client } ve kind ∈ { standard, capacity }. Dizelerin kendisi normatif protokol verisidir — her iki tarafın ML-DSA-65 imzaları, body_hash aracılığıyla tam baytlara taahhüt eder. Bunlar yerelleştirilMEZ; imzalanan gövde dilden bağımsızdır. Herhangi bir ifade değişikliği yeni bir şema sürümü gerektirir (structured/v2).
Sekiz dize, aramaları (acknowledgement_for(role, kind)) ve her birinin gerekçesi referans uygulama tarafından sabitlenir. Uyumlu uygulamalar bayt-aynı onay değerleri yaymak ZORUNDADIR; dört rol kombinasyonunun tamamını kapsayan altın-fikstür SHA3-256 gövde-özeti testleri herhangi bir kaymayı yakalar.
İzleyici görüntüleme sırası. Onay dizeleri, açıklama / kapsam satırlarının onaylardan önce sunulduğunu varsayan "yukarıda açıklandığı gibi" ("described above") gibi ifadeler içerir. İzleyiciler terms dizisini CBOR sırasında sunmak ZORUNDADIR; yeniden sıralama metnin anlamsal bütünlüğünü bozar.
Karşı taraf iletişimi. Taraf B'nin contact bilgisi geçerli bir e-posta adresi olduğunda, qub yükleme hizmeti, hazırlama anında otomatik olarak bir inceleme / birlikte imzalama davet e-postası gönderir ve nihai birlikte imzayı aynı adresin doğrulamasına bağlar (§9.7). Taraf B iletişimi olmayan paktlar yine de birlikte imzalanabilir, ancak yalnızca bant dışı bir kanal aracılığıyla — hizmet, eşleşen bir 15 dakikalık e-posta doğrulama işaretçisi üretemeyen birlikte imzalama isteklerini reddeder.
6.2 Karar gövdesi (content_type = 0x04)
Bir karar gövdesi, bir VerdictBody değerinin kanonik CBOR kodlamasıdır:
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
}
Kanonik CBOR anahtar sırası:
"outcome" (8 encoded bytes)
"reflection" (11 encoded bytes) ← only if present
"evidence_url" (13 encoded bytes) ← only if present
"verdict_version" (16 encoded bytes)
Toplam serileştirilmiş karar CBOR'u 8 KB'yi aşMAMALIDIR (yukarıdaki kayıt defteri satırıyla eşleşir).
Sonuç sıralı türü (enum). Tel baytı niyetten bağımsızdır; dört kategori — Right / Partial / Wrong / Unfalsifiable — karar taşıyan her niyetin sonuç uzayını kapsar. Niyete özgü etiketler (Right için "Bildim" / "Tuttum" / "Yayımlandı" / "Doğrulandı" gibi) izleyici tarafı sunum işidir ve üst qub'un niyetine göre çözümlenir — tel, dilden ve niyetten bağımsız kalır. 1..=4 dışındaki değerler kod çözmede reddedilmek ZORUNDADIR.
Üst bağlantısı. Bir karar qub'u, üst referansını gövdesinde taşıMAZ. Üst qub'un Arweave işlem kimliği, yükleme anında Parent-Tx-Id depolama etiketi olarak yayılır (§7 depolama-etiketi katmanı). Bu, gövdeyi kendi kendine yeten, imzalı bir öz-değerlendirme bildirimi olarak tutar; denetim zinciri ("ne hakkında haklı?") Arweave-etiketi araması üzerinden kurulur.
Kanıt URL güvenliği (normatif). evidence_url mevcut olduğunda, doğrulayıcılar (hazırlama tarafı, tel tarafı, Worker kenarı) şunları uygulamak ZORUNDADIR:
- Yalnızca HTTPS. Dize,
https://bayt dizisiyle başlamak ZORUNDADIR. Başka herhangi bir şema —http,ftp,javascript,data,filevb. — reddedilir. - Uzunluk üst sınırı. ≤ 2.048 bayt (tarayıcı URL pratik sınırı).
- NFC + düşmanca kod noktası denetimi.
titlevereflectionile aynı kural — bidi-override / sıfır genişlik / etiket bloğu / BOM / C0 / C1 kod noktaları reddedilir. Tanım, Rustcrate::handle::contains_hostile_text_codepointve TSworkers/api/src/utils/unicode.ts::isHostileCodepointile eşleşir (üçü birlikte ilerletilmek ZORUNDADIR). - Boşluk yok, ASCII denetim karakteri yok. URL'nin herhangi bir yerindeki boşluk / DEL /
0x20altındaki baytlar reddedilir — bidi kuralının kapsamadığı\n/\tenjeksiyon vektörünü kapatır. - Boş olmayan ana bilgisayar bölümü.
https://ile ilk/,?veya#arasındaki her şey boş olmayan ZORUNDADIR.
Sunucu tarafında getirme yok. Worker, URL'yi vekille çekMEMELİ, getirMEMELİ ya da önizleMEMELİDİR. Protokol bir dize saklar; sunum, rel="nofollow noopener noreferrer" target="_blank" ile izleyici tarafında gerçekleşir ve bağlantı metniyle birlikte görünür bir ana bilgisayar gösterilir.
Düşünce. İsteğe bağlı, yaratıcının yazdığı düşünce metni ("ne değişti, ne öğrendin"). title ile aynı NFC + düşmanca kod noktası doğrulaması. Boş / yalnızca boşluk içeren girdi, oluşturma anında yok sayılır.
Şema sürümü. v1 yalnızca verdict_version = 0x01'i destekler. Gelecekteki şema güncellemeleri bu baytı artırır ve §12 uyarınca yeni bir protokol sürümüyle birlikte iner.
7. Mühürleme protokolü
Tam mühürleme dizisi. Her adım normatiftir.
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.
Depolama etiket katmanı (bant dışı). qub yükleme hizmeti, sarmalanmış yüke ek olarak kasıtlı olarak küçük bir depolama işlem etiketi seti ekler. Content-Type=application/octet-stream normatif olarak gereklidir. Referans hizmet ayrıca, yaratıcı bunları yüzeye çıkarmayı seçtiğinde üç isteğe bağlı etiket ekler: Intent (izin listesi doğrulamalı oluşturma niyeti — örneğin quote, reply, commitment), Author (yaratıcının §9.3 açık anahtar parmak izi 64 karakterli küçük harf onaltılık olarak) ve Parent-Tx-Id (yanıt zincirleri için üst qub'un depolama işlem kimliği, 43 karakterli base64url).
Author etiketi qub başına opsiyoneldir: referans yaratıcı uygulaması bunu yalnızca kullanıcı mühürleme anında kamu atıfını açıkça etkinleştirdiğinde ekler. Geçiş kapalıyken — varsayılan — hiçbir Author etiketi yazılmaz ve qub zincirde atfedilmemiştir: kalıcı depolamadaki hiçbir şey yüklemeyi bir yaratıcının kullanıcı adına, e-postasına veya diğer qub'larına bağlamaz. Geçiş açıkken, Author parmak izi §9.5 onay zinciri aracılığıyla yaratıcının seçtiği @handle'a çözümlenir. Yanıt zinciri ilişkileri ve Intent tanımlayıcı değildir. Dış sarmalayıcı (§13), iç gövdeyi şifreli metin korelasyonundan korur — bir hasatçının drand turu yayınlandıktan sonra qub-şekilli yüklemeleri tanımasını ve toplu olarak şifresini çözmesini engeller.
Referans hizmet kasıtlı olarak App-Name, App-Version veya Type etiketlerini eklemez: bu tür herhangi bir tek değerli filtre, bir GraphQL sorgusuna tüm qub corpus'unu döndürür ki bu, sarmalayıcının yalnızca-gövde gizlilik kapsamıyla tutarsızdır.
Uyumlu bir doğrulayıcı, §11 üçüncü taraf doğrulaması için herhangi bir depolama etiketine bağımlı olMAMALIDIR; gövde özeti / qub_id / imza yalnızca iç CBOR'a taahhüt eder, asla etiket setine değil.
8. Açma protokolü
Tam açma dizisi. Her adım normatiftir.
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. Yazarlık imzalama
9.1 Gerekçe
qub'lar kalıcı depolamada saklanır. Yazarlık imzaları süresiz olarak sahteciliğe karşı dirençli kalmalıdır, bu nedenle v1.0, güvenliği qub'un kalıcı yaşam süresi içinde bozulabilecek klasik bir şema yerine post-kuantum ML-DSA-65 şemasını (FIPS 204) kullanır.
9.2 Algoritma kayıt defteri
sig_alg |
Şema | Anahtar boyutu | İmza boyutu |
|---|---|---|---|
0x00 |
İmza yok (imzasız) | — | — |
0x01 |
ML-DSA-65 (FIPS 204) | 1.952 bayt | 3.309 bayt |
İzleyiciler bilinmeyen sig_alg değerlerini reddetmek ZORUNDADIR.
9.3 İmzalı ön görüntü inşası
İki ön görüntü sürümü var olmuştur. Tüm imzalar V2 kullanmak ZORUNDADIR ve doğrulayıcılar yalnızca V2'yi kabul etmek ZORUNDADIR. Eski V1 ön görüntüsü (tarihsel referans için aşağıda belgelenmiştir), V2 geçişi sırasında yalnızca doğrulama amaçlı bir yedek olarak kabul ediliyordu; bu yedek kullanımdan kaldırılmıştır ve yalnızca V1 olan bir imza artık reddedilir.
V2 (güncel — tüm yeni yazar imzalaması tarafından ve pakt hazırlama / birlikte imzalama akışının her iki imzası tarafından üretilir):
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) ile aynı yokluk-nöbetçisi kuralını izler: 32 sıfır bayt geçerli bir SHA3-256 çıktısı değildir, bu nedenle "yok" hiçbir zaman mevcut bir etiketle çakışamaz. Tüm alanlar sabit genişliktedir, bu nedenle ön görüntü, uzunluk önekleri olmadan belirsizlik taşımaz.
V1 (eski — KULLANIMDAN KALDIRILDI; artık üretilmez ve doğrulamada artık kabul edilmez):
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 ön görüntüsü sender_label ve reply_to'yu dışarıda bırakıyordu. V2'ye geçiş sırasında yalnızca doğrulama amaçlı bir yedek olarak kabul ediliyordu; bu yedek o zamandan beri kullanımdan kaldırılmıştır — doğrulayıcılar yalnızca V2 ön görüntüsünü kabul etmek ZORUNDADIR. Tanım burada tarihsel referans için ve aşağıdaki etki alanı ayırıcısını açıklamak için tutulmuştur. Yalnızca V1'e karşı doğrulanan bir imza, bir doğrulama hatası olarak ele alınmak ZORUNDADIR.
Etki alanı ayırıcıları: "QUB_AUTHOR_SIG_V1" / "QUB_AUTHOR_SIG_V2" her biri 17 ASCII bayttır ([0x51, 0x55, 0x42, 0x5F, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x5F, 0x53, 0x49, 0x47, 0x5F, 0x56, 0x31/0x32]). Dolgu yok. Farklı ayırıcı, iki yapıyı etki alanı olarak ayırır, bu nedenle bir ön görüntü üzerindeki bir imza asla diğeri olarak doğrulanamaz.
org_id_present baytı: unlock_at'ı izleyen bayt 0x00 OLMALIDIR. Referans uygulama bunu crates/qub-core/src/signing.rs içinde ORG_ID_PRESENT_INDIVIDUAL = 0x00 sabiti olarak sunar; doğrulama için sig_input'u yeniden oluşturan izleyiciler aynı baytı yaymak ZORUNDADIR.
İmza kapsamı — neyi kapsar ve neyi kapsamaz. V2 sig_input'u doğrudan version, qub_id, body_hash, unlock_at, sender_label ve reply_to'ya taahhüt eder (artı sabit etki alanı ayırıcısı ve org_id_present baytı). qub_id'nin kendisi §4.1 ön görüntüsü aracılığıyla version, content_type, created_at, unlock_at, outcome_at, drand_round ve body_hash'ten türetilir, bu nedenle bu alanlarda yapılan herhangi bir değişiklik farklı bir qub_id üretir ve imzayı geçişli olarak geçersiz kılar. Bu nedenle kimliği doğrulanmış yüzey şudur:
| Alan | İmza ile kimliği doğrulanır | Nasıl |
|---|---|---|
version |
✓ | sig_input'a doğrudan girdi |
qub_id |
✓ | Doğrudan girdi |
body_hash |
✓ | Doğrudan girdi |
unlock_at |
✓ | Doğrudan girdi |
sender_label |
✓ | sender_label_hash aracılığıyla doğrudan girdi (V2 ön görüntüsü — kabul edilen tek biçim) |
reply_to |
✓ | reply_to_or_zero aracılığıyla doğrudan girdi (V2 ön görüntüsü — kabul edilen tek biçim) |
content_type |
✓ | qub_id ön görüntüsü aracılığıyla geçişli olarak |
created_at |
✓ | qub_id ön görüntüsü aracılığıyla geçişli olarak |
outcome_at |
✓ | qub_id ön görüntüsü aracılığıyla geçişli olarak |
drand_round |
✓ | qub_id ön görüntüsü aracılığıyla geçişli olarak (V1.2) |
body |
✓ | body_hash = SHA3-256(body) aracılığıyla geçişli olarak |
author_pubkey |
— (örtük) | İmzayı doğrulayan anahtar, tanım gereği yazardır |
cosigner_pubkey / cosigner_signature |
— | Aynı sig_input üzerinde bağımsız olarak imzalanır (bkz. §9.7) |
drand_chain_id, tlock_ciphertext, visibility |
— | Dış SealedQub alanları, zarfın içinde değil — kendi yapısal değişmezleri (tur / zincir tutarlılığı) tarafından kapsanır ancak yazar imzası tarafından kapsanmaz. (drand_round artık qub_id ön görüntüsü aracılığıyla geçişli olarak bağlanır — yukarıya bakın.) |
Neden yalnızca V2 kabul edilen ön görüntüdür.
- Kullanımdan kaldırılan V1 ön görüntüsü altında, depolanan baytlara yazma erişimi olan bir taraf,
sender_label'ı ("Alice" → "Mallory") değiştirebilir veyareply_to'yu yeniden bağlayabilir — ve tur sonrası yeniden şifreleyebilir — yazar imzasını geçersiz kılmadan, çünkü hiçbir alan imzalı ön görüntüde değildi. V2 her ikisini de kapsar, bu nedenle her iki alandaki herhangi bir değişiklik doğrulamayı "başarısız" duruma çevirir. Doğrulayıcılar artık yalnızca V2'yi kabul ettiğinden, bu değiştirme her imza için kapatılmıştır: hiçbir alanı bağlamayan (yani yalnızca V1'e karşı doğrulanan) bir imza, düşürülmek yerine doğrudan reddedilir. - Zarftaki
author_pubkey, gerçek kimlik dayanağı olarak kalır — izleyiciler görüntüleme kimliğinisender_label'a güvenmek yerineauthor_pubkey'den (§9.5 onay katmanı aracılığıyla) türetmek ZORUNDADIR.
sender_label veya reply_to'yu son kullanıcılara gösteren uygulamalar, kimliği doğrulanmış kimliği (açık anahtar parmak izi, onay) etiket yerine birincil kimlik sinyali olarak yüzeye çıkarmak ZORUNDADIR.
9.4 Doğrulama prosedürü
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."
İmza doğrulama en pahalı işlemdir (özellikle ML-DSA-65). Daha ucuz tüm kontroller (özet, qub_id, unlock_at) geçtikten sonra yapılmalıdır (SHOULD).
9.5 Kimlik onayları
Kimlik onayları — author_pubkey'in qub kullanıcı adı, e-posta adresi, sosyal kullanıcı adı veya parola anahtarı kimlik bilgisi gibi insan tarafından tanınabilen kimlik iddialarına eşlenmesi — izleyici tarafında aşamalı bir geliştirmedir ve imza doğrulaması için gerekli değildir. Onayları bir görüntüleme kimliğine çözen izleyiciler şu önceliği uygulamak ZORUNDADIR:
handle > email > social > fingerprint
Parmak izi yedeği, SHA3-256(author_pubkey)'in küçük harf onaltılığıdır; herhangi bir imzalı qub için her zaman kullanılabilir. İzleyiciler bunu görüntüleme için kısaltABİLİR — referans izleyici, qub: ardından ilk ve son dört baytı sunar (qub:<8 hex>…<8 hex>).
Uyumlu bir doğrulayıcı, qub API'sine başvurmadan, kalıcı depolama ve drand'ın ötesinde herhangi bir ağ olmadan ve herhangi bir sunucu tarafı araması olmadan §9.4'teki her kontrolü tamamlayabilir. Onay çözümleme, yalnızca imza doğrulaması başarılı olduktan sonra gerçekleştirilen ayrı bir en iyi çaba adımıdır.
9.6 Boyut etkisi
| Ed25519 | ML-DSA-65 | |
|---|---|---|
| İmza | 64 bayt | 3.309 bayt |
| Açık anahtar | 32 bayt | 1.952 bayt |
| qub başına toplam | 96 bayt | 5.261 bayt |
| Depolama maliyet farkı (~5$/MB ile) | ~0,0005$ | ~0,026$ |
500–2.000 bayt'lık bir metin qub için ML-DSA-65 depolanan boyutu kabaca üç katına çıkarır. Mutlak maliyet ihmal edilebilir düzeydedir.
9.7 Birlikte imzalayan doğrulaması (Pakt ikili anlaşmaları)
İkili anlaşmalar için (content_type = 0x03), ikinci bir imza katmanı her iki tarafın da aynı koşullara onay verdiğini kanıtlar.
Zarf alanları:
cosigner_pubkey: Karşı imzalayanın (Taraf B) ML-DSA-65 açık anahtarı.cosigner_signature: Yazarla aynısig_inputüzerindeki imza (§9.3).
Her iki alan da birlikte mevcut olmak veya her ikisi de yok olmak ZORUNDADIR. Yalnızca biri mevcutsa, izleyiciler bir bütünlük hatası bildirmek ZORUNDADIR.
Doğrulama prosedürü:
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."
Özellikler:
- Birlikte imzalayan, yazarla aynı
sig_input'u imzalar — her iki taraf da aynıqub_id,body_hashveunlock_at'a (ve V2 altında, aynısender_label_hashvereply_to_or_zero'ya) taahhüt eder. - Karşı imzalayanın ham zarf baytlarına erişimi olmadan V2 ön görüntüsünü yeniden oluşturabilmesi için, hazırlama hizmeti, hazırlama anında bir pakt zarfının
sender_label'ınınpact_terms.party_a.labeldeğerine eşit olmasını vereply_to'nun bulunmamasını zorunlu kılar. Her ikisi de her referans istemci paktı için geçerlidir; ihlal eden zarflar hazırlamada reddedilir. qub_idtüretmesi (§4.1) birlikte imzalayan alanlarını İÇERMEZ. Mevcut bir zarfa bir birlikte imzalayan eklemekqub_id'yi değiştirmez.- Bir pakt yalnızca yazar tarafından imzalanmış (tek taraflı taahhüt), yalnızca birlikte imzalayan (alışılmadık) veya her ikisi (tam ikili kanıt) olabilir.
E-posta bağlama kapısı (operasyonel). Hazırlanan bir pakt bir Taraf B e-posta iletişimi taşıdığında (§6.1), qub yükleme hizmeti, hem hazırlama kimliği hem de bu iletişimin normalleştirilmiş e-posta özeti ile eşleşen kısa ömürlü bir e-posta doğrulama işaretçisi mevcut olmadıkça birlikte imzalama isteğini reddetmek ZORUNDADIR. İşaretçi, sihirli bağlantı belirteci bir staging_id taşıdığında ve doğrulanmış adres SHA-256(normalise_email(party_b.contact)) ile eşleştiğinde /api/v1/auth/verify tarafından yazılır — burada normalise_email(addr) yerel bölümün büyük/küçük harfini korur ve yalnızca etki alanı bölümünü küçük harfe çevirir (RFC 5321 §2.3.11 uyarınca) ve buradaki SHA-256, NIST FIPS 180-4 özetidir (§4 türetmelerinde kullanılan SHA3-256'dan farklı) — ve verildikten 900 saniye (15 dakika) sonra sona erer. Bu operasyonel bir kimlik taklidine karşı kapıdır, zincir üzerindeki qub kanıtının bir parçası DEĞİLDİR — §11'i yeniden oynayan üçüncü taraf bir doğrulayıcının yalnızca kalıcı depolama ve drand'a ihtiyacı vardır, herhangi bir sunucu tarafı araması olmadan. İşaretçi yalnızca sunucu tarafında bulunur ve asla imzalanmış gövdenin bir parçası değildir.
Boyut etkisi (ML-DSA-65 yazar + birlikte imzalayan):
| Bileşen | Boyut |
|---|---|
| Yazar imzası | 3.309 bayt |
| Yazar açık anahtarı | 1.952 bayt |
| Birlikte imzalayan imzası | 3.309 bayt |
| Birlikte imzalayan açık anahtarı | 1.952 bayt |
| Toplam kripto ek yükü | 10.522 bayt |
| Depolama maliyet farkı | ~0,05$ |
10. Markdown sunumu ve temizleme
Bu bölüm güvenlik açısından kritiktir. İzleyici, metin qub'larını (content_type = 0x01) kısıtlı bir Markdown alt kümesi kullanarak sunar.
10.1 İzin verilen öğeler
- Başlıklar:
#'tan####'a (#####veya######yok) - Vurgu: kalın (
**), italik (*), üstü çizili (~~) - Listeler: sıralı (
1.) ve sırasız (-,*) - Alıntı blokları (
>) - Kod: satır içi aralıklar (```) ve çitlenmiş bloklar (`````)
- Yatay çizgiler (
---) - Satır sonları (iki sondaki boşluk veya boş satır)
- Paragraflar
10.2 Yasaklanan öğeler
| Öğe | İşleme |
|---|---|
Ham HTML (<div>, <script>, vb.) |
Tamamen çıkarılır. HTML'den hiçbiri geçmez. |
Görseller () |
Çıkarılır. Görsel söz dizimi çıktıdan kaldırılır. |
Bağlantılar ([text](url)) |
URL görünür düz metin olarak sunulur. Otomatik bağlantılanmaz. Açık kullanıcı eylemi olmadan tıklanabilir değildir. |
| Tehlikeli URL şemaları | javascript:, data:, vbscript:, file: — çıkarılır. |
| iframe'ler, gömülenler, nesneler | Çıkarılır. |
| HTML varlıkları | Yalnızca güvenliyse görüntüleme karakterlerine kod çözülür. |
10.3 Uygulama
Uygulamalar bir kara liste değil, katı bir izin listesi ayrıştırıcısı kullanmak ZORUNDADIR. Önerilen yaklaşım:
- Markdown'ı
pulldown-cmark(veya eşdeğeri) kullanarak ayrıştırın. - AST'de gezinin ve izin listesinde olmayan herhangi bir düğümü atın (§10.1).
- Bağlantı düğümleri için: URL'yi tıklanabilir bir
<a>öğesi olarak değil, görünür metin olarak yayın. - Filtrelenmiş AST'yi tipli bir ara temsile dönüştürün (örneğin, yalnızca güvenli varyantları olan bir
MarkdownNodeenum'u). Bu IR'de ham HTML yapısal olarak temsil edilemez. - Tipli IR'den hedef görünüm katmanına (örneğin, reaktif görünüm bileşenleri, DOM düğümleri) sunum yapın. Hiçbir noktada HTML dize birleştirme veya
innerHTMLkullanılmaz.
Kara liste yaklaşımları kırılgandır çünkü yeni Markdown uzantıları veya ayrıştırıcı tuhaflıkları filtrelenmemiş öğeler getirebilir. Tipli AST yaklaşımı, XSS'yi yapısal olarak imkansız hale getirir — keyfi HTML taşıyabilecek bir varyant yoktur.
10.4 Boyut ve yapı sınırları
- Maksimum sunulan başlık derinliği:
####(H4).#####ve daha derin olanlar kalın metin olarak sunulur. - Paragraf sayısında sınır yoktur (gövde boyutu sınırları §6'da kısıtlamadır).
- Çitlenmiş kod blokları: MVP'de söz dizimi vurgulama yok. Monospace önceden biçimlendirilmiş metin olarak sunulur.
11. Üçüncü taraf doğrulaması
Herhangi bir üçüncü taraf, qub işbirliği olmadan bir kamu qub'unu doğrulayabilir. Doğrulama prosedürü:
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.
Doğrulamanın kanıtladıkları:
| Kanıt | Ne kurar |
|---|---|
| Taahhüt | Şifreli metin depolama blok zaman damgasına kadar var olmuştur. |
| Bütünlük | Düz metin gövdesi taahhüt edilen özetle eşleşir ve değiştirilmemiştir. |
| Zamanlama | İçerik, seçilen açılma zamanına karşılık gelen drand turuna kadar okunamazdı (tlock ve drand güvenlik varsayımlarına tabidir). |
Doğrulamanın kanıtlaMADIKLARI:
| Kanıtlanamayan | Neden |
|---|---|
| Yazarlık | sender_label dekoratiftir. sig_alg ≥ 0x01 olmadan, bu içeriği herhangi biri mühürlemiş olabilir. |
| Niyet | qub içeriği ve zamanlamayı kanıtlar, yaratıcının öznel olarak ne demek istediğini değil. |
| Olay öncesi zamanlama | Depolama blok dahil edilmesi gerçek yüklemeden dakikalarca gecikebilir. Taahhüt zaman damgası blok zamanıdır, kullanıcının "mühürle"ye bastığı an değildir. |
12. Sürümleme
12.1 Protokol sürümü
Hem SealedQub hem de QubEnvelope içindeki version alanı (u8), birincil protokol sürümünü tanımlar.
- İzleyiciler bilinmeyen birincil sürümleri açık bir hata ile reddetmek ZORUNDADIR.
- Bilinen bir birincil sürüm içinde, kod çözücüler bilinmeyen harita anahtarlarını reddetmek ZORUNDADIR (§3.1) — şema evrimi, mevcut kod çözücülerin atlayacağı anahtarlar eklenerek değil, yeni bir
versiontanıtılarak gerçekleşir. (Bu spesifikasyonun önceki revizyonları bilinmeyen isteğe bağlı alanların tolere edilmesine izin veriyordu; o madde geri çekilmiştir —encode(decode(x))işlemini birebir olmaktan çıkarıyor ve pakt yükleri üzerinde bir gizli-imzalı-içerik vektörü açıyordu.) - İçerik türleri (
content_type) ve imza şemaları (sig_alg) sürüm kapılıdır: yeni değerler yalnızca yeni bir protokol sürümü veya açık kayıt defteri güncellemesi ile birlikte tanıtılabilir.
12.2 Sürüm geçmişi
| Sürüm | Değer | Açıklama |
|---|---|---|
| v1 | 0x01 |
Kamu metin qub'ları (content_type 0x01), pakt ikili anlaşmaları (0x03, structured/v1 şeması, ML-DSA-65 yazar + birlikte imzalayan), tlock, SHA3-256 |
12.3 İleriye dönük uyumluluk
Bilinmeyen CBOR harita anahtarlarına (§3.2 kanonik sırasında olmayan anahtarlar) sahip bir QubEnvelope ile karşılaşan bir v1 izleyicisi, onu bir kod çözme hatası ile reddetmek ZORUNDADIR (§3.1). İleriye dönük uyumluluk version alanına dayanır, anahtar toleransına değil: gelecekteki eklemeler — küçük meta veriler bile — yeni bir version değeri altında yayımlanır ve bir v1 izleyicisi bunu, imzaların taahhüt ettiği içeriği sessizce düşürmek yerine açık bir "daha yeni protokol" hatasıyla reddeder.
sig_alg = 0x01 (ML-DSA-65) ile karşılaşan ancak ML-DSA-65 doğrulama desteğinden yoksun bir v1 izleyicisi, qub'u tamamen reddetmek yerine "imza mevcut ancak doğrulanamaz" notu ile qub içeriğini görüntülemelidir (SHOULD). Bugünkü referans uygulama, 0x00 ve 0x01 dışındaki her sig_alg değerini reddeder çünkü v1 kayıt defterinde başka geçerli algoritma yoktur — üçüncü bir algoritma kaydedilene kadar katı reddetme ve yumuşak hata gözlemsel olarak aynıdır. Yukarıdaki yumuşak hata davranışı, §9.2 yeni bir giriş kabul ettikten sonra yük taşır hale gelir ve referans izleyici o noktada yumuşak hataya güncellenecektir.
12.4 Dış sarmalayıcı sürümü
§13'te açıklanan OuterWrapper, SealedQub.version ve QubEnvelope.version'dan bağımsız olarak kendi version baytını taşır. İki sürüm alanı ayrı ayrı evrimleşir: gelecekteki post-kuantum-güvenli bir simetrik değiştirme, iç protokol sürümüne dokunmadan sarmalayıcı baytını yükseltir ve gelecekteki bir protokol katmanı eklemesi (örneğin yeni bir zarf alanı), sarmalayıcı baytına dokunmadan iç sürümü yükseltir.
OUTER_WRAPPER_VERSION_* |
Değer | Algoritma | Durum |
|---|---|---|---|
OUTER_WRAPPER_VERSION_1 |
0x01 |
12-baytlık nonce, 16-baytlık kimlik doğrulama etiketi, qub_id'ye bağlı AAD ile AES-256-GCM |
v1 varsayılan |
| — | 0x02–0xFF |
Ayrılmış | Gelecek |
İzleyiciler bilinmeyen sarmalayıcı sürümlerini açık bir hata ile reddetmek ZORUNDADIR. Protokol, somut bir geçiş itici gücü ortaya çıkana kadar (örneğin farklı bir AEAD'yi destekleyen NIST kılavuzu) sarmalayıcı sürüm alanını kasıtlı olarak dar tutar; bir 0x02 yuvası, algoritmayı tanıtan aynı revizyonda tahsis edilecektir.
13. Dış şifreleme sarmalayıcısı
13.1 Gerekçe
Protokol katmanları (QubEnvelope → tlock → SealedQub) mühürlü bir qub'u zamana kilitli yapar: gövde unlock_at'a ve drand tur imzası yayınlanana kadar okunamaz. Ancak açılmadan sonra, tur imzası kamuya açıktır ve SealedQub'un kanonik CBOR şekli tanınabilirdir, bu nedenle kalıcı depolama işlemlerini indeksleyen bir hasatçı, tüm qub corpus'unu toplu olarak şifresini çözebilir.
Dış şifreleme sarmalayıcısı, kanonik SealedQubCbor ile kalıcı depolamaya yazılan baytlar arasına ek bir simetrik AEAD katmanı yerleştirerek bu kanalı kapatır. 256-bitlik anahtar K, yalnızca teslim URL'sinin URL parçasında ve kullanıcı cihazlarında bulunur; tarayıcılar URL parçalarını sunuculara iletmez, bu nedenle qub.social, her depolama ağ geçidi ve her ikisinin önündeki her CDN, K'ye gözlemsel olarak kördür. Bu nedenle kalıcı depolamadaki her qub, düz metni yaratıcının paylaşmayı seçtiği URL olmadan kurtarılamayan opak bir şifreli metindir.
Net etki:
- Varsayılan olarak numaralandırma bağışıklığı. Kalıcı depolamadaki sarmalanmış baytlar, keyfi şifreli metinden bayt olarak ayırt edilemez. "qub-şekilli yüklemeler için GraphQL sorgusu yap, kamu drand imzalarıyla toplu şifre çöz" şeklindeki bir hasatçı stratejisi düz metinle sonlanmaz.
- Kripto-parçalama gizlilik duruşu. qub.social, kendi corpus'unun şifresini kelimenin tam anlamıyla çözemez. Mahkeme celpleri şifreli metne ulaşır, düz metne değil.
- İki katmanlı gizlilik merdiveni. Varsayılan = bağlantı kontrollü erişim (bu bölüm). Alıcıyla şifrelenmiş özel qub'lar (Faz 2 için ayrılmış, henüz tanımlanmamış bir özellik), ikinci katman olarak üstte katmanlanır.
13.2 Katmanlama
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)
Protokol katmanındaki mühürleme ve açma (§7, §8) sarmalayıcı sınırının altında değişmez; sarmalayıcı seal()'ın çağrı yerinde takılır ve unlock()'ın çağrı yerinde çıkarılır.
13.3 OuterWrapper veri yapısı
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
}
Alan değişmezleri.
version, v1.0 sarmalayıcı baytları için0x01'e eşit OLMALIDIR.qub_id, sarmalama açıldıktan sonra kurtarılan SealedQub'unqub_idalanına eşit OLMALIDIR. Sarmalama açma adımı bunu doğrudan zorlamaz (AEAD AAD bağlama, bayt düzeyinde kurcalamayı imkansız kılar), ancak açma katmanı ilişkiyi geçişli olarak kontrol eder: bir yaratıcı, içqub_id'si sarmalayıcıqub_id'siyle eşleşmeyen birSealedQubCbor'u sararsa, §8 adım 11 başarısız olur.nonce, 96 bit (12 bayt) OLMALIDIR, her sarmalama işlemi için bir CSPRNG tarafından taze olarak üretilir. Aynı anahtar altında bir nonce'u yeniden kullanmak, düz metni kurtaran AEAD nonce-yeniden kullanım saldırılarına izin verir; üreticiler (key,nonce) çiftlerini tek atışlık olarak işlemek ZORUNDADIR.ciphertext, AES-256-GCM çıktısıdır: 16 bayt kimlik doğrulama etiketi ile birleştirilmiş şifreli metin baytları.ciphertext.len() == SealedQubCbor.len() + 16tam olarak.
CBOR kodlaması. §3 uyarınca kanonik CBOR, aynı anahtar sıralama kuralıyla (artan kodlanmış bayt uzunluğuna göre sıralı, sonra sözlüksel olarak). Dört anahtar şudur:
| Anahtar | Kodlanmış baytlar | Sıra |
|---|---|---|
nonce |
6 | 1 |
qub_id |
7 | 2 |
version |
8 | 3 |
ciphertext |
11 | 4 |
Bu nedenle OuterWrapper CBOR'unun ilk baytı, 4-girişli bir harita için kesin uzunluklu harita başlığıdır (0xA4).
13.4 qub_id'ye AAD bağlama
Sarmalayıcı, qub_id'yi AEAD ek kimliği doğrulanmış veri olarak bağlar. Bu, üç sınıf saldırıya karşı yük taşıyan yapısal savunmadır:
| Saldırı | Savunma |
|---|---|
Şifreli metni sarmalayıcıdaki farklı bir qub_id alanı altında taşımak |
AAD uyuşmazlığı → AEAD kimlik doğrulaması başarısız olur |
| qub A'nın URL parçasını qub B'nin depolama baytları ile karıştırmak | AAD uyuşmazlığı → AEAD kimlik doğrulaması başarısız olur |
Yüklemeden sonra sarmalayıcının qub_id alanını kurcalamak |
AAD uyuşmazlığı → AEAD kimlik doğrulaması başarısız olur |
qub_id'yi sarmalayıcı düz metninde taşımak, numaralandırma bağışıklığını anlamlı ölçüde zayıflatmaz — qub_id'nin kendisi §4.1 ön görüntüsünün özetten kurtarılamayan ön görüntüsüz bir SHA3-256 özetidir ve sarmalayıcı baytlarını zaten toplayan bir numaralandırıcı, görünür qub_id'den yüklemenin varlığından çıkarabileceğinden daha fazla bir şey öğrenmez.
13.5 Sarmalama ve sarmalama açma algoritmaları
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
Hata modu çöküşü. Yanlış K, yanlış nonce, AAD uyuşmazlığı ve kurcalanmış şifreli metin, hepsi aynı DECRYPT_FAILED hatasını üretir. Bu, kasıtlı bir AEAD özelliğidir: hata modunu ayırt etmek, uzaktan bir saldırganın hatalı biçimlendirilmiş sarmalayıcılar göndererek ve yanıtı zamanlayarak araştırabileceği bir yan kanal oluşturur. Referans uygulamalar tüm AEAD hatalarını tek bir hata şekline daraltmak ZORUNDADIR.
13.6 Anahtar materyali ve dağıtım
Sarmalama anahtarı K, bir CSPRNG tarafından qub başına üretilen 256-bitlik tek tip rastgele bir değerdir. Referans uygulamalar bunu şuradan alır:
- WASM yaratıcısı:
getrandom(wasm_jsarka ucu altında WebCrypto). - Sunucu tarafı mühürleme API çağırıcısı: kendi yerel CSPRNG'si; çağırıcı
K'yıwrapper_key_b64urlolarak sağlar ve saklar. Worker, sarmalayıcı içinK'yı bellekte kullanır ancak onu kalıcı kılmamalıdır (MUST NOT). Bu, bir idempotent yeniden denemenin, tek seferlik sunucu tarafında üretilen bir gizli değere bağlı kalmak yerine çağırıcının sakladığı yetkiyi kullanarak redakte edilmiş bir yanıtı kurtarmasına olanak tanır.
Dağıtım: K, URL-güvenli base64 (RFC 4648 §5, dolgu yok) olarak kodlanmak ve teslim URL'sine parça bileşeni olarak eklenmek ZORUNDADIR:
delivery_url = <origin>/c/<arweave_tx_id>#<base64url(K)>
Parça, uyumlu bir tarayıcı tarafından hiçbir sunucuya iletilmez. Tam teslim URL'sini — parça dahil — kullanıcının cihazının ötesinde kalıcı kılan kurtarma kanalları (sunucu tarafı geçmiş dizini, opt-in e-posta otomatik gönderme), varsayılan kripto-parçalama duruşuna karşı açık bir takastır ve açık kullanıcı onayına kapılı olmak ZORUNDADIR.
Parça kaybı. Bir kullanıcı URL parçasını kaybeder ve kurtarma kanalı yoksa, qub okunamaz. Bu, tasarımın yük taşıyan takasıdır ve mühürleme anında kullanıcıya açıklanmak ZORUNDADIR. MVP, mühürleme anı açıklamasını açık "bu URL'yi kaydedin" metni ve opt-in yapan kullanıcılar için doğrulanmış-e-posta kurtarma kanalı ile güçlendirir.
13.7 Bu bölümün kapsamı dışında
- Yazarlık imzalama (§9) değişmez: imzalar iç
QubEnvelopeiçinde hesaplanır ve sarmalama açma → tlock şifre çözme → CBOR ayrıştırma sonrasında kurtarılır. - Alıcıyla şifrelenmiş özel qub'lar (Faz 2 için ayrılmış, henüz tanımlanmamış bir özellik) bu sarmalayıcının üzerine ikinci bir gizlilik katmanı olarak oluşturulur; her iki katman aynı anda etkin olabilir.
- Paktlar (§6, content_type
0x03) tam olarak metin qub'ları gibi sarmalanır; sarmalayıcı iç içerik türüne bayt olarak kördür.
13.8 Kamu qub'ları (sarmalayıcı atlanması)
Dış sarmalayıcı, teslim katmanında isteğe bağlıdır. Bir yaratıcı bir qub'u kamu olarak mühürleyebilir; bu durumda kanonik SealedQubCbor, OuterWrapper katmanı ve K anahtarı olmadan kalıcı depolamaya doğrudan yazılır:
SealedQubCbor bytes ──(public)──▶ uploaded to permanent storage as-is
SealedQubCbor bytes ──(private)─▶ AES-256-GCM(K, …) ▶ OuterWrapper ▶ uploaded
Bir kamu qub'u zamana kilitlidir ancak bağlantı kontrollü değildir: drand turu yayınlanana kadar okunamaz durumda kalır (tlock katmanı değişmez), ancak açılmadan sonra arweave_tx_id'ye sahip olan herkes onun şifresini çözebilir — hiçbir URL parçası gerekmez, çünkü bir K yoktur. Bu, sunucunun yürütmesi gereken yüzeyler için kasıtlı bir takastır: açılma bildirimi e-postaları, üçüncü taraf gömme öğeleri ve daha zengin açılma sonrası SEO'nun tümü, sunucunun asla elinde tutmadığı bir gizli değer olmadan çalışan bir bağlantıya ihtiyaç duyar (§13.6).
Bir üreticinin hesaba katmak ZORUNDA olduğu sonuçlar:
- Numaralandırma bağışıklığı yok. Kamu qub'ları, yapısı gereği §13.1 numaralandırma bağışıklığı özelliğinden vazgeçer. Referans yükleme hizmeti, bunlara (ve yalnızca bunlara) bir
Visibility: publickalıcı depolama etiketi basar, böylece kasıtlı olarak keşfedilebilirler; özel qub'lar böyle bir etiket taşımaz ve bayt olarak ayırt edilemezliklerini korur. - Mühürleme anında açığa çıkan düz metin başlık. §3.2
titlealanı,SealedQubCboriçinde düz metindir. Sarmalayıcının altında, bir izleyiciKsağlayana kadar gizlidir; sarmalayıcı olmadan, açılmadan önce yükleme anından itibaren kalıcı depolamada herkes tarafından okunabilir. Uyumlu yaratıcı uygulamaları bunu mühürleme anında açıklamak ZORUNDADIR. - Tespit yapısaldır. Uyumlu bir izleyici/gömme öğesi, iki şekli ayrıştırarak ayırt eder:
OuterWrapperolarak ayrıştırılan baytlarKile sarmalama açma yolunu izler; çıplak birSealedQubCborolarak ayrıştırılan baytlar doğrudan kabul edilir. Hiçbir kablo bayrağı gerekmez vequb_idgörünürlüğe bağlanmaz — aynı içerik, kamu olarak mı yoksa özel olarak mı mühürlendiğine bakılmaksızınSealedQubkatmanında bayt olarak özdeştir.
Özel (sarmalanmış) varsayılan olarak kalır; kamu, açık bir qub-başına yaratıcı seçimidir.
14. Test vektörleri
14.1 qub_id türetmesi
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
Uygulamalar bu girdi için aynı body_hash ve qub_id değerlerini üretmek ZORUNDADIR. Bu test vektörü yazılan ilk birim testi olmalıdır (SHOULD). Yukarıdaki kanonik değerler referans uygulama tarafından hesaplanmıştır ve bit-bit eşleşmek ZORUNDADIR. Tarihsel ön görüntü düzenleri (lansman öncesi — bu değerlere bağlı canlı qub yoktu): 92 baytlık V1.0 qub_id şuydu: 3d9fc2390eab043d38a1669ed3b71be76f9eefe872b9569ab1aaa027b88392b0; 100 baytlık V1.1 qub_id (outcome_at_or_zero katlandıktan sonra) şuydu: b0d032898ad629795150fdcb3f84e518f59ed05b7a2a82bc24ebdb87f52144ed. V1.2, drand_round'u katlar ve etki alanı ayırıcısını QUB_ID_V2'ye yükseltir.
14.2 Açılma turu eşleştirmesi
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 Kanonik CBOR gidiş-dönüşü
Uygulamalar, tüm geçerli girdiler için serialize(parse(serialize(qub))) == serialize(qub) olduğunu doğrulamak ZORUNDADIR. Bu tek bir vektör değil, bir özellik testidir.
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)
Kanonik CBOR baytları ve SHA3-256 body_hash, referans uygulama tarafından hesaplanır. Uygulamalar bu girdi için bayt-aynı CBOR üretmek ZORUNDADIR.
Uygulamalar ayrıca, tüm geçerli PactTerms girdileri için serialize(parse(serialize(pact))) == serialize(pact) olduğunu doğrulamak ZORUNDADIR (özellik testi).
14.5 Dış sarmalayıcı diller arası vektörler
Dış sarmalayıcı (§13), crates/qub-core/tests/vectors/wrapper_v1.json konumunda ayrı bir kanonik fikstüre sahiptir. Her vaka, opak onaltılık girdiler olarak bir (key, nonce, qub_id, sealed_cbor) demetini sabitler ve belirli bir expected_wrapper_hex çıktısını onaylar. Her iki referans uygulama da aynı JSON dosyasını tüketir:
- Rust:
crates/qub-core/tests/wrapper_vectors.rs(cargo test -p qub-core --test wrapper_vectors). - TypeScript:
workers/api/src/crypto/__tests__/wrapper.test.ts(npm test).
Fikstür şu anda üç vakayı sabitler:
| Vaka | Kapsam |
|---|---|
basic-text-public |
En küçük gerçekçi SealedQub şekli; isteğe bağlı alan yok. v1.0-tipik bir qub için kanonik sarmalayıcı şeklini kurar. |
with-recipient-pubkey |
recipient_pubkey ayarlı SealedQub (Faz 2 yolu). Farklı iç CBOR anahtar seti, farklı qub_id. |
longer-body |
~4 KiB gövde — hem iç zarfta hem de dış şifreli metinde çok baytlı CBOR uzunluk öneklerini sınar. |
Uygulamalar, kaydedilen girdiler için bayt-aynı expected_wrapper_hex üretmek ZORUNDADIR. Fikstürü yeniden oluşturmak QUB_REGEN_VECTORS=1 cargo test -p qub-core --test wrapper_vectors gerektirir ve kasıtlı biçim değişiklikleri için ayrılmıştır.
15. Kripto profil yönetişimi (Gelecek)
Bu bölüm v1 için bilgilendiricidir ve qub'un kriptografik ilkellerinden herhangi birine ikinci bir algoritma girdiği ilk anda normatif hale gelir.
15.1 Mevcut duruş
Protokol v1, ilkel başına tam olarak bir algoritmaya bağlanır:
- İmza: ML-DSA-65 (
sig_alg = 0x01; 1952 baytlık açık anahtar, 3309 baytlık imza) ve imzasız (sig_alg = 0x00). §9.2 kayıt defteri başka hiçbir değer tanımlamaz; v1 doğrulayıcısı{0x00, 0x01}dışındaki hersig_algdeğerini reddetmek ZORUNDADIR. Gelecekte bir Ed25519 girişi öngörülmektedir (§15.3) ancak v1'de ayrılmamıştır. - Zaman kilidi: yalnızca drand quicknet — zincir özeti, açık anahtar, doğuş zamanı ve periyot, referans
DrandTimelockProvider::quicknet()(crates/qub-core/src/tlock.rs) veconfig/drand-endpoints.jsontarafından taşınan sabit ağ parametreleridir. - Dış sarmalayıcı: yalnızca AES-256-GCM v1 (§13).
Doğrulayıcılar şu anda ilkel başına anahtar ve imza uzunluklarını sabit kodlar. Aktarım biçimi tarafından çeviklik yüzeyi sunulmaz.
15.2 Hedeflenen şekil
Protokole ikinci bir algoritma girdiğinde, doğrulayıcı, ilkel başına izin verilen değerlerin tam setini — sig_alg'ler, drand zincirleri, sarmalayıcı sürümleri, içerik türleri — listeleyen adlandırılmış bir CryptoProfile (örneğin ExqubV1) için yapılandırılacaktır. Profil doğrulama zamanında sabitlenir, asla bant içinde müzakere edilmez. Aktif profilin dışındaki herhangi bir değer reddedilir.
Bu, ML-DSA-87 eklemenin veya Ed25519'u etkinleştirmenin mevcut doğrulayıcı yapılandırmalarını geriye dönük olarak zayıflatamamasını garanti eder: bir v1 doğrulayıcısı, bir v2 profili yayınlandıktan sonra bile bir v1 doğrulayıcısı olarak kalır.
15.3 Tetikleyici koşullar
§15'i şunlardan herhangi biri önerildiğinde normatif duruma yükseltin:
- İkinci bir
sig_algbaytı (Ed25519 etkinleştirmesi, ML-DSA-87 veya §9 kayıt defterindeki herhangi bir yeni giriş). - Üretimde kullanılan ikinci bir drand zinciri.
- İkinci bir dış sarmalayıcı sürümü.
O zamana kadar §15, gelecekteki PR'ların müzakere yüzeyini sıfırdan yeniden tartışmak yerine bilinen bir hedefe karşı inmesi için geçiş şeklini sabitleyen bir yer tutucudur.
16. Şeffaflık günlüğü ve dayanıklılık katmanları (Tasarım — inceleme tamamlandı)
Durum. Bu bölüm bir tasarım belirtimidir. Aşağıdaki kablo biçimleri, özetleme ve güven modeli uygulama açısından normatiftir, ancak henüz hiçbir şeffaflık günlüğü kodu yayınlanmamıştır. W5 dış incelemesi tamamlandı: §16.15, çözülen kararları ve incelemeden çıkan bağlayıcı lansman kısıtlarını kaydeder. Uygulama bu kısıtlar altında ilerleyebilir. §16, §15 ile aynı anlamda ileriye dönük kalır — uygulamanın güven modelini kod incelemesinde yeniden türetmek yerine yerleşmiş bir tasarıma karşı inmesi için hedefi sabitler. Kesinlikle eklemelidir — mevcut her qub kendi bireysel Arweave işlemini korur ve
SealedQub/QubEnvelopekablo biçiminde hiçbir değişiklik yoktur.
16.1 Gerekçe ve dayanıklılık katmanları
Bugün bir qub'un dayanıklılığı ve zamansal taahhüdü, her ikisi de tek bir qub-başına Arweave işlemine dayanır (§11). Bu, mühürleme gecikmesini Arweave kesinliğine bağlar, qub-başına yüklemeyi bir ürün maliyet tavanı yapar (ARWEAVE_DAILY_CEILING) ve qub'lar arasında kurcalamaya karşı kanıt sunan bir sıralama sağlamaz. Şeffaflık günlüğü, bu tek katmanın altına ve etrafına iki katman ekler:
| Katman | Ad | Garanti | Ne zaman |
|---|---|---|---|
| T1 | R2-öncelikli senkron onay | Dayanıklılık tabanı — mühürlenmiş baytlar, mühürleme dönmeden önce dayanıklı depolamaya yazılır (< 300 ms p95). |
Her qub, senkron olarak (§16.10). |
| T2 | Toplu şeffaflık günlüğü dahil edilmesi | Evrensel ekleme-yalnızca, kurcalamaya karşı kanıt sunan taahhüt + toplam sıralama, Arweave'e demirlenmiş. | Her qub, ertelenmiş + toplu (§16.5–16.7). |
| T3 | qub-başına Arweave kalıcılığı | qub için bireysel bir Arweave işlemi. | Ücretli ek satış ve Arweave-erişilemezlik yedeği (§16.8). |
T2, qub-başına Arweave'i tek dayanıklılık yolu yerine bir seçim (T3) yapar. ARWEAVE_DAILY_CEILING, bir ürün tavanı olmaktan çıkarılır ve yalnızca özel demir cüzdanı üzerinde bir devre kesiciye indirgenir (§16.7); kullanıcı mühürlemeleri bunu aştığı için asla reddedilmez.
Dayanıklılık dürüstlüğü (çözüldü — §16.15 Q6). Dayanıklılık gerilemez: T1 R2 yazması senkron ve tek-yazımlıktır, bu nedenle T3 satın almamış ücretsiz katman bir qub'u, mühürleme döndüğü anda tamamen dayanıklıdır. Kabalaşan şey, kanıtlanabilir üst sınır taahhüt zamanıdır: ücretsiz bir qub için bu, qub-başına işlem blok zamanı yerine demir blok zamanı olur. Düşük hacimde — gerçekçi erken-lansman ve yoğun olmayan durum — tam günlük tempo, nadir bir uç durum değil, tipik tabandır. Bu nedenle ürün çerçevelemesi, taahhüt edilmiş hiçbir sayısal gecikme olmadan bir üst sınırdır — "şimdi mühürlü ve dayanıklı; bir sonraki günlük demirinde bağımsız bir kamu zaman damgası eklenir (tipik olarak günlük)" — ve tam-saat taahhüt kanıtı, ücretli bir T3 özelliğidir, katman-karşılaştırma yüzeyinde ve koşullarda açıklanır (§16.11, §16.15 Q6). Herhangi bir zaman sınırı yalnızca dahili bir SLO'dur, asla pazarlanan bir SLA değildir.
16.2 LogLeaf yapısı (iki taahhüt edilmiş şekil)
Bir günlük girdisi, §3.1 profili altında elle yazılmış kanonik CBOR olarak kodlanan bir LogLeaf'tir (kesin uzunluklu, etiket yok, kayan nokta yok, en kısa biçimli tamsayılar, NFC metin, yoksa atlanan isteğe bağlı alanlar, anahtarlar artan kodlanmış-bayt uzunluğuna sonra bayt-bazında sıralı). §3.1 ayrıştır → yeniden kodla → karşılaştır kanonik koruması, özetlemeden önce kodlama yolunda uygulanır (yalnızca kod çözmede değil), bu nedenle iki uygulama bir tamsayı-genişliği veya anahtar-sırası farkı yoluyla yaprak baytları üzerinde anlaşmazlığa düşemez. Tüm tamsayılar u8 / u64 / i64'tür; tüm özetler 32-baytlık bayt dizgeleridir (bstr[32]). Depolanan bir Arweave işlem kimliği, asla bir base64url metin dizgesi olarak değil, bstr[32] olarak taşınan ham 32-baytlık bir SHA-256 özetidir (§3.3 ile eşleşir).
Yaprağın bir kind baytı ile seçilen iki şekli vardır, çünkü varsayılan yükleme yolunda Worker bayta kördür: POST /api/v1/upload yalnızca qub_id ve unlock_at'ı güvenilmeyen istemci iddiaları olarak alır — body_hash, drand_round, created_at ve drand_chain_version'ın tümü, Worker'ın anahtarını asla tutmadığı §13 dış sarmalayıcısı içinde mühürlüdür. Yalnızca sunucu-mühürleme yolu (POST /api/v1/seal), body_hash / drand_round'u düz metinden türetir. Bu nedenle body_hash + drand_round taşıyan tek bir yaprak şekli, gerçek qub'ların çoğunluğu için operatörün asla doğrulamadığı değerleri taahhüt ederdi. Bu bölünme, taahhüt edilen her değeri dürüst tutar:
| Anahtar | Kod. uzunluğu | Tür | Bulunuş | Anlam |
|---|---|---|---|---|
seq |
4 | u64 |
gerekli | Genel 0-tabanlı yaprak indeksi; dahil edilme kanıtının taahhüt ettiği konum. |
kind |
5 | u8 |
gerekli | 0x01 onaylı (sunucu-mühürleme) veya 0x02 iddia edilen (istemci-mühürleme / bayta kör yükleme). |
ref |
4 | bstr[32] |
gerekli | Yaprak referans kimliği. Onaylı → ham qub_id. İddia edilen → körleştirilmiş kimlik SHA3-256(qub_id ‖ log_blind_secret) (§16.2.1). |
chash |
6 | bstr[32] |
gerekli | İçerik adresi SHA3-256(stored_bytes) — Worker'ın her iki yolda da her zaman dürüstçe hesaplayabileceği tek içerik bağı. |
unlock_at |
10 | i64 |
gerekli | Kopyalanmış (onaylı) veya iddia edilen (iddia edilen); yaprağa girmeden önce > 0 doğrulanır. |
received_at |
12 | i64 |
gerekli | R2-onayında Worker duvar saati. Kanıt değeri taşımaz (operatör-iddiası; §16.6). Kendini tanımlama için vardır, asla bir kanıt değildir. > 0 doğrulanır. |
body_hash |
10 | bstr[32] |
yalnızca kind=0x01 |
0x02'de atlanır — Worker §13 altında ona sahip değildir. |
drand_round |
12 | u64 |
yalnızca kind=0x01 |
0x02'de atlanır. |
Bir kind=0x02 yaprağı, kasıtlı olarak ne body_hash ne de drand_round taahhüt eder: qub_id ve unlock_at iddia eden, içerik-adresi chash'teki opak bir şifreli metnin taahhüdünü ve sıralamasını onaylar — düz metnini veya turunu değil. İddia edilen bir qub için düz metin/tur ayakları, günlükten değil, mevcut §11 .qub-paket doğrulamasından gelir (§16.11). drand_chain_version yaprakta değildir (varsayılan yolda sarmalayıcının içindedir); zincir ayrıntısı demirde bulunur (§16.7). Kodlayıcı disiplini: tümü-sıfır bir ref veya chash'i reddedin ve cbor.rs'deki outcome_at > 0 sentinel korumasını yansıtarak, pozitif olmayan unlock_at / received_at'ı reddedin.
16.2.1 Özel-qub körleştirmesi
Günlük, §13 dış sarmalayıcısının önlemek için var olduğu numaralandırma kâhini haline gelmemelidir (§13.1). Özel (sarmalanmış) bir qub için asserted yaprağı, log_blind_secret'in sunucu-tutulan bir gizli olduğu körleştirilmiş tanımlayıcı SHA3-256(qub_id ‖ log_blind_secret)'i taahhüt eder ve body_hash'i atlar. Üçüncü bir taraf böyle bir yaprağı belirli bir qub_id'ye bağlayamaz; teslim URL'sine ve dolayısıyla qub_id'ye sahip olan qub'un sahibi, kendi dahil edilmesini doğrulamak için körleştirmeyi yeniden hesaplayabilir. Kamu bir qub (zaten numaralandırılabilir, §13.8 uyarınca Visibility: public Arweave etiketini zaten taşıyan), ham qub_id'yi taahhüt eder. Bu, bağımsız doğrulanabilirliğin yük taşıyan bir gizlilik değişmezine kasıtlı olarak boyun eğdiği tek yerdir; özel qub'lar için bağımsız bağ chash'tir (§16.9).
log_blind_secret muhafazası (çözüldü — §16.15 Q4). Körleştirme, düz metin gizliliğini değil, yaprak bağlanamazlığını korur (§13 sarmalayıcısı bunu bağımsız olarak tutar). Bir log_blind_secret ele geçirildiğinde, saldırganın zaten elinde tuttuğu veya yeniden inşa edebileceği herhangi bir qub_id için (paketine/URL'sine sahip olduğu her qub, artı düşük-entropili veya kamu herhangi bir qub_id) yaprak ref'ini tek bir özette yeniden hesaplar ve onu bağlar — bu, bilinmeyen bir uzay üzerinde kaba kuvvet değil, bilinen bir popülasyonun doğrudan bağlanmasıdır. log_blind_secret'i diğer sunucu gizlileriyle aynı muhafaza katmanında bir korelasyon/Sybil-derecesi gizli olarak sınıflandırın ve yalnızca ileriye dönük döndürün (bir döndürme, gelecekteki yaprakları yeniden körleştirir; zaten demirlenmiş olanları geriye dönük olarak ayıramaz).
16.3 Yaprak ve düğüm özetlemesi
RFC 6962 §2.1 etki-alanı-ayrılmış özetleme, SHA-256 yerine SHA3-256 ile:
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
Etki-alanı önek baytları 0x02 (girdi zinciri, §16.4) ve 0x03 (STH özeti, §16.6) ayrılmıştır ve bunlardan ayrıktır. Bunlar tek baytlardır ve bu nedenle mevcut 10-baytlık ASCII etki-alanı ayırıcılarıyla (QUB_ID_V2, vb.) çakışamazlar. Ağaç, RFC 6962 sol-dolu dengesiz ağaçtır (her iç bölünme, alt-ağaç yaprak sayısından kesinlikle küçük en büyük ikinin kuvvetinde), bu da dahil edilme ve tutarlılık kanıtlarının tek bir denetim-yolu algoritmasını paylaşmasını sağlar. Referans belirtimi, açık sol/sağ türetme sözde kodunu taşır ve sağ-kenar terfi durumunu — ki bunu 4-yapraklı bir vektör gizler — uygulayan bir ikinin-kuvveti-olmayan (5-yapraklı) test vektörü sabitler.
16.4 Özet zincirleme (dahili)
LogDO, yalnızca çökme tutarlılığı için bir dahili girdi zinciri tutar. Bu asla yayınlanmaz ve asla doğrulayıcıya dönük değildir:
entry_chain[seq] = SHA3-256(0x02 || entry_chain[seq-1] || leaf_hash[seq])
entry_chain[-1] = SHA3-256("QUB_TLOG_GENESIS_V1")
Yayınlanan ekleme-yalnızca otorite, operatörün yaprakları sunmaya denk geldiği ham sıra değil, kümülatif Merkle kökü + demiridir (§16.5–16.6): zincir, sunulan herhangi bir sıra için yeniden hesaplanır, bu nedenle yalnızca demirlenmiş kök kanonik konumu sabitler.
16.5 Kümülatif Merkle ağacı ve toplama
İzole edilmiş toplama-başına ağaçlar değil, tüm yapraklar üzerinde seq sırasıyla sürekli büyüyen tek bir RFC 6962 ağacı vardır. (Taşıma-yaprağı-zincirli bir toplama-başına inşa reddedildi: bu gerçek bir önek ilişkisi değildir, bu yüzden "tutarlılık kanıtları" sağlam değildir.) Kümülatif ağaç, gerçek RFC 9162 tutarlılık kanıtları verir ve tek bir yakın demirin herhangi bir eski qub için dahil edilmeyi kanıtlamasını sağlar.
LogDO Durable Object tek yazıcıdır (blockConcurrencyWhile, QuotaDO / EntitlementDO'yu yansıtır) — paylaşılan bir günlüğe ekleme, paylaşılan durum üzerinde oku-değiştir-yaz'dır ve bu nedenle asla KV değil, bir DO'dan geçmek ZORUNDADIR. Ağacın sağ-kenar sınırını (O(log n) özet) önbelleğe alır, böylece bir toplamayı kapatmak O(batch)'tir. Bir toplama, birlikte demirlenen yaprakların setidir; tetikleyicileri yapılandırılabilirdir, protokole sabitlenmemiştir: en az LOG_BATCH_MAX_LEAVES (varsayılan 4096) kadar bir tree_size ilerlemesi, ya da yaşın demirleme temposuna ulaşması, ya da ücretli bir T3 mühürlemesi indiğinde zorlanan bir boşaltma. root_i, 0 .. tree_size_i yaprakları üzerindeki kümülatif Merkle Ağaç Özetidir.
16.6 Arweave demiri aracılığıyla imzalı ağaç başlığı
Arweave demir işlemi, İmzalı Ağaç Başlığı'dır (Signed Tree Head) ve ağaç başlığının kendisi için bir operatör imzasının yerini alır: günlük demir, qub anahtarına ihtiyaç duymaz çünkü Arweave tx owner imzadır. Moat tezi geçerlidir — demirlenmiş kök için yük taşıyan, bir qub-tutulan gizli değil, değişmez alt yapıdır.
Tasarımda tam olarak bir sıcak qub imzalama anahtarı vardır ve sabitlenmiştir: mühürleme-başına makbuz anahtarı (§16.10). Açık anahtarı LogProfile'da (doğrulayıcı ile dağıtılır) taahhüt edilir ve anchor_owner tarafından çapraz-imzalanır, böylece bir doğrulayıcı bir makbuzu demirle aynı sabitlenmiş köke karşı doğrular. Bu, §16.15 Q2'nin çözümüdür — sabitlenmemiş, operatör-döndürülebilir bir makbuz anahtarı reddedilebilir olurdu (operatör anahtarın kendisine ait olduğunu inkâr edebilirdi), bu da makbuzun var olma amacı olan operatör-seviyesi düşmana karşı hesap verebilirlik değerini geçersiz kılardı. Yani: qub hiçbir sabitlenmemiş günlük-imzalama anahtarı tutmaz; makbuz anahtarı sabitlenmiş ve anchor_owner-çapraz-imzalanmıştır.
SignedTreeHead, kanonik CBOR'dur (anahtarlar kodlanmış uzunluğa göre): size:u64, root:bstr[32], batch:u64, prev:bstr[32] (önceki sth_hash; doğuş = 32 sıfır bayt), log_id:bstr[32], first_seq:u64, anchored_at:i64. Özeti sth_hash = SHA3-256(0x03 || canonical_cbor(SignedTreeHead))'tür.
Sabitlenmiş güven kökü. log_id = SHA3-256("QUB_TLOG_V1" || anchor_owner_address). Uyumlu bir doğrulayıcı, anchor_tx.owner == LogProfile.anchor_owner'ı gerektirmek ZORUNDADIR; burada anchor_owner (ve makbuz-anahtarı açık anahtarı), DrandTimelockProvider::quicknet()'te zaten bulunan quicknet sabitlerinin yanında LogProfile olarak qub_core'a yerleştirilir ve doğrulayıcı ikilisiyle dağıtılır. Doğrulayıcı ayrıca, bir ağ geçidi /raw/ yanıtına güvenmek yerine Arweave tx veri → tx_id bağlamasını yerel olarak doğrulamak ZORUNDADIR. Bu, sahte-cüzdan eşitsizlik (equivocation) açığını kapatır: doğrulayıcı hangi cüzdanı sabitlediğine kadar "Arweave'e demirlenmiş" anlamsızdır.
Döndürme, bir reuse değil, bir §15 yönetişim uzantısıdır (çözüldü — §16.15 Q3). §15.2'nin profil yüzeyi şu anda yalnızca sig_alg'ler / drand zincirleri / sarmalayıcı sürümleri / içerik türlerini sıralar ve §15.3'ün tetikleyicileri bunların hiçbirini listelemez — LogProfile / anchor_owner henüz §15'in yüzeyinde değildir. Bu nedenle döndürme yönetişimi inşa edilmelidir: §15.3 (aşağıda) LogProfile tetikleyicisini ekleyecek şekilde genişletilir ve bir döndürme, bir doğrulayıcı güncellemesinde sevk edilen imzalı bir LogProfile yükseltmesidir. Planlı bir döndürme, giden → gelen çapraz-imza taşır; ele geçirme-kaynaklı bir döndürme bunu yapamaz (giden anahtar tam o anda güvenilmez/erişilemezdir) ve önceki-demir çatallanma kontrolünün (aşağıda) ara dönemde hasarı sınırladığı §15-yönetimli yükseltmeye geri döner.
Eşitsizlik penceresi (birinci-sınıf güven parametresi). Bir yaprak, yalnızca onu kapsayan demiri Arweave-onaylandığında eşitsizliğe dirençlidir. Pencere received_at → demir onayı'dır (≤ tempo + Arweave kesinliği). İçinde tek garantiler, sabitlenmiş mühürleme makbuzu (§16.10) ve qub'un operasyonel bütünlüğüdür. Üç hesap verebilirlik eseri bunu el sallamak yerine dürüst kılar (tanık modeli §16.15 Q2'nin çözümüdür):
- Sabitlenmiş imzalı mühürleme makbuzu — yükleme yanıtında döndürülen SCT analoğu (§16.10), sabitlenmiş,
anchor_owner-çapraz-imzalanmış makbuz anahtarıyla imzalanır. Demirinden önce düşürülen bir yaprak, kurbana yayınlayacağı reddedilemez bir makbuz bırakır ve sessiz-atlama açığını kapatır. - Yayınlanan izleme metodolojisi + önceki-zincir yürüyüşü — demir
prevzinciri baştan→doğuşa yürünür; bir çatallanma (birsize'da farklırootile iki demir, ya da bozuk birprev) yayınlanabilir bir kötü davranış kanıtıdır. Eşitsizlik tespiti, sessiz bir varsayım değil, belirtilmiş bir operasyonel taahhüttür. - Çift kendi-yayınlanan başlık — her yeni başlık
{sth_hash, tree_size}, özel bir qub-sahipli kamu, ekleme-yalnızca GitHub deposuna gönderilir (yük taşıyan kurcalamaya-karşı-kanıt kendi-yayınlama ayağı), yalnızca en iyi-çaba teyidi olarak bir sosyal gönderiyle. Başarısız bir gönderim, sessiz başarısız olmak yerine sayfa açmak (page) ZORUNDADIR.
Dürüstlük sınırı (bağlayıcı kısıt). qub her iki gönderim yüzeyini de kontrol ettiğinden, bu bağımsız tanıklı değil, kendi-yayınlanmıştır. Hiçbir ürün, pazarlama veya yasal yüzey günlüğün "bağımsız tanıklı" olduğunu iddia edemez; izin verilen iddia, eşitsizliğin tespit edilebilir olduğu ve reddedilemez bir makbuz bıraktığıdır. Gerçek bir bağımsız üçüncü-taraf tanığı, gelecekteki bir §15 yönetişim yükseltmesine ertelenir.
received_at operatör-iddiasıdır ve hiçbir iddia ona dayanamaz — herhangi bir ürün / yasal / API / kanıt-sunma yüzeyinde asla kanıt veya anlaşmazlık teyidi olarak yüzeye çıkarılmaz. Arweave demir blok zamanı T, tek güvensiz zaman damgasıdır ("şu zamana kadar günlüğe alındı" üzerinde bir üst sınır). received_at üzerindeki herhangi bir izleme akıl-sağlığı kontrolü, operatör-kontrollü anchored_at STH alanına karşı değil, T'ye karşı karşılaştırmak ZORUNDADIR; böyle bir kontrol, yalnızca dürüst bir operatörün saat hatasına karşı bir korumadır, kötü niyetli bir operatöre karşı bir hesap verebilirlik kontrolü değildir (§16.15 Q5).
16.7 Demir işlemi biçimi ve tempo
AnchorBundle, §16.8 paketleyicisi aracılığıyla yazılan kanonik-CBOR Arweave işlem gövdesidir: ver:u8, sth:bstr (kanonik SignedTreeHead baytları), prev_anchor:bstr (önceki demir tx kimliği ham baytları; doğuşta atlanır), chain_hash:tstr (yürürlükteki drand zinciri — quicknet) ve demir kendi kendine yeterli olacak şekilde toplamanın yaprak-CBOR akışı seq sırasında: bir izleyici, root'u sıfır qub bağımlılığıyla gövdeden yeniden türetir. (Yaprak akışı yüksek hacimde büyürse, gelecekteki bir revizyon yalnızca bir yaprak aralığını referansla taahhüt edebilir; not edildi, v1'de benimsenmedi.)
Arweave etiketleri kasıtlı olarak numaralandırılabilirdir — özel qub'ların aksine, günlüğün bulunması amaçlanmıştır: App-Name: qub-tlog, Anchor-Format: 1, Log-Id: <hex>, Batch: <n>, Tree-Size: <n>, Root: <hex>, Prev-Anchor: <tx>, Content-Type: application/cbor. Etiketler güvenilmeyen ipuçlarıdır; CBOR gövdesi tek otoritedir.
Tempo: varsayılan olarak günlük, hacimle yeniden gözden geçirilir (boyut tetikleyicisi yük altında etkin tempoyu otomatik olarak kısaltır); ücretli bir T3 mühürlemesi bir demiri zorlar, böylece ödeme yapan müşteriler asla bir gün beklemez. Demir cüzdanı özel ve düşük-hızlıdır, yükleme cüzdanından ayrıdır — kendi JWK'si OLMALIDIR (yükleme cüzdanında mantıksal bir rol değil, ayrı bir anahtar), böylece bir yükleme-cüzdanı ele geçirilmesi demirler sahteleyemez — günde sert bir demir-işlem bütçesi ile (indirgenen ARWEAVE_DAILY_CEILING). Muhafaza duruşu açıkça belirtilir: "soğuk" değil, sıkı bir devre kesicisi ve düşük bakiyesi olan dar-kapsamlı bir sıcak anahtar — günlük otomatik imzalayan bir cüzdan soğuk olamaz ve belirtim aksini iddia etmez.
16.8 ANS-104 paketleyici
İçeride üretilmiş bir ANS-104 DataItem kodlayıcı ve derin-özet imzalayıcı, kabaca 300 satır, yalnızca Web Crypto, sıfır npm bağımlılığı (her iki Turbo SDK de npm ci --ignore-scripts tedarik-zinciri kapısında başarısız olur). DataItem bayt düzeni:
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
İmzalama, Arweave deepHash'tir — ["dataitem", "1", sig_type, owner, target, anchor, encoded_tags, data] üzerinde özyinelemeli bir SHA-384 özeti (Arweave'in kablo gereksinimi, crypto.subtle.digest("SHA-384")) — ardından cüzdan JWK'si ile crypto.subtle aracılığıyla derin özet üzerinde RSA-PSS; id = base64url(SHA-256(signature)). Buradaki SHA-384, bir qub güven ilkeli değil, yalnızca-Arweave-kablosu bir ilkel olarak karantinaya alınmıştır (§15 çiti kaydeder; qub güven özetlemesi baştan sona SHA3-256'dır).
Tek bir kod yolu üç tüketiciye hizmet eder: ücretli T3 qub-başına kalıcılık, Arweave-erişilemezlik yedeği (DataItem'ı kuyruğa al, ne olursa olsun R2-öncelikli onayı döndür — bu mevcut ARWEAVE_UNAVAILABLE 503 çıkmazını kapatır) ve AnchorBundle'ı yazma. İmza şeması (çözüldü — §16.15 Q8): v1, RSA-PSS (imza türü 1) ile imzalar, mevcut Arweave cüzdan JWK mekanizmasını yeniden kullanarak (sıfır yeni uzun-ömürlü anahtar muhafazası, "bir gizli daha az" tezine hizmet eder); Ed25519, §15 PK-geçiş yoluna ertelenir.
Elle yazılmış derin özet, W5'teki en yüksek-riskli, en düşük-doğal-kapsamlı koddur, bu nedenle kapılaması pazarlık konusu değildir (§16.15 Q8):
- Diller arası fikstür
tlog_v1.json(Rust + TS, §14.5wrapper_v1.jsondeseni), derin-özeti, DataItem baytlarını + kimliğini, yaprak özetlerini, bir 5-yapraklı kökü + denetim yolunu, bir STH özetini, bir dahil edilme kanıtını ve bir tutarlılık kanıtını — hem imzalama hem de doğrulama yönlerinde kapsar (doğrulama yönü önemlidir çünkü §16.6'nın yerel tx → tx_id kontrolü, derin özeti yalnızca yazıcıya değil, her bağımsız doğrulayıcıya çeker). - Bir referans ANS-104 paketleyicisi aracılığıyla tek seferlik bir birlikte-çalışabilirlik gidiş-dönüşü, yalnızca statik test verisi olarak tüketilir — asla bir npm çalışma-zamanı bağımlılığı değil (yalnızca-Web-Crypto / kurulum-betiği-yok duruşu geçerlidir).
- Derin-özet + RSA-PSS yolu, üretimin kullandığı aynı
crypto.subtleilkelleri üzerinden gidiş-dönüş yapmalıdır, böylece içeride üretilmiş kodlayıcı bayt-uyumludur. - Süregelen bir paket-sonrası kabul izleyicisi, her demir / yedek DataItem'ın gerçekten Arweave kabulüne ulaştığını bir alarm + devre kesici ile doğrular — çünkü derin özet, Arweave-erişilemezlik yedek kuyruğuna da hizmet eder, bu nedenle sessiz bir gerileme, var olduğu kesin kesinti sırasında o kuyruğu ağ-tarafından-reddedilen öğelerle doldurur.
16.9 Dahil edilme ve tutarlılık kanıtları
Her ikisi de RFC 9162, SHA3-256'dır, kanonik CBOR olarak sunulur.
InclusionProof — GET /api/v1/qub/:tx_id/proof: ver:u8, leaf:bstr (tam yaprak CBOR — doğrulayıcı leaf_hash'i kendisi yeniden hesaplar ve asla sağlanan bir özete güvenmez), index:u64, size:u64, audit:[bstr[32]], root:bstr[32], anchor:{ txid:bstr[32], batch:u64, sth:bstr[32], log_id:bstr[32], block_height?:u64, anchored_at?:i64 }.
ConsistencyProof — GET /api/v1/log/consistency?first=<size_a>&second=<size_b>: ver:u8, first_size:u64, second_size:u64, first_root:bstr[32], second_root:bstr[32], nodes:[bstr[32]], first_anchor, second_anchor. Tek bir kesin anahtar listesi, test vektörü ile sabitlenmiş.
Bağımsız doğrulama (qub sunucusu yok, §11'i genişletir):
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).
Kanıt-sunma depolaması koordinat-anahtarlı OLMALIDIR (çözüldü — §16.15 Q7, engelleyici önkoşul). Soğuk-yaprak kanıt üretimi, yalnızca R2 denetim materyali, toplama-başına düğüm deltaları değil, mutlak ağaç koordinatı (level, index) ile anahtarlanmış kalıcı bir Merkle-düğüm deposu ise doğruluk açısından nötrdür. Koordinat-anahtarlı bir depo ile, herhangi bir (leaf i, size N) denetim yolu, toplama sınırları arasında yeniden hesaplama olmaksızın O(log N) doğrudan R2 GET'lik bir settir; toplama-anahtarlı bir depo ile değildir, ki bu, bu çözümün kapattığı depolama-düzeni boşluğudur. Yaprak gövdeleri de aynı şekilde seq ile içerik-adreslenebilirdir. Bir W5 test vektörü, doğuş-dönemi bir soğuk yaprağı, LogDO depolaması silinmiş olarak yalnızca R2 + Arweave kullanarak çok-sonraki bir köke karşı kanıtlamak ZORUNDADIR, böylece §16.13'teki geri-kazanım-güvenliği iddiası iddia edilmek yerine desteklenir. O(log N) ardışık R2 GET'ler, yalnızca asenkron kanıt uç noktasına aittir — asla mühürleme sıcak yoluna (§16.10) veya tik-başına bir crona değil.
16.10 R2-öncelikli onay sıralaması
POST /api/v1/upload dizisi şöyle olur:
- Ön-yarı kapıları (kimlik doğrulama, doğrulama, eşsizlik (idempotency) parça anahtarı) — değişmedi.
- Senkron olarak
await QUB_CACHE.put(qub-cache/<tx_id>, wrappedBytes)— dayanıklılık tabanı; ayrıca W1'in ön-önbellek yarışını kapatır (eskiden Arweave gönderimi sonrası birctx.waitUntil). - Senkron olarak
await LogDO.append(leaf)— bir colo-içi DO RPC'si; tek yazıcıseqatar, girdi zincirini genişletir ve sınırı günceller. (Paylaşılan durum üzerinde RMW → DO, asla KV değil.)appendRPC'si yalnızca bunu yapar —O(batch)Merkle toplama-kapatma işi, bu RPC'nin dışında LogDO alarmında çalışır, yoksaappendp95'i herLOG_BATCH_MAX_LEAVES'inci mühürlemede sıçrar. - Onayı şimdi döndür — mühürleme makbuzu (sabitlenmiş makbuz anahtarıyla imzalı, §16.6) ve
{ tx_id, log_seq, anchor_status: "pending" }ile. Çok-saniyelik Arweave fan-out'u kritik yoldan kaldırılır. - Tek bir
ctx.waitUntil, ertelenen işi kuyruğa alır: qub-başına Arweave gönderimi (artık en iyi-çaba / ücretli; başarısızlıkta kullanıcıyı 503'lemek yerine paketleyici yedek kuyruğuna yönlendirir) artı mevcut geçici-meta yazmaları. Toplama kapatma ve demirleme, LogDO alarmından ve günlük demir cronundan bağımsız çalışır. Bir döngü içindectx.waitUntilyok; mevcut eşsizlik parça anahtarı korunur.
Gecikme bütçesi (çözüldü — §16.15 Q7). < 300 ms p95 hedefi bir varsayım değil, bir ölçülen lansman kapısıdır. Dürüst kritik yol, ön-yarı KV okumaları + bir R2 PUT + iki sıralı Durable Object'tir — mevcut QuotaDO mühürleme-kotası borçlandırması ve yeni LogDO eklemesi — bu nedenle bütçe, bir değil, iki colo-içi DO gidiş-dönüşünü hesaba katmak ZORUNDADIR. QuotaDO'nunkini yansıtan bir LogDO gecikme alarmı sevk edin ve bir p95 gerilemesini bir sürüm engelleyicisi olarak ele alın.
16.11 Güven modeli — yaprak türüne göre kapsamlanan kesin iddia
kind=0x01 (onaylı) için: "Bu içerik — body_hash'le eşleşen gövde, qub_id ile tanımlanan — seq konumunda qub'un ekleme-yalnızca günlüğüne taahhüt edildi ve en geç Arweave blok zamanı T'de var olmuştu; drand turu R = unlock_round(unlock_at)'a kadar kriptografik olarak okunamazdı." Bu, tam {tlock tur bağlama + Merkle dahil edilmesi + demirlenmiş kök} üçlüsüdür.
kind=0x02 (iddia edilen, varsayılan) için: "İçerik-adresi chash olan, qub_id ve unlock_at iddia eden opak bir şifreli metin, seq konumunda ekleme-yalnızca günlüğüne taahhüt edildi ve en geç Arweave blok zamanı T'de var olmuştu." Tur ve gövde ayakları, günlük tarafından değil, mevcut §11 .qub-paket doğrulaması (qub_core::unlock) tarafından sağlanır; günlüğün çıplak bir qub-başına işleme kattığı şey, kurcalamaya karşı kanıt sunan sıralama, güvensiz bir üst-sınır taahhüt zamanı ve eşitsizlik direncidir.
Her iki iddia da §11 uyarınca şunları hariç tutar: sig_alg ≥ 0x01 olmadan yazarlık, niyet ve demir-altı-ayrıntı zamanlama. İkisi de hiçbir iddianın received_at'a dayanmasına izin vermez.
İddia tavanı (bağlayıcı lansman kısıtı — çözüldü §16.15 Q1). Ücretsiz / varsayılan (kind=0x02) qub'lar için, yukarıdaki kapsamlanan kind=0x02 iddiası, herhangi bir ürün, pazarlama, koşul veya kanıt-sunma yüzeyinin öne sürebileceği şeyin tavanıdır. Hiçbir yüzey, günlüğün varsayılan bir qub'un içeriğini veya açılma turunu kanıtladığını belirtemez veya ima edemez — günlük, opak bir şifreli metnin sıralamasını + güvensiz bir üst-sınır taahhüt zamanını kanıtlar. İçerik ve tur kanıtı, yalnızca günlük-bağımsız olan mevcut §11 .qub-paket doğrulamasından gelir. Bu, stilistik bir tercih değil, kopya üzerinde sert bir lansman engelleyicisidir; bayta-kör varsayılan yolu dürüst tutan çözüm budur.
16.12 Sürümleme ve W3 koordinasyonu
Hiçbir SealedQub kablo yükseltmesi yoktur ve bu nedenle hiçbir protokol-sürümü yükseltmesi yoktur (§12.1): günlük, mevcut alanlara ve baytlara taahhüt eden bir yan dosyadır, bu nedenle §12.2 protokol-sürümü geçmişine girmez. W3'ün isteğe bağlı drand_chain_version'ı dokunulmamış kalır ve tek isteğe bağlı SealedQub alanı olarak kalır. Günlük bunun yerine kendi bağımsız sürüm uzaylarını tanıtır — LOG_VERSION_1, ANCHOR_FORMAT_1, InclusionProof.ver — §12.4 sarmalayıcı-sürüm bağımsızlığını yansıtarak (sarmalayıcı, protokol sürümünden bağımsız bir sürüm baytı taşır ve günlük sürümleri aynı ayrımı izler).
Kanıt teslimi varsayılan olarak çekilir, isteğe bağlı bir yanında-binme ile. Mühürleme anında bir kanıt var olamaz (demir henüz yazılmamıştır), bu nedenle mühürleme-anı .qub paketi kanıt-içermez kalır. W7'nin doğrulayıcısı GET …/proof'u bir kez çeker ya da tamamen-çevrimdışı modda kanıtı Log-Id üzerinde bir Arweave sorgusu aracılığıyla kamu AnchorBundle'dan yeniden inşa eder. .qub paketi (W7), W3'ün drand_chain_version'ıyla aynı "isteğe bağlı, varsayılan olarak atlanan, eklemeli" desenini izleyerek bir isteğe bağlı inclusion_proof üyesi ayırır — mühürlemede yok, soğuk arşiv için demir-sonrası bir yeniden-dışa-aktarımla doldurulur.
16.13 Saklama
LogDO açık kuyruğu, R2 kanıt-sunma alt yapısı, demir devre-kesici sayaçları ve paketleyici yedek kuyruğu için saklama pencereleri docs/DATA-RETENTION.md'de belirtilmiştir. İlke: günlüğün sıcak girdi-başına depolaması (LogDO) demir-sonrası geri-kazanılabilirdir; denetim materyali — koordinat-anahtarlı (level, index) Merkle-düğüm deposu + seq-adresli yaprak gövdeleri (§16.9) + Arweave demirleri — kalıcıdır. Bir soğuk yaprağı DO'dan geri kazanmak, asla yayınlanmış bir kanıtı geçersiz kılmaz, çünkü bir kanıt DO'ya karşı değil, o kalıcı R2 düğüm deposuna ve Arweave demirine karşı çözülür (ve §16.9 silinmiş-DO test vektörü bunu kanıtlar).
16.14 Test vektörleri
W5, diller arası fikstür tlog_v1.json'u (§16.8) artı işlenmiş vektörleri sevk eder: bir kind=0x01 ve bir kind=0x02 yaprağı → leaf_hash; 5-yapraklı kümülatif kök; bir dahil edilme kanıtı; bir tutarlılık kanıtı; bir AnchorBundle; ve bir DataItem kimliği. Bunlar, §14.5 dış-sarmalayıcı vektörlerinin yanında bulunur ve hem Rust (qub-core) hem de TypeScript (Worker) uygulamaları tarafından uygulanır.
16.15 İnceleme kararları (W5 — çözüldü)
W5 dış incelemesi (bir hasım tasarım geçişi + sahip onayı) tamamlandı. Aşağıdaki her karar yerleşmiştir ve yukarıdaki §16 metnine yansıtılmıştır; bağlayıcı lansman kısıtları sonda yeniden belirtilir. Uygulama bunlar altında ilerleyebilir.
- Varsayılan-yol (
kind=0x02) yaprak dürüstlüğü — ÇÖZÜLDÜ. İki-yaprak-türü bölünmesini belirtildiği gibi sevk edin:kind=0x02nebody_hashne dedrand_roundtaahhüt eder. Bayta-kör yolda*_body_hashalanı yok (entegratörler için en okunaklı sahte "doğrulanmış" sinyal olurdu ve §11'in paketten zaten sağladığı bir kolaylıktır). Günlük-onaylı qub'lar için sunucu-mühürleme gerektirmeyin (bu, düz metni Worker'dan zorlar ve kripto-parçalama moat'ını yok ederdi). Herhangi bir kendini-tanımlayan kısayol, bir yaprak alanına değil,.qubpaketinde / kanıt zarfında doğrulayıcı-tarafından-yeniden-hesaplanan bir alana aittir. Sahip-onaylı iddia tavanı: §16.11. - Eşitsizlik / atlama hesap verebilirliği — ÇÖZÜLDÜ. Mühürleme-makbuzu anahtarı,
LogProfile'da sabitlenmiş +anchor_owner-çapraz-imzalanmıştır (önceki "imzalama anahtarı yok" çelişkisini kapatır; §16.6). Lansman tanık modeli: sabitlenmiş makbuz + izleme metodolojisi + önceki-zincir yürüyüşü + çift kendi-yayınlanan başlık (qub-sahipli kamu GitHub deposu, sosyal en iyi-çaba), tespit edilebilir + makbuzlu olarak pazarlanır, asla bağımsız tanıklı değil. Gerçek bir üçüncü-taraf tanığı bir §15 yönetişim yükseltmesine ertelenir. - Sabitlenmiş demir-sahibi güven kökü + döndürme — ÇÖZÜLDÜ.
LogProfilesabitlemesini benimseyin (§16.6); doğrulayıcıanchor_tx.owner == anchor_owner'ı kontrol eder ve tx veri → tx_id bağlamasını yerel olarak doğrular. Döndürme yönetişimi bir reuse değil, bir §15 inşa edilecek uzantıdır (§15.3 tetikleyici eklendi); planlı döndürmeler çapraz-imzalar, ele geçirme-kaynaklı döndürmeler çatallanma kontrolünün hasarı sınırladığı §15 yükseltmesine geri döner. - Özel-qub yaprak körleştirmesi — ÇÖZÜLDÜ. Özel qub'lar için körleştirmeyi koruyun (
ref = SHA3-256(qub_id ‖ log_blind_secret)), kamu qub'lar için hamqub_id(zaten §16.2.1), bağımsız bağ olarakchash.log_blind_secretbir korelasyon/Sybil-derecesi gizlidir, yalnızca-ileriye-döndürülür (§16.2.1). received_at— ÇÖZÜLDÜ. Onu yaprakta tutun, taahhüt edilmiş ama açıkça kanıt değeri taşımayan; herhangi bir yüzeyde asla kanıt veya anlaşmazlık teyidi olarak yüzeye çıkarılmaz. Herhangi bir izleme akıl-sağlığı kontrolü, operatör-kontrollüanchored_at'a karşı değil, Arweave blok zamanıT'ye karşı karşılaştırır (§16.6).- Ücretsiz-katman kanıtlanabilir-zamanlama — ÇÖZÜLDÜ (sahip onayı). Dayanıklılık gerilemez; yalnızca kanıtlanabilir üst-sınır taahhüt zamanı demir blok zamanına kabalaşır. Ücretsiz-katman kopyası hiçbir sayısal SLA kullanmaz ("…bir sonraki günlük demirinde, tipik olarak günlük eklenir"); tam-saat kanıtı ücretli bir T3 özelliğidir, katman-karşılaştırma yüzeyinde + koşullarda açıklanır (§16.1).
- Workers üzerinde kümülatif ağaç — ÇÖZÜLDÜ. Tek kümülatif RFC 9162 ağaç + sınır-önbellekli tek-yazıcı LogDO (~1k yazma/saniye DO tavanına karşı rahat üst boşluk; Merkle-of-shard-roots parçalamasını ona yaklaşana kadar ertele). Engelleyici önkoşul: koordinat-anahtarlı
(level, index)R2 düğüm deposu + silinmiş-DO soğuk-yaprak test vektörü (§16.9);< 300 ms, iki sıralı DO üzerinde bir ölçülen lansman kapısıdır (§16.10). - ANS-104 imza şeması + derin-özet — ÇÖZÜLDÜ. RSA-PSS (imza türü 1, özel demir-cüzdan JWK'sini yeniden kullanır); Ed25519, §15 PK yoluna ertelenir. Elle yazılmış SHA-384 derin özeti, her-iki-yön diller-arası fikstüre, yalnızca-statik bir referans-paketleyici birlikte-çalışabilirlik kontrolüne, paylaşılan-
crypto.subtlegidiş-dönüşüne ve paket-sonrası Arweave-kabul izleyicisine kapılıdır (§16.8).
Bağlayıcı lansman kısıtları (uygulamaya + ürün/yasal incelemeye taşıyın):
- İddia tavanı (Q1/Q6). Hiçbir yüzey günlüğün varsayılan bir qub'un içeriğini veya açılma turunu kanıtladığını söyleyemez; izin verilen iddia, güvensiz bir üst-sınır taahhüt zamanıyla, kurcalamaya-karşı-kanıt sunarak sıralanmış olduğudur. Ücretsiz-katman zaman damgası kopyası hiçbir sayısal gecikme taşımaz; tam-saat kanıtı yalnızca ücretli T3'tür.
- Tanık dürüstlüğü (Q2). Eşitsizliği tespit edilebilir + makbuzlu olarak pazarlayın, asla bağımsız tanıklı değil.
- Makbuz + demir anahtarları (Q2/Q8). Makbuz anahtarı sabitlenmiş + çapraz-imzalanmıştır; demir cüzdanı, yükleme cüzdanından ayrı kendi JWK'sidir.
- Derin-özet kapısı (Q8). Her-iki-yön fikstürü + birlikte-çalışabilirlik kontrolü geçene kadar hiçbir demir veya T3 tx'i sevk edilmez; kabul izleyicisi başarısızlıkta sayfa açar.
- Depolama önkoşulu (Q7). Koordinat-anahtarlı düğüm deposu + silinmiş-DO soğuk-yaprak vektörü, "geri-kazanım asla bir kanıtı geçersiz kılmaz" garantisinin önkoşullarıdır.