文件与格式
应用与命令行读写的各类文件。带版本号的格式,版本号写在文件里。
条目
条目是一个规范 JSON 对象,恰有七个成员:
| 成员 | 内容 |
|---|---|
spec | 规格名,zikaron/1 |
entryType | 类型:genesis、history、grant、revocation、adoption、succession、annotation,或任何约定的新类型 |
author | 作者地址,小写十六进制 |
seq | 序号,从 0 起 |
prev | 前一条的编号;第一条为 null |
body | 正文,按类型而定 |
sig | 65 字节的 EIP-191 签名 |
条目编号是它全部字节的 SHA-256。规范格式:紧凑书写,成员按字节序排列,整数按十进制书写,十六进制一律小写。详见法 §3 与 §4。
命令行的账本目录
一个明文文件夹,每条条目一个文件,文件名为条目编号的 64 位十六进制加 .entry。zikaron 读写的就是这种目录。
机器目录
每台机器一个。默认位置是 ~/.zikaron-desk.d/;指针文件 ~/.zikaron-desk 可以把它指到别处:一行绝对路径,以一个换行结尾,权限 0600。早先版本放在 ~/Library/Application Support/ZIKARON 的,应用会沿用并迁移一次。
| 文件 | 内容 |
|---|---|
keys-anchor.json | 密钥库,格式 zikaron-desk/keybox/3,权限 0600;错误次数也记在这里 |
identities-anchor.json | 身份登记,加密 |
machine.json | 机器设置,格式 zikaron-desk/machine/1,明文,开锁前要读 |
kits/index.json | 记录包索引,明文,见下文 |
records/index.json | 签入时的文件名与位置,加密 |
set-aside/ | 主钥已失、永久封存的文件,字节原样,按 1、2、3 编号平铺;目录已有时为 set-aside-2、-3 |
机器目录从 HOME 算起,应用只用自己的密钥库,系统钥匙串保持原样。
数据目录
每个身份的每种角色一个,默认放在机器目录下,角色子目录为 author(记录者)或 grantee(使用方)。里面四个子目录:
ledger/- 账本,每条条目一个加密文件。
kits/- 导出的记录包、授权文件、凭证、快照,以及签发时留存的条款文件(
kits/terms/)。 grants-held/- 收到的授权,每份附上次复核的结论;收下的授权文件在
grants-held/files/。 settings/- 设置
desk.json、待上链队列queue.json、上次账本检查last-audit.json,以及只让一个窗口写入的锁writer.lock。
数据目录的文件夹名和账本里的文件名,都由一把本机名钥转写,地址与条目编号由此从文件名上隐去;内容逐文件加密。要给别的工具读,导出账本镜像。
本机数据的加密
本机数据钥由主钥经 HKDF-SHA256 派生(信息串 zikaron/local/v1),文件名钥另用信息串 zikaron/names/v1。每个文件以 XChaCha20-Poly1305 单独加密:
"zikaron-local/1\n" · 种类长度(1 字节) · 种类 · 版本(u16 大端) · 随机数(24 字节) · 密文与标签随机数之前的部分都作为附加数据,所以一个文件绑定在它的种类与格式版本上。写入时先写临时文件,再改名到位。
密钥库
主钥与各身份的密钥封在 keys-anchor.json 里:口令经 scrypt(N=262144、r=8、p=1)派生密钥,以 AES-128-CTR 加密,keccak MAC 校验。口令为 8 位 ASCII 字母或数字,连错 5 次锁定,只能走恢复。
整机备份
文件名 zikaron-backup-YYYY-MM-DD.zikaron(UTC 日期),同一天再导出编号为 -2、-3。第一行为 zikaron-backup/1,第二行是规范 JSON 文件头:app、created、format、kdf(scrypt 的 N、r、p 与 32 字节盐)、nonce。正文用 scrypt(N=262144、r=8、p=1)从备份密码派生密钥,以 XChaCha20-Poly1305 加密,两行文件头作为附加数据。
备份里有:身份登记、每个身份的密钥、每一份加密的本机文件(解开后放入)、主身份的记录与 machine.json。主钥、口令与错误次数留在本机;明文的导出件(记录包、索引、凭证、授权文件、镜像、密钥文件)也在备份之外。
密钥文件
标准以太坊 keystore(V3):scrypt(N=262144、r=8、p=1)、aes-128-ctr,文件名为 UTC--<时间>--<40 位十六进制地址>,权限 0600,以导出时设定的文件密码(至少 8 位)加密。写出后应用读回核对格式与地址,相符才算导出成功。
记录包
一个文件夹,格式由 zikaron.kit/1 §7 规定:
kit-3fa9c2e1/
manifest.json 清单
entries/<64 位十六进制>.zk1 条目,每条一个文件
files/<路径> 原文件与附件
files/verify.md 给收件方的核验说明
proofs/<路径> 上链证明清单列出每个条目的编号,每个文件的路径、大小与 SHA-256,以及每份证明对应的交易;包里出现清单之外的文件,核验即失败。记录包编号是清单字节的 SHA-256。包内路径只用 a-z、0-9、.、_、-;有附件改过名时,files/zikaron-names.json 记下原名与包内名的对照,改名规则为 <转写名>-<原名 SHA-256 前八位>.<扩展名>。
导出的文件夹名为 kit- 加所选里序号最小的那件记录的内容指纹前八位;所选只含其他条目时为 kit,同名已有即编号为 -2、-3。
记录包索引
机器目录下的 kits/index.json,格式名 zikaron.kits-index/1,明文保存,供同一台机器上的其他应用只读访问,见接入。每导出一个记录包记一行,同一路径再导出时替换原行:
| 字段 | 内容 |
|---|---|
id | 记录包编号 |
created | 导出时刻,Unix 秒 |
root | 账本创建条目的编号 |
path | 包的绝对路径 |
contents | 包内原件的内容指纹 |
note_md | 附言 |
link | 取处(这个包在网上的 https 地址),可选 |
授权码与凭证
文本 zikaron-grant: 后接一段或多段,段间以 . 连接。每段是一条授权条目的规范字节,经 base64url 编码(省去填充);多段时,从最初作者的授权依次排到当前这一份。全长上限 2,953 字节,恰为一个二维码的容量(版本 40、字节模式、纠错等级 L)。格式见 zikaron.kit/1 §6。
凭证文件夹名为 badge- 加授权编号前十位,里面的 badge.txt 是原样的文本,badge.svg 是它的二维码。
授权文件
扩展名 .zkgrant,文件名为 grant- 加授权编号前十位。它是一个容器:第一行 zikaron-kit-file/1,之后每一项写成「包内路径、换行、十进制长度、换行、字节、换行」,清单在前,其余按字节序。上限为总长 64 MiB、4096 项。里面装着:
manifest.json;entries/*.zk1:授权链各跳的条目,授权在本角色账本里时,连同签发者账本;files/zikaron-grant.txt(授权码)、files/terms/…(条款文件)、files/verify.md,以及可选的files/publish.txt(导出这份授权文件的数据目录所设的发布地址)。
账本镜像
<所选文件夹>/ZIKARON-backup/<40 位十六进制地址>/<author|grantee>/
mirror.json 种类 desk-mirror,版本 1
entries/<64 位十六进制> 条目原文,文件名只有编号
held/<路径> 收到的授权等同一文件夹里已有较早的镜像时,只补上新增的条目。要当作命令行的 --ledger 目录,把 entries/ 里的文件复制到空文件夹,并在文件名后加 .entry。
派生路径
约定的字面量
bytes-sha256/1- 存证的方式标记,文件、文件夹与 Git 仓库共用这一个,表示内容指纹是一串字节的 SHA-256。对文件,这串字节是文件的全部字节;对文件夹,是按相对路径排序的规范 JSON
{"files":[{"path":…,"sha256":…}…]}(符号链接与特殊文件略过并计数,空文件夹拒收);对 Git 仓库,是当前提交对象去掉commit <长度>\0头之后的字节,与git cat-file commit HEAD | shasum -a 256相同。与之配对的toolchain是这个字面量本身的 SHA-256:0xb7f3c4a226684d6da684b0ac82d36ed5bcba7bb61d09c955bff9437f84a52a4d。 retraction- 删除条目的类型名。正文中
subject必填,为本账本里一条存证的编号,0x加 64 位小写十六进制;note_md可选。别的工具把它列为未知类型(UNKNOWN_TYPE),账本结论照旧;本应用的读法写在zikaron_glue::retraction,应用与命令行共用。 for- 存证正文里的附加成员:
app、identity(hex20)、ref,另有可选的seat。填了任一项,前三项都要有。 upstream- 授权正文里的附加成员,值为上游授权的编号,zikaron.kit/1 把它读作转授权。