Anleitungen

Anleitungen · Teil 4 von 6

Einen versiegelten PoE erstellen

Ein einfacher PoE belegt, dass ein bestimmter Inhalt existiert hat. Ein versiegelter PoE belegt dasselbe, hält den Inhalt selbst aber geheim: Sie verschlüsseln die Bytes für einen oder mehrere Empfängerschlüssel, speichern nur den Chiffretext und verankern den Datensatz on-chain (in der Blockchain). Jede und jeder kann sehen, dass der Datensatz existiert, und seine Struktur verifizieren; entschlüsseln können die Nutzdaten aber nur diejenigen, die einen passenden privaten Schlüssel besitzen. Das Umschlagformat beschreibt Versiegelter PoE, das Bedrohungsmodell Versiegelt bis zur Abholung.

Empfänger adressieren

Ein Empfänger wird über eine Zeichenkette im age-Stil identifiziert. Es gibt zwei Arten, die sich am Präfix unterscheiden lassen:

  • age1…: ein klassischer X25519-Schlüssel (32 Byte).
  • age1pqc…: ein hybrider X-Wing-Schlüssel (ML-KEM-768 + X25519, 1216 Byte).

X-Wing (mlkem768x25519) ist der Standard-KEM. Er bleibt auch gegenüber einem künftigen Quantenangreifer sicher, und jede Identität verfügt stets über eine age1pqc…-Adresse.

Ein Empfänger teilt Ihnen seine Zeichenkette über einen separaten, vertrauenswürdigen Kanal mit. Mit parseAgeRecipient wandeln Sie sie zurück in den rohen öffentlichen Schlüssel, den die Versiegelungs-Hilfsfunktion benötigt:

import { parseAgeRecipient } from '@cardanowall/sdk-ts';

const them = parseAgeRecipient('age1pqc…'); // { kem: 'mlkem768x25519', publicKey: Uint8Array }

Wenn Sie selbst einen 32-Byte-Seed besitzen, liefert Ihnen recipientsFromSeed beide eigenen Adressen. Geben Sie eine davon weiter, damit andere an Sie versiegeln können, und nehmen Sie Ihren eigenen Schlüssel in die Empfängerliste auf, um den Lesezugriff auf das von Ihnen Versendete zu behalten:

import { recipientsFromSeed } from '@cardanowall/sdk-ts';

const me = recipientsFromSeed(mySeed); // { age: 'age1…', age1pqc: 'age1pqc…' }

Versiegeln und veröffentlichen

Das Versiegeln läuft über ein Gateway, das die Cardano-Transaktion erstellt und verteilt und den Chiffretext für Sie speichert. Richten Sie den Client auf das von Ihnen genutzte Gateway; das SDK ist gateway-unabhängig.

publishSealed erwartet rohe öffentliche Empfängerschlüssel, entnehmen Sie also publicKey aus jeder geparsten Adresse. Alle Empfänger müssen denselben KEM verwenden, halten Sie age1pqc…-Schlüssel daher beieinander. Schreiben Sie zuerst mit quote einen Preis fest, dann veröffentlichen Sie:

import { Label309Client, parseAgeRecipient } from '@cardanowall/sdk-ts';

const client = new Label309Client({
  baseUrl: 'https://your-gateway.example',
  apiKey: process.env.CW_API_KEY,
});

const content = new TextEncoder().encode('the secret payload');
const recipients = ['age1pqc…recipient', me.age1pqc].map((r) => parseAgeRecipient(r).publicKey);

const quote = await client.poe.quote({
  recordBytes: 512,
  recipientCount: recipients.length,
  fileBytesTotal: content.length,
});

const result = await client.poe.publishSealed({
  content,
  recipients,
  quoteId: quote.quote_id,
  // kem defaults to 'mlkem768x25519' (X-Wing); pass 'x25519' only for age1… keys.
});

console.log(result.tx_hash);

Die Hilfsfunktion verschlüsselt den Inhalt, lädt den Chiffretext hoch, bindet dessen ar://-URI und den Klartext-Hash in einen Label-309-Datensatz ein und reicht ihn ein. Ihr Seed und der Klartext verlassen Ihren Rechner dabei niemals im Klartext.

Mit Python

cardanowall-sdk ist ein byteidentischer Zwilling: derselbe KEM-Standard, derselbe Umschlag.

import asyncio
import os
from cardanowall import Label309Client, parse_age_recipient

async def main():
    content = b"the secret payload"
    recipients = [parse_age_recipient("age1pqc…recipient").public_key]

    async with Label309Client(
        base_url="https://your-gateway.example",
        api_key=os.environ["CW_API_KEY"],
    ) as client:
        quote = await client.poe.quote(
            record_bytes=512, recipient_count=len(recipients), file_bytes_total=len(content)
        )
        result = await client.poe.publish_sealed(
            content=content, recipients=recipients, quote_id=quote["quote_id"]
        )
        print(result["tx_hash"])

asyncio.run(main())

Mit Rust

Das cardanowall-Crate versiegelt über denselben Gateway-Client. parse_age_recipient dekodiert jede Adresse in den rohen Schlüssel, und kem: None behält den X-Wing-Standard bei:

use cardanowall::client::{
    Label309Client, Label309ClientConfig, PublishSealedInput, QuoteInput,
};
use cardanowall::recipient::parse_age_recipient;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Label309Client::new(Label309ClientConfig {
        base_url: Some("https://your-gateway.example".into()),
        api_key: std::env::var("CW_API_KEY").ok(),
    })?;

    let content = b"the secret payload".to_vec();
    let recipients = vec![parse_age_recipient("age1pqc…recipient")?.public_key];

    let quote = client.poe().quote(&QuoteInput {
        record_bytes: 512,
        recipient_count: recipients.len() as u64,
        file_bytes_total: content.len() as u64,
    })?;

    let result = client.poe().publish_sealed(&PublishSealedInput {
        content,
        recipients,
        quote_id: quote.quote_id,
        hash_alg: None,
        kem: None, // defaults to mlkem768x25519 (X-Wing); set Some for x25519
        signer: None,
        idempotency_key: None,
    })?;

    println!("{:?}", result.tx_hash);
    Ok(())
}

Das CLI veröffentlicht reine Hash-Datensätze und Merkle-Datensätze; das Versiegeln ist derzeit ein reiner SDK-Ablauf.

Sobald der Datensatz endgültig in die Blockchain aufgenommen ist, findet ihn jeder Empfänger, entschlüsselt die Nutzdaten mit seinem privaten Schlüssel und berechnet den Klartext-Hash neu, um den Kreis zu schließen. Das ist die Empfänger-Seite von Einen Datensatz verifizieren.

Versiegeln Sie auch an sich selbst

publishSealed fügt Sie nicht stillschweigend zur Empfängerliste hinzu. Nehmen Sie keinen Ihrer eigenen Schlüssel auf, veröffentlichen Sie einen Datensatz, den Sie nie wieder lesen können. Nehmen Sie me.age1pqc (oder me.age) unter die Empfänger auf, wann immer Sie den Zugriff auf das von Ihnen Versendete behalten möchten.