examples/sign_llm_output.py
| 1 | """Sign a piece of AI-generated text and verify it round-trips. |
| 2 | |
| 3 | Run: python examples/sign_llm_output.py |
| 4 | """ |
| 5 | |
| 6 | from __future__ import annotations |
| 7 | |
| 8 | from quantumshield import AgentIdentity |
| 9 | |
| 10 | from pqc_content_provenance import ( |
| 11 | AIGeneratedAssertion, |
| 12 | ContentManifest, |
| 13 | GenerationContext, |
| 14 | ManifestSigner, |
| 15 | ModelAttribution, |
| 16 | UsageAssertion, |
| 17 | embed_manifest, |
| 18 | extract_manifest, |
| 19 | ) |
| 20 | |
| 21 | |
| 22 | def main() -> None: |
| 23 | identity = AgentIdentity.create("llama-3-signer") |
| 24 | signer = ManifestSigner(identity) |
| 25 | |
| 26 | # The AI output we want to prove provenance for |
| 27 | content = b"Post-quantum cryptography will be mandatory by 2027." |
| 28 | |
| 29 | manifest = ContentManifest.create( |
| 30 | content=content, |
| 31 | content_type="text/plain", |
| 32 | model_attribution=ModelAttribution( |
| 33 | model_did="did:pqaid:llama3-reference", |
| 34 | model_name="Llama-3-8B-Instruct", |
| 35 | model_version="1.0", |
| 36 | registry_url="https://quantamrkt.com/models/meta-llama-Llama-3-8B-Instruct", |
| 37 | ), |
| 38 | generation_context=GenerationContext( |
| 39 | prompt_hash="ab" * 32, |
| 40 | parameters={"temperature": 0.7}, |
| 41 | generated_at="2026-04-20T12:00:00Z", |
| 42 | ), |
| 43 | assertions=[ |
| 44 | AIGeneratedAssertion( |
| 45 | model_name="Llama-3-8B-Instruct", |
| 46 | model_version="1.0", |
| 47 | generator_type="text", |
| 48 | human_edited=False, |
| 49 | ), |
| 50 | UsageAssertion( |
| 51 | license="cc-by-4.0", |
| 52 | commercial_use=True, |
| 53 | attribution_required=True, |
| 54 | attribution_text="Generated by Llama-3-8B, verified via QuantaMrkt.", |
| 55 | ), |
| 56 | ], |
| 57 | ) |
| 58 | |
| 59 | signed = signer.sign(manifest) |
| 60 | print(f"Signed manifest: {signed.manifest_id}") |
| 61 | print(f" signer: {signed.signer_did}") |
| 62 | print(f" algorithm: {signed.algorithm}") |
| 63 | print(f" content hash: {signed.content_hash}") |
| 64 | |
| 65 | # Package content + manifest into a sidecar envelope |
| 66 | envelope = embed_manifest(content, signed, mode="sidecar") |
| 67 | print(f"\nEnvelope size: {len(envelope)} bytes") |
| 68 | |
| 69 | # Consumer extracts and verifies |
| 70 | recovered_manifest, recovered_content = extract_manifest(envelope, mode="sidecar") |
| 71 | result = ManifestSigner.verify(recovered_manifest, recovered_content) |
| 72 | print(f"\nVerification: valid={result.valid}, content_match={result.content_hash_match}") |
| 73 | |
| 74 | |
| 75 | if __name__ == "__main__": |
| 76 | main() |
| 77 | |