# AetherProof
**开源回执引擎。Signet 的原型。**
生成加密回执,证明 AI 输出是真实且未经修改的 —— 无需服务器,无需依赖项,可永久离线验证。
```
pip install aetherproof
```
不带任何参数运行 `aetherproof` 即可进入交互式菜单:
```
.+######+. AETHERPROOF
## ## v0.2.2
# /\ # Cryptographic receipt engine
# / \ # Prototype of Signet · R0/L2
# / /\ \ #
# / / \ \ # github.com/pulkit6732/aetherproof
# /______\ \ # Verify(receipt, pk, log) = TRUE
# \______/ #
## ##
'######'
────────────────────────────────────────────────
Sign · Verify · Inspect · Log · Keygen
```
## 它的功能
每次 AI 模型生成输出时,AetherProof 都会颁发一份防篡改的签名回执:
```
Receipt ID : ap_8694dae2
Model Root : abcdef0123456789... (SHA-256 Merkle of model weights)
Model Root Type : artifact_hash (bound to the weights) | name_only (claim only)
Output Hash : fedcba9876543210... (SHA-256 of the output)
Timestamp : 2026-06-11T15:30:00Z
Signature : ✓ Ed25519 VALID
```
`Model Root Type` 字段如实说明了根证明的内容:
`artifact_hash`(你签名了一个真实的 weights 文件)、`api_attested`(云 API
返回了模型 ID),或者 `name_only`(你输入了一个名称)。回执绝不会
把名称伪装成 weights —— 请参阅下方的[本地与云端对比](#local-models-vs-cloud-models)。
**改变一个 bit → 签名瞬间失效。**
## 快速开始
### 简易模式(适合所有人)
```
aetherproof
```
分步向导:
1. 你使用了什么模型?
2. 粘贴输出内容
3. 回执被签名并保存
### 专家模式(适合开发者)
```
# 生成 receipt
aetherproof sign model.onnx output.txt
# 验证它(离线,永久)
aetherproof verify receipt.json
# 检查所有字段
aetherproof inspect receipt.json
# 测试篡改检测
aetherproof tamper receipt.json
```
## 本地模型与云端模型
这是 AetherProof 中最重要的区别。**能够证明什么取决于你是否能看到 weights。**
| | 本地/自托管 (Llama, custom, on-prem) | 云 API (GPT-4o, Claude, Grok, DeepSeek, Gemini…) |
|---|---|---|
| 谁持有 weights | **你** | 提供商 |
| 你能对 weights 进行哈希处理吗? | **可以** | **绝对不能** |
| `model_root_type` | `artifact_hash` | `api_attested` |
| 证明运行了确切的模型? | **是的** | **否**(只有提供商能对此证明) |
| 证明输入 + 输出未被篡改? | 是的 | **是的** |
| 证明 *API 声称的模型* + 时间? | 是的 | **是的** |
### 为什么云端回执无法证明 weights —— 以及为什么这是诚实的
`model_weight_root` 需要读取 weights。对于 GPT-4o 或 Grok,**weights 存在于提供商的服务器上 —— 你永远看不到它们,因此你无法对它们进行哈希处理。** 任何客户端工具都做不到。任何声称可以“在加密意义上证明云模型运行过”的人都在夸大其词,而且精明的审计员会拒绝接受。
云端回执 *确实* 能证明的,是 **你负有责任** 的部分:你的系统发送的确切输入、它所依据的确切输出、API *声称* 的模型、时间,以及所有这些都没有被篡改或倒签日期。这是你的记录保存义务(SEC 17a-4, FRE 902(14))。提供商拥有其基础设施证明;AetherProof 负责保障你记录的准确性。
### 模型名称是如何捕获的(你不需要手动输入)
对于 `api_attested`,模型身份来自于 **API 响应**,而不是猜测。所有主流 API 都会返回解析后的 ID:
```
# OpenAI / DeepSeek / xAI (Grok) — OpenAI-compatible
resp = client.chat.completions.create(model="gpt-4o", messages=[...])
resp.model # "gpt-4o-2024-08-06" ← the RESOLVED id (dated snapshot)
resp.system_fingerprint # "fp_a7d06e42bc" ← backend config snapshot
resp.id, resp.created # call id + provider timestamp
# Anthropic (Claude)
resp = client.messages.create(model="claude-opus-4-8", ...)
resp.model # "claude-opus-4-8"
```
你请求的是 `"gpt-4o"`;API 回答 `"gpt-4o-2024-08-06"` —— 为你提供服务的确切快照。你绑定了那个返回的字符串 + `system_fingerprint`,因此用户无法伪造(它是在你正在进行哈希处理的响应内部返回的)。
### 为云端调用签名
```
from aetherproof.core.receipt import Receipt
from aetherproof.core.keystore import load_or_create_signer
from aetherproof.core.log import ReceiptLog
resp = client.chat.completions.create(model="gpt-4o", messages=[...])
r = Receipt.for_api_call(
provider="openai",
model_id=resp.model, # read FROM the response
prompt=user_prompt,
output_text=resp.choices[0].message.content,
response_metadata={
"system_fingerprint": resp.system_fingerprint,
"response_id": resp.id,
"created": resp.created,
},
)
# r.model_root_type == "api_attested"
signer = load_or_create_signer()
r.signature = signer.sign(r.signing_bytes())
ReceiptLog().append(r)
```
这适用于 **任何** OpenAI 兼容或 Anthropic 风格的提供商 —— OpenAI、
Azure OpenAI、DeepSeek、xAI/Grok、Mistral、Together、Groq 等(已跨越 17 个
模型族在 `tests/security/test_cloud_models_matrix.py` 中测试)。
### “但如果他们没有提供商证明怎么办?他们会被拒绝吗?”
不会 —— 诚实的答案 *能通过* 安全审查。当被问及“证明 Grok 的 weights 运行了”时,答案是:
在真正的争议中(错误的拒绝、糟糕的摘要),争论焦点几乎从来不是
“是 GPT-4o 还是 GPT-4-turbo” —— 而是 **“AI 真的输出了这个内容,还是记录事后被编辑了?”** AetherProof 能完整回答这个问题,适用于任何云
模型,且完全不需要提供商的配合。只有当提供商对其基础设施进行签名时(AWS Bedrock +
Nitro,未来),模型身份的缺口才会升级为真正的硬件根 —— 届时 **Signet** 将导入该签名,层级将提升为 `api_attested → hardware-rooted`,且回执格式无需任何更改。
## 不变量(使之成为现实的原理)
```
Verify(receipt, public_key, log) = TRUE
using ONLY those three inputs, forever, with zero dependency on
AetherProof servers, any vendor SDK, or any hardware driver.
```
这不是一句口号。它是内置的。离线验证仅使用:
1. 回执文件
2. 公钥(PEM 文件)
3.(可选)透明度日志条目
没有网络。没有 API 调用。没有特殊硬件。在 2026、2035、2050 年都能正常工作。
## 离线验证实际是如何工作的
你可以在 **没有互联网且完全不依赖 AetherProof 代码的情况下** 证明回执是真实的 —— 数学原理是公开的。这里是具体的过程。
### 你需要什么(三个输入项)
1. **回执**(`ap_xxxx.json`)—— 签名后的声明。
2. **公钥**(`ap_xxxx.pub`,一个 PEM 文件)—— 与回执一同分发。
3. **(可选)原始输出文件** —— 仅当你还需要证明
输出本身未被更改时才需要。
### 步骤
1. **重构签名消息。** 回执是对其字段(version, model root, model-root-type,
input commitment, output hash, timestamp, log sequence, hardware evidence, log
anchor)的规范长度前缀 preimage 进行签名的。该编码是单射的,因此没有两个不同的回执能共享同一个 preimage(进而共享同一个签名)。
2. **检查**该 preimage 相对于公钥的 **Ed25519 签名**。如果验证通过,则回执的内容正是被签名的内容 —— 哪怕只有一个 bit 的改变也会导致此检查失败。
3. **(可选)使用 SHA-256 重新计算输出文件的哈希值**(原始字节,流式处理),并与回执的 `output_hash` 进行比较。如果它们匹配,则说明输出未被更改。
### 单命令方式
```
# 仅 signature
aetherproof verify ap_xxxx.json
# signature + 确认输出文件仍然匹配
aetherproof verify ap_xxxx.json --output original_output.txt
# 脚本 / CI:machine-readable,任何失败时以 non-zero 退出
aetherproof verify ap_xxxx.json --output original_output.txt --quiet
# -> {"valid": true, "signature_valid": true, "output_unmodified": true}
```
只有在一切检查无误时退出代码才为 `0`,任何篡改都会返回 `1` —— 因此 `aetherproof verify … && deploy` 在 pipeline 中使用是安全的。
### 不使用 AetherProof 进行验证(使用任何 Ed25519 库)
由于格式是开放的,任何人都可以使用标准的加密库进行验证 ——
不依赖此工具。在 Python 中使用 `cryptography` 库:
```
import json, hashlib
from cryptography.hazmat.primitives.serialization import load_pem_public_key
r = json.load(open("ap_xxxx.json"))
pub = load_pem_public_key(open("ap_xxxx.pub", "rb").read())
# 为每个字段按顺序重建 injective preimage:"
:"
fields = [
r["receipt_version"], r["model_weight_root"], r["model_root_type"],
r["input_commitment"], r["output_hash"], str(r["timestamp_ms"]),
str(r["log_sequence"]),
json.dumps(r["hw_evidence"], sort_keys=True, separators=(",", ":")),
r["log_anchor"],
]
preimage = "".join(f"{len(f)}:{f}" for f in fields).encode("utf-8")
pub.verify(bytes.fromhex(r["signature"]), preimage) # raises if invalid
print("signature OK")
# 可选:证明输出文件未被更改
digest = hashlib.sha256(open("original_output.txt", "rb").read()).hexdigest()
print("output unmodified:", digest == r["output_hash"])
```
这就是整个信任模型:**一个公钥以及一些你可以在任何地方、永久运行的 SHA-256 + Ed25519 数学运算。**
## Agent 链上下文(回执 v1.2)
回执可以选择性地提交至 **命名空间 runtime 上下文** —— 即输出属于哪个 agent
操作、运行或策略决策 —— 并置于签名 *内部*。
这会将回执绑定到其颁发时所针对的确切决策中,因此有效的回执
无法在不同的上下文中被重放。
```
from aetherproof.core.receipt import Receipt
r = Receipt(
model_weight_root="...",
output_hash="...",
signed_extensions={
"org.liminal.agent_chain/v0.1": {
"purpose": "generate",
"actor_id": "agent:planner",
"run_id": "run_42",
"policy_decision_id": "pol_7",
}
},
)
# r.receipt_version 现在为 "1.2";基于 canonicalized
# extensions 的 SHA-256 commitment 被折叠进 signing preimage 中 —— 篡改任何字段都会破坏它。
```
- **空的 extensions → 回执保持为 v1.1,字节完全相同。** 对
现有的回执或验证器没有影响。
- **非空 → v1.2。** 每个扩展的 SHA-256 承诺(RFC 8785 JCS
规范化)被聚合并附加到单射 preimage 中,因此可以
披露或省略一个命名空间,而不会破坏其他命名空间。
这是 AetherProof 方面对应的 [agent 链上下文规范](https://github.com/pulkit6732/aetherproof/issues/1)。
多跳 pipeline 聚合(对每一跳进行签名,识别被篡改的跳)属于
**Signet Layer 3**,并基于此原语构建。
## 架构(god file)
AetherProof 是 **Signet** 技术栈的 **Layer 2**。Signet 在此基础上增加了硬件根、合规包和透明度网络。
## 许可证
Apache 2.0。使用它,部署它,fork 它,将其嵌入到商业产品中 ——
没有任何限制。完整条款请参见 LICENSE。
**AetherProof 是当你需要防篡改证明时的选择。**
**Signet 是当你需要硬件根、合规包和透明度日志时的选择。**