密码学
在 Velum 上传输的一切都采用混合方案做端到端加密:经典算法(X25519)加后量子算法(ML-KEM-768)。即使其中之一被攻破,另一个仍能保护消息。
身份、钱包与设备
一切都源自一组 24 个单词的助记词(BIP-39,256 位)。单词表跟随设备语言;俄语没有官方单词表,因此使用英文表。
种子 = BIP39.mnemonicToSeed(助记词) 64 字节
身份 = HKDF-SHA512(种子, info = "velum/v2/identity") ed25519
钱包 = HKDF-SHA512(种子, info = "m/44'/7420'/0'/0'/0'") ed25519
信箱 = HKDF-SHA512(种子, info = "velum/v2/mailbox") 32 B
- 身份用于签署你的资料和设备列表。只有你的联系人知道它(通过二维码或链接),它从不以明文进入网络。
- 钱包用于签署交易。它是另一把密钥,这样谁也无法把聊天和转账关联起来。
- 每台设备都有自己的随机密钥,永不离开设备:ed25519(签名)、X25519 和 ML-KEM-768(加密)。
地址是 vel 加上 ed25519 公钥(32 字节)的 base58 编码。参见钱包与交易所。
设备列表
每个账号都会在 profile 类型的加密消息中,向联系人发布一份由身份签名的列表:
DeviceList = { identity, devices: [{ id, sign, x25519, kem, mailboxSeed, added, name }], ts, sig }
该列表从不发布到链上,最多包含 5 台设备。移除一台设备时,会签发一份不含它的新列表,并轮换信箱秘密。
混合信封
针对每台收件设备:
eph = X25519 临时密钥
(kemCt, kemSs) = ML-KEM-768.encapsulate(设备.kem)
密钥 = HKDF-SHA512(ikm = X25519(eph, 设备.x25519) ‖ kemSs,
salt = eph.pub ‖ kemCt,
info = "velum/v2/envelope", 32 字节)
密文 = XChaCha20-Poly1305(密钥, 24 B nonce)
格式:[版本 2][32 eph][1088 kemCt][24 nonce][密文]。这与 Signal PQXDH 和 Apple PQ3 的思路相同:攻击者必须同时攻破 X25519 和 ML-KEM-768。
密封发件人
从外面看,信封不会透露发件人。信封里面包含:
- 由发件人设备密钥签名的内容(
Payload)。 - 发件人的身份。
- 一份证书:该身份对该设备的签名。
这样收件人能确认消息来自那个人,而其他任何人都无从得知。
群聊
群消息的内容只用一把随机密钥加密一次,再把这把密钥用混合方案为每位成员的每台设备分别密封。每一份看起来都像一对一消息:节点和观察者都无法判断这是群聊,也不知道有多少成员。
填充
在拆分之前,信封会被填充到下一个固定档位:2 KB、8 KB、32 KB、128 KB、512 KB、2 MB 或 8 MB。一句「你好」和一段简短的语音可以一样大。真实大小加密后存放在信封内部。
通过轮换实现前向保密
每台设备每 24 小时轮换一次 X25519 + ML-KEM 密钥对,并在资料中公布新的公钥。旧密钥保留 7 天,用于解开迟到的消息,然后删除。即使今天有人窃取了某台设备的密钥,也打不开一周之前的消息。
完整的三重棘轮(逐条消息的前向保密)已列入路线图。
认证保护什么,不保护什么
应用会向 Apple 申请一份证明(App Attest),证明它是运行在真实 iPhone 上、未经修改的官方应用。这份证明保护的是网络,用来防止垃圾流量和奖励被盗。它并不是保护你消息的手段:即使有人修改了应用,也读不了别人的消息。这一点由密码学保证。
算法
| 用途 | 算法 |
|---|---|
| 签名(身份、钱包、设备、节点) | ed25519 |
| 经典密钥协商 | X25519 |
| 后量子密钥封装 | ML-KEM-768(FIPS 203) |
| 密钥派生 | HKDF-SHA512 |
| 认证加密 | XChaCha20-Poly1305 |
| 回执 | HMAC-SHA512 与 SHA-512 |
| 助记词 | BIP-39,24 个单词 |
| 交易标识 | 规范 JSON 的 SHA-256 |