@agentunion/fastaun 0.2.20 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -23
- package/_packed_docs/CHANGELOG.md +63 -23
- package/_packed_docs/design/2026-05-22-aun-rpc-trace-enhancement.md +542 -0
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1 -24
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +419 -0
- package/_packed_docs/protocol/index.md +13 -3
- package/_packed_docs/python-sdk-v2-only-changelog.md +189 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +39 -16
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +131 -39
- package/_packed_docs/sdk/09-message-rpc-manual.md +30 -67
- package/dist/auth.js +26 -7
- package/dist/auth.js.map +1 -1
- package/dist/client.d.ts +117 -166
- package/dist/client.js +2130 -3419
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.js +0 -4
- package/dist/config.js.map +1 -1
- package/dist/e2ee.d.ts +5 -139
- package/dist/e2ee.js +4 -1151
- package/dist/e2ee.js.map +1 -1
- package/dist/errors.d.ts +0 -8
- package/dist/errors.js +0 -14
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/keystore/aid-db.d.ts +12 -61
- package/dist/keystore/aid-db.js +41 -539
- package/dist/keystore/aid-db.js.map +1 -1
- package/dist/keystore/file.d.ts +5 -41
- package/dist/keystore/file.js +8 -64
- package/dist/keystore/file.js.map +1 -1
- package/dist/keystore/index.d.ts +1 -49
- package/dist/namespaces/auth.d.ts +8 -0
- package/dist/namespaces/auth.js +169 -2
- package/dist/namespaces/auth.js.map +1 -1
- package/dist/protected-headers.d.ts +13 -0
- package/dist/protected-headers.js +47 -0
- package/dist/protected-headers.js.map +1 -0
- package/dist/seq-tracker.d.ts +7 -2
- package/dist/seq-tracker.js +33 -13
- package/dist/seq-tracker.js.map +1 -1
- package/dist/transport.d.ts +11 -1
- package/dist/transport.js +255 -6
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +0 -56
- package/dist/v2/crypto/aead.d.ts +20 -0
- package/dist/v2/crypto/aead.js +59 -0
- package/dist/v2/crypto/aead.js.map +1 -0
- package/dist/v2/crypto/canonical.d.ts +20 -0
- package/dist/v2/crypto/canonical.js +119 -0
- package/dist/v2/crypto/canonical.js.map +1 -0
- package/dist/v2/crypto/dh-path.d.ts +39 -0
- package/dist/v2/crypto/dh-path.js +55 -0
- package/dist/v2/crypto/dh-path.js.map +1 -0
- package/dist/v2/crypto/ecdh.d.ts +29 -0
- package/dist/v2/crypto/ecdh.js +122 -0
- package/dist/v2/crypto/ecdh.js.map +1 -0
- package/dist/v2/crypto/ecdsa.d.ts +29 -0
- package/dist/v2/crypto/ecdsa.js +120 -0
- package/dist/v2/crypto/ecdsa.js.map +1 -0
- package/dist/v2/crypto/hkdf.d.ts +19 -0
- package/dist/v2/crypto/hkdf.js +47 -0
- package/dist/v2/crypto/hkdf.js.map +1 -0
- package/dist/v2/crypto/index.d.ts +8 -0
- package/dist/v2/crypto/index.js +8 -0
- package/dist/v2/crypto/index.js.map +1 -0
- package/dist/v2/crypto/recipients.d.ts +32 -0
- package/dist/v2/crypto/recipients.js +183 -0
- package/dist/v2/crypto/recipients.js.map +1 -0
- package/dist/v2/e2ee/decrypt.d.ts +29 -0
- package/dist/v2/e2ee/decrypt.js +159 -0
- package/dist/v2/e2ee/decrypt.js.map +1 -0
- package/dist/v2/e2ee/encrypt-group.d.ts +17 -0
- package/dist/v2/e2ee/encrypt-group.js +143 -0
- package/dist/v2/e2ee/encrypt-group.js.map +1 -0
- package/dist/v2/e2ee/encrypt-p2p.d.ts +31 -0
- package/dist/v2/e2ee/encrypt-p2p.js +190 -0
- package/dist/v2/e2ee/encrypt-p2p.js.map +1 -0
- package/dist/v2/e2ee/index.d.ts +9 -0
- package/dist/v2/e2ee/index.js +9 -0
- package/dist/v2/e2ee/index.js.map +1 -0
- package/dist/v2/e2ee/metadata-auth.d.ts +15 -0
- package/dist/v2/e2ee/metadata-auth.js +50 -0
- package/dist/v2/e2ee/metadata-auth.js.map +1 -0
- package/dist/v2/e2ee/types.d.ts +57 -0
- package/dist/v2/e2ee/types.js +7 -0
- package/dist/v2/e2ee/types.js.map +1 -0
- package/dist/v2/session/index.d.ts +4 -0
- package/dist/v2/session/index.js +3 -0
- package/dist/v2/session/index.js.map +1 -0
- package/dist/v2/session/keystore.d.ts +50 -0
- package/dist/v2/session/keystore.js +138 -0
- package/dist/v2/session/keystore.js.map +1 -0
- package/dist/v2/session/session.d.ts +124 -0
- package/dist/v2/session/session.js +318 -0
- package/dist/v2/session/session.js.map +1 -0
- package/dist/v2/state/commitment.d.ts +58 -0
- package/dist/v2/state/commitment.js +85 -0
- package/dist/v2/state/commitment.js.map +1 -0
- package/dist/v2/state/index.d.ts +2 -0
- package/dist/v2/state/index.js +2 -0
- package/dist/v2/state/index.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V2 E2EE Session Manager。
|
|
3
|
+
*
|
|
4
|
+
* 管理本设备的 IK/SPK 生命周期、服务端注册、加解密密钥获取。
|
|
5
|
+
*
|
|
6
|
+
* 设计要点:
|
|
7
|
+
* - IK = AID 长期密钥(多设备共享 AID 身份),不独立生成
|
|
8
|
+
* - SPK 设备级 P-256 密钥对,IK 签名背书
|
|
9
|
+
* - SPK 销毁三重条件:
|
|
10
|
+
* - contig_seq >= 该 SPK 引用的最大 seq
|
|
11
|
+
* - 自最后一次见到该 spk_id >= 7 天
|
|
12
|
+
* - 不在最近 7 代保留窗口内
|
|
13
|
+
* - 对端 IK 公钥缓存 TTL 1 小时
|
|
14
|
+
* - SPK 注册:调 callFn("message.v2.put_peer_pk", ...)
|
|
15
|
+
*/
|
|
16
|
+
import { V2KeyStore } from './keystore.js';
|
|
17
|
+
/** 对端 IK 公钥缓存 TTL(毫秒)。 */
|
|
18
|
+
export declare const PEER_KEY_CACHE_TTL_MS: number;
|
|
19
|
+
/** SPK 销毁安全窗口(毫秒)。 */
|
|
20
|
+
export declare const DESTROY_DELAY_MS: number;
|
|
21
|
+
/** SPK 销毁时保留的最近代数。 */
|
|
22
|
+
export declare const RECENT_GENERATIONS = 7;
|
|
23
|
+
export declare const HARD_LIMIT_MS: number;
|
|
24
|
+
/** 服务端 RPC 调用函数签名(与 Python `call_fn` 等价)。 */
|
|
25
|
+
export type CallFn = (method: string, params: Record<string, unknown>) => Promise<Record<string, unknown> | unknown>;
|
|
26
|
+
/** 加密所需的发送方身份。 */
|
|
27
|
+
export interface SenderIdentity {
|
|
28
|
+
aid: string;
|
|
29
|
+
deviceId: string;
|
|
30
|
+
ikPriv: Uint8Array;
|
|
31
|
+
ikPubDer: Uint8Array;
|
|
32
|
+
}
|
|
33
|
+
export declare class V2Session {
|
|
34
|
+
private readonly _store;
|
|
35
|
+
private readonly _deviceId;
|
|
36
|
+
private readonly _aid;
|
|
37
|
+
private readonly _ikPriv;
|
|
38
|
+
private readonly _ikPubDer;
|
|
39
|
+
private _spkId;
|
|
40
|
+
private _spkPriv?;
|
|
41
|
+
private _spkPubDer?;
|
|
42
|
+
private _registered;
|
|
43
|
+
private _lastUploadedSPKId;
|
|
44
|
+
private _lastUploadedGroupSPKIds;
|
|
45
|
+
private _peerIKCache;
|
|
46
|
+
private _verifiedSPKs;
|
|
47
|
+
private _oldSPKMaxSeq;
|
|
48
|
+
private _nowFn;
|
|
49
|
+
constructor(store: V2KeyStore, deviceId: string, aid: string, ikPriv: Uint8Array, ikPubDer: Uint8Array);
|
|
50
|
+
/** 测试用:注入虚拟时钟。 */
|
|
51
|
+
_setNowFn(fn: () => number): void;
|
|
52
|
+
get deviceId(): string;
|
|
53
|
+
get aid(): string;
|
|
54
|
+
get currentSpkId(): string;
|
|
55
|
+
get currentIkPubDer(): Uint8Array;
|
|
56
|
+
/** 暴露 store 便于测试(与 Python 同等私有约定)。 */
|
|
57
|
+
get _storeForTest(): V2KeyStore;
|
|
58
|
+
/** 加载或生成当前 SPK;IK 由构造函数注入,无需加载。 */
|
|
59
|
+
ensureKeys(): void;
|
|
60
|
+
private _generateNewSPK;
|
|
61
|
+
/** 注册本设备 SPK 到服务端。IK = AID 长期密钥,无需注册。 */
|
|
62
|
+
ensureRegistered(callFn: CallFn): Promise<void>;
|
|
63
|
+
/** SPK 由 AID 私钥(IK)签名背书,并上报到 message.v2.put_peer_pk。 */
|
|
64
|
+
private _registerSPK;
|
|
65
|
+
/** 返回加密所需的 sender 结构。 */
|
|
66
|
+
getSenderIdentity(): SenderIdentity;
|
|
67
|
+
/**
|
|
68
|
+
* 返回解密所需的私钥。
|
|
69
|
+
* - spkId 空:1DH(仅 IK)
|
|
70
|
+
* - spkId == 当前 SPK:当前 spkPriv
|
|
71
|
+
* - 否则:从 store 加载旧 SPK 私钥(可能为 null = 已销毁)
|
|
72
|
+
*/
|
|
73
|
+
getDecryptKeys(spkId: string | null | undefined): {
|
|
74
|
+
ikPriv: Uint8Array;
|
|
75
|
+
spkPriv?: Uint8Array;
|
|
76
|
+
};
|
|
77
|
+
/** 判断 spkId 是否命中当前活跃 SPK。 */
|
|
78
|
+
isCurrentSPK(spkId: string | null | undefined): boolean;
|
|
79
|
+
/** 跟踪每个旧 SPK 引用的最大 seq(用于销毁判定)。 */
|
|
80
|
+
trackOldSPKMaxSeq(spkId: string, seq: number): void;
|
|
81
|
+
/**
|
|
82
|
+
* contig_seq 已覆盖、超过 7 天安全窗口、且不在最近 7 代保留窗口内时销毁。
|
|
83
|
+
*
|
|
84
|
+
* 销毁条件(全部满足才销毁):
|
|
85
|
+
* - contig_seq >= 该 SPK 引用的最大 seq(接收方已消费完所有引用此 SPK 的消息)
|
|
86
|
+
* - 自最后一次见到该 spk_id 引用 >= 7 天
|
|
87
|
+
* - 不在最近 7 代 SPK 保留窗口内
|
|
88
|
+
*
|
|
89
|
+
* 7 天 + 7 代双兜底:低频群即便 contig_seq 已覆盖也至少留 7 代或 7 天,
|
|
90
|
+
* 避免发送方陈旧 bootstrap 缓存导致新消息加密失败。
|
|
91
|
+
*/
|
|
92
|
+
maybeDestroyOldSPKs(contigSeq: number): string[];
|
|
93
|
+
/** 轮换 SPK:生成新 SPK 并上报到服务端。旧 SPK 保留本地用于解密。 */
|
|
94
|
+
rotateSPK(callFn: CallFn): Promise<void>;
|
|
95
|
+
cachePeerIK(peerAid: string, deviceId: string, ikPubDer: Uint8Array): void;
|
|
96
|
+
getPeerIK(peerAid: string, deviceId: string): Uint8Array | null;
|
|
97
|
+
isPeerSPKVerified(peerAid: string, deviceId: string, spkId: string): boolean;
|
|
98
|
+
markPeerSPKVerified(peerAid: string, deviceId: string, spkId: string): void;
|
|
99
|
+
/** 确保指定群有独立 group SPK,返回 { spkId, priv, pubDER }。 */
|
|
100
|
+
ensureGroupSPK(groupId: string): {
|
|
101
|
+
spkId: string;
|
|
102
|
+
priv: Uint8Array;
|
|
103
|
+
pubDer: Uint8Array;
|
|
104
|
+
};
|
|
105
|
+
/** 注册指定群的 group SPK 到服务端。group 服务负责成员鉴权。 */
|
|
106
|
+
ensureGroupRegistered(groupId: string, callFn: CallFn): Promise<void>;
|
|
107
|
+
/** 轮换指定群的 group SPK,保留旧私钥用于缓存窗口内的历史 wrap 解密。 */
|
|
108
|
+
rotateGroupSPK(groupId: string, callFn: CallFn): Promise<{
|
|
109
|
+
spkId: string;
|
|
110
|
+
priv: Uint8Array;
|
|
111
|
+
pubDer: Uint8Array;
|
|
112
|
+
}>;
|
|
113
|
+
/** 群消息解密优先查 group SPK;找不到时 fallback 旧 P2P SPK 兼容历史消息。 */
|
|
114
|
+
getGroupDecryptKeys(groupId: string, spkId: string): {
|
|
115
|
+
ikPriv: Uint8Array;
|
|
116
|
+
spkPriv: Uint8Array | null;
|
|
117
|
+
};
|
|
118
|
+
/** 判断 spk_id 是否为本进程最后一次成功上传的 P2P SPK。 */
|
|
119
|
+
isLastUploadedSPK(spkId: string): boolean;
|
|
120
|
+
/** 判断 spk_id 是否为本进程在该群最后一次成功上传的 group SPK。 */
|
|
121
|
+
isLastUploadedGroupSPK(groupId: string, spkId: string): boolean;
|
|
122
|
+
/** 签名并上传 group SPK 到 group.v2.put_group_pk。 */
|
|
123
|
+
private _publishGroupSPK;
|
|
124
|
+
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V2 E2EE Session Manager。
|
|
3
|
+
*
|
|
4
|
+
* 管理本设备的 IK/SPK 生命周期、服务端注册、加解密密钥获取。
|
|
5
|
+
*
|
|
6
|
+
* 设计要点:
|
|
7
|
+
* - IK = AID 长期密钥(多设备共享 AID 身份),不独立生成
|
|
8
|
+
* - SPK 设备级 P-256 密钥对,IK 签名背书
|
|
9
|
+
* - SPK 销毁三重条件:
|
|
10
|
+
* - contig_seq >= 该 SPK 引用的最大 seq
|
|
11
|
+
* - 自最后一次见到该 spk_id >= 7 天
|
|
12
|
+
* - 不在最近 7 代保留窗口内
|
|
13
|
+
* - 对端 IK 公钥缓存 TTL 1 小时
|
|
14
|
+
* - SPK 注册:调 callFn("message.v2.put_peer_pk", ...)
|
|
15
|
+
*/
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
17
|
+
import { generateP256Keypair } from '../crypto/ecdh.js';
|
|
18
|
+
import { ecdsaSignRaw } from '../crypto/ecdsa.js';
|
|
19
|
+
/** 对端 IK 公钥缓存 TTL(毫秒)。 */
|
|
20
|
+
export const PEER_KEY_CACHE_TTL_MS = 60 * 60 * 1000; // 1h
|
|
21
|
+
/** SPK 销毁安全窗口(毫秒)。 */
|
|
22
|
+
export const DESTROY_DELAY_MS = 7 * 24 * 60 * 60 * 1000; // 7 天
|
|
23
|
+
/** SPK 销毁时保留的最近代数。 */
|
|
24
|
+
export const RECENT_GENERATIONS = 7;
|
|
25
|
+
export const HARD_LIMIT_MS = 180 * 24 * 60 * 60 * 1000; // 180 天
|
|
26
|
+
export class V2Session {
|
|
27
|
+
_store;
|
|
28
|
+
_deviceId;
|
|
29
|
+
_aid;
|
|
30
|
+
_ikPriv;
|
|
31
|
+
_ikPubDer;
|
|
32
|
+
_spkId = '';
|
|
33
|
+
_spkPriv;
|
|
34
|
+
_spkPubDer;
|
|
35
|
+
_registered = false;
|
|
36
|
+
// SPK 上传去重
|
|
37
|
+
_lastUploadedSPKId = '';
|
|
38
|
+
_lastUploadedGroupSPKIds = new Map();
|
|
39
|
+
_peerIKCache = new Map();
|
|
40
|
+
_verifiedSPKs = new Set();
|
|
41
|
+
_oldSPKMaxSeq = new Map();
|
|
42
|
+
_nowFn = () => Date.now();
|
|
43
|
+
constructor(store, deviceId, aid, ikPriv, ikPubDer) {
|
|
44
|
+
if (!ikPriv || !ikPubDer) {
|
|
45
|
+
throw new Error('V2Session requires AID priv/pub keys (IK = AID identity)');
|
|
46
|
+
}
|
|
47
|
+
this._store = store;
|
|
48
|
+
this._deviceId = deviceId;
|
|
49
|
+
this._aid = aid;
|
|
50
|
+
this._ikPriv = ikPriv;
|
|
51
|
+
this._ikPubDer = ikPubDer;
|
|
52
|
+
}
|
|
53
|
+
/** 测试用:注入虚拟时钟。 */
|
|
54
|
+
_setNowFn(fn) {
|
|
55
|
+
this._nowFn = fn;
|
|
56
|
+
}
|
|
57
|
+
get deviceId() {
|
|
58
|
+
return this._deviceId;
|
|
59
|
+
}
|
|
60
|
+
get aid() {
|
|
61
|
+
return this._aid;
|
|
62
|
+
}
|
|
63
|
+
get currentSpkId() {
|
|
64
|
+
return this._spkId;
|
|
65
|
+
}
|
|
66
|
+
get currentIkPubDer() {
|
|
67
|
+
return this._ikPubDer;
|
|
68
|
+
}
|
|
69
|
+
/** 暴露 store 便于测试(与 Python 同等私有约定)。 */
|
|
70
|
+
get _storeForTest() {
|
|
71
|
+
return this._store;
|
|
72
|
+
}
|
|
73
|
+
/** 加载或生成当前 SPK;IK 由构造函数注入,无需加载。 */
|
|
74
|
+
ensureKeys() {
|
|
75
|
+
if (this._spkPriv)
|
|
76
|
+
return;
|
|
77
|
+
const cur = this._store.loadCurrentSPK(this._deviceId);
|
|
78
|
+
if (cur) {
|
|
79
|
+
this._spkId = cur.spkId;
|
|
80
|
+
this._spkPriv = cur.priv;
|
|
81
|
+
this._spkPubDer = cur.pubDer;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this._generateNewSPK();
|
|
85
|
+
}
|
|
86
|
+
_generateNewSPK() {
|
|
87
|
+
const [priv, pubDer] = generateP256Keypair();
|
|
88
|
+
const hashHex = createHash('sha256').update(pubDer).digest('hex');
|
|
89
|
+
const spkId = `sha256:${hashHex.substring(0, 16)}`;
|
|
90
|
+
this._store.saveSPK(this._deviceId, spkId, priv, pubDer);
|
|
91
|
+
this._spkId = spkId;
|
|
92
|
+
this._spkPriv = priv;
|
|
93
|
+
this._spkPubDer = pubDer;
|
|
94
|
+
}
|
|
95
|
+
/** 注册本设备 SPK 到服务端。IK = AID 长期密钥,无需注册。 */
|
|
96
|
+
async ensureRegistered(callFn) {
|
|
97
|
+
if (this._registered)
|
|
98
|
+
return;
|
|
99
|
+
this.ensureKeys();
|
|
100
|
+
await this._registerSPK(callFn);
|
|
101
|
+
this._registered = true;
|
|
102
|
+
this._lastUploadedSPKId = this._spkId;
|
|
103
|
+
}
|
|
104
|
+
/** SPK 由 AID 私钥(IK)签名背书,并上报到 message.v2.put_peer_pk。 */
|
|
105
|
+
async _registerSPK(callFn) {
|
|
106
|
+
const spkTimestamp = Math.floor(this._nowFn() / 1000);
|
|
107
|
+
const signData = Buffer.concat([
|
|
108
|
+
Buffer.from(this._spkPubDer),
|
|
109
|
+
Buffer.from(this._spkId, 'utf-8'),
|
|
110
|
+
Buffer.from(String(spkTimestamp), 'utf-8'),
|
|
111
|
+
]);
|
|
112
|
+
const signature = ecdsaSignRaw(this._ikPriv, signData);
|
|
113
|
+
await callFn('message.v2.put_peer_pk', {
|
|
114
|
+
peer_aid: this._aid,
|
|
115
|
+
key_source: 'peer_device_prekey',
|
|
116
|
+
spk_id: this._spkId,
|
|
117
|
+
spk_pk: Buffer.from(this._spkPubDer).toString('base64'),
|
|
118
|
+
spk_signature: Buffer.from(signature).toString('base64'),
|
|
119
|
+
spk_timestamp: spkTimestamp,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/** 返回加密所需的 sender 结构。 */
|
|
123
|
+
getSenderIdentity() {
|
|
124
|
+
this.ensureKeys();
|
|
125
|
+
return {
|
|
126
|
+
aid: this._aid,
|
|
127
|
+
deviceId: this._deviceId,
|
|
128
|
+
ikPriv: this._ikPriv,
|
|
129
|
+
ikPubDer: this._ikPubDer,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 返回解密所需的私钥。
|
|
134
|
+
* - spkId 空:1DH(仅 IK)
|
|
135
|
+
* - spkId == 当前 SPK:当前 spkPriv
|
|
136
|
+
* - 否则:从 store 加载旧 SPK 私钥(可能为 null = 已销毁)
|
|
137
|
+
*/
|
|
138
|
+
getDecryptKeys(spkId) {
|
|
139
|
+
this.ensureKeys();
|
|
140
|
+
if (!spkId)
|
|
141
|
+
return { ikPriv: this._ikPriv };
|
|
142
|
+
if (spkId === this._spkId)
|
|
143
|
+
return { ikPriv: this._ikPriv, spkPriv: this._spkPriv };
|
|
144
|
+
const oldSPK = this._store.loadSPK(this._deviceId, spkId);
|
|
145
|
+
if (!oldSPK)
|
|
146
|
+
return { ikPriv: this._ikPriv };
|
|
147
|
+
return { ikPriv: this._ikPriv, spkPriv: oldSPK };
|
|
148
|
+
}
|
|
149
|
+
/** 判断 spkId 是否命中当前活跃 SPK。 */
|
|
150
|
+
isCurrentSPK(spkId) {
|
|
151
|
+
return Boolean(spkId) && spkId === this._spkId;
|
|
152
|
+
}
|
|
153
|
+
/** 跟踪每个旧 SPK 引用的最大 seq(用于销毁判定)。 */
|
|
154
|
+
trackOldSPKMaxSeq(spkId, seq) {
|
|
155
|
+
if (!spkId || spkId === this._spkId)
|
|
156
|
+
return;
|
|
157
|
+
const cur = this._oldSPKMaxSeq.get(spkId);
|
|
158
|
+
const curSeq = cur ? cur.seq : 0;
|
|
159
|
+
if (seq > curSeq) {
|
|
160
|
+
this._oldSPKMaxSeq.set(spkId, { seq, lastSeenAt: this._nowFn() });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* contig_seq 已覆盖、超过 7 天安全窗口、且不在最近 7 代保留窗口内时销毁。
|
|
165
|
+
*
|
|
166
|
+
* 销毁条件(全部满足才销毁):
|
|
167
|
+
* - contig_seq >= 该 SPK 引用的最大 seq(接收方已消费完所有引用此 SPK 的消息)
|
|
168
|
+
* - 自最后一次见到该 spk_id 引用 >= 7 天
|
|
169
|
+
* - 不在最近 7 代 SPK 保留窗口内
|
|
170
|
+
*
|
|
171
|
+
* 7 天 + 7 代双兜底:低频群即便 contig_seq 已覆盖也至少留 7 代或 7 天,
|
|
172
|
+
* 避免发送方陈旧 bootstrap 缓存导致新消息加密失败。
|
|
173
|
+
*/
|
|
174
|
+
maybeDestroyOldSPKs(contigSeq) {
|
|
175
|
+
const destroyed = [];
|
|
176
|
+
const now = this._nowFn();
|
|
177
|
+
let recentKeep;
|
|
178
|
+
try {
|
|
179
|
+
recentKeep = new Set(this._store.listRecentSPKIds(this._deviceId, RECENT_GENERATIONS));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
recentKeep = new Set();
|
|
183
|
+
}
|
|
184
|
+
for (const [spkId, info] of Array.from(this._oldSPKMaxSeq.entries())) {
|
|
185
|
+
if (spkId === this._spkId)
|
|
186
|
+
continue;
|
|
187
|
+
if (contigSeq < info.seq)
|
|
188
|
+
continue;
|
|
189
|
+
if (now - info.lastSeenAt < DESTROY_DELAY_MS)
|
|
190
|
+
continue;
|
|
191
|
+
if (recentKeep.has(spkId))
|
|
192
|
+
continue;
|
|
193
|
+
try {
|
|
194
|
+
this._store.deleteSPK(this._deviceId, spkId);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
// 忽略 delete 失败,但 _oldSPKMaxSeq 仍清理避免重复尝试
|
|
198
|
+
}
|
|
199
|
+
this._oldSPKMaxSeq.delete(spkId);
|
|
200
|
+
destroyed.push(spkId);
|
|
201
|
+
}
|
|
202
|
+
// 180 天硬上限:无论是否被引用,超龄 SPK 强制销毁
|
|
203
|
+
try {
|
|
204
|
+
const expired = this._store.listExpiredSPKIds(this._deviceId, HARD_LIMIT_MS);
|
|
205
|
+
for (const spkId of expired) {
|
|
206
|
+
if (spkId === this._spkId)
|
|
207
|
+
continue;
|
|
208
|
+
try {
|
|
209
|
+
this._store.deleteSPK(this._deviceId, spkId);
|
|
210
|
+
}
|
|
211
|
+
catch { /* ignore */ }
|
|
212
|
+
this._oldSPKMaxSeq.delete(spkId);
|
|
213
|
+
if (!destroyed.includes(spkId))
|
|
214
|
+
destroyed.push(spkId);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch { /* ignore */ }
|
|
218
|
+
return destroyed;
|
|
219
|
+
}
|
|
220
|
+
/** 轮换 SPK:生成新 SPK 并上报到服务端。旧 SPK 保留本地用于解密。 */
|
|
221
|
+
async rotateSPK(callFn) {
|
|
222
|
+
this._generateNewSPK();
|
|
223
|
+
await this._registerSPK(callFn);
|
|
224
|
+
this._lastUploadedSPKId = this._spkId;
|
|
225
|
+
}
|
|
226
|
+
cachePeerIK(peerAid, deviceId, ikPubDer) {
|
|
227
|
+
this._peerIKCache.set(`${peerAid}#${deviceId}`, { pubDer: ikPubDer, cachedAt: this._nowFn() });
|
|
228
|
+
}
|
|
229
|
+
getPeerIK(peerAid, deviceId) {
|
|
230
|
+
const key = `${peerAid}#${deviceId}`;
|
|
231
|
+
const entry = this._peerIKCache.get(key);
|
|
232
|
+
if (!entry)
|
|
233
|
+
return null;
|
|
234
|
+
if (this._nowFn() - entry.cachedAt >= PEER_KEY_CACHE_TTL_MS) {
|
|
235
|
+
this._peerIKCache.delete(key);
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return entry.pubDer;
|
|
239
|
+
}
|
|
240
|
+
isPeerSPKVerified(peerAid, deviceId, spkId) {
|
|
241
|
+
return this._verifiedSPKs.has(`${peerAid}#${deviceId}#${spkId}`);
|
|
242
|
+
}
|
|
243
|
+
markPeerSPKVerified(peerAid, deviceId, spkId) {
|
|
244
|
+
this._verifiedSPKs.add(`${peerAid}#${deviceId}#${spkId}`);
|
|
245
|
+
}
|
|
246
|
+
// ── Group SPK 独立管理 ──────────────────────────────────────────
|
|
247
|
+
/** 确保指定群有独立 group SPK,返回 { spkId, priv, pubDER }。 */
|
|
248
|
+
ensureGroupSPK(groupId) {
|
|
249
|
+
this.ensureKeys();
|
|
250
|
+
const cur = this._store.loadCurrentGroupSPK(this._deviceId, groupId);
|
|
251
|
+
if (cur)
|
|
252
|
+
return cur;
|
|
253
|
+
// 生成新 group SPK
|
|
254
|
+
const [priv, pubDer] = generateP256Keypair();
|
|
255
|
+
const hashHex = createHash('sha256').update(pubDer).digest('hex');
|
|
256
|
+
const spkId = `sha256:${hashHex.substring(0, 16)}`;
|
|
257
|
+
this._store.saveGroupSPK(this._deviceId, groupId, spkId, priv, pubDer);
|
|
258
|
+
return { spkId, priv, pubDer };
|
|
259
|
+
}
|
|
260
|
+
/** 注册指定群的 group SPK 到服务端。group 服务负责成员鉴权。 */
|
|
261
|
+
async ensureGroupRegistered(groupId, callFn) {
|
|
262
|
+
const { spkId, pubDer } = this.ensureGroupSPK(groupId);
|
|
263
|
+
await this._publishGroupSPK(groupId, spkId, pubDer, callFn);
|
|
264
|
+
}
|
|
265
|
+
/** 轮换指定群的 group SPK,保留旧私钥用于缓存窗口内的历史 wrap 解密。 */
|
|
266
|
+
async rotateGroupSPK(groupId, callFn) {
|
|
267
|
+
this.ensureKeys();
|
|
268
|
+
const [priv, pubDer] = generateP256Keypair();
|
|
269
|
+
const hashHex = createHash('sha256').update(pubDer).digest('hex');
|
|
270
|
+
const spkId = `sha256:${hashHex.substring(0, 16)}`;
|
|
271
|
+
this._store.saveGroupSPK(this._deviceId, groupId, spkId, priv, pubDer);
|
|
272
|
+
await this._publishGroupSPK(groupId, spkId, pubDer, callFn);
|
|
273
|
+
return { spkId, priv, pubDer };
|
|
274
|
+
}
|
|
275
|
+
/** 群消息解密优先查 group SPK;找不到时 fallback 旧 P2P SPK 兼容历史消息。 */
|
|
276
|
+
getGroupDecryptKeys(groupId, spkId) {
|
|
277
|
+
this.ensureKeys();
|
|
278
|
+
if (!spkId)
|
|
279
|
+
return { ikPriv: this._ikPriv, spkPriv: null };
|
|
280
|
+
// 优先查 group SPK
|
|
281
|
+
const groupSPK = this._store.loadGroupSPK(this._deviceId, groupId, spkId);
|
|
282
|
+
if (groupSPK)
|
|
283
|
+
return { ikPriv: this._ikPriv, spkPriv: groupSPK };
|
|
284
|
+
// fallback 到 P2P SPK(兼容历史消息)
|
|
285
|
+
if (spkId === this._spkId)
|
|
286
|
+
return { ikPriv: this._ikPriv, spkPriv: this._spkPriv ?? null };
|
|
287
|
+
const oldSPK = this._store.loadSPK(this._deviceId, spkId);
|
|
288
|
+
return { ikPriv: this._ikPriv, spkPriv: oldSPK };
|
|
289
|
+
}
|
|
290
|
+
/** 判断 spk_id 是否为本进程最后一次成功上传的 P2P SPK。 */
|
|
291
|
+
isLastUploadedSPK(spkId) {
|
|
292
|
+
return Boolean(spkId) && spkId === this._lastUploadedSPKId;
|
|
293
|
+
}
|
|
294
|
+
/** 判断 spk_id 是否为本进程在该群最后一次成功上传的 group SPK。 */
|
|
295
|
+
isLastUploadedGroupSPK(groupId, spkId) {
|
|
296
|
+
return Boolean(spkId) && this._lastUploadedGroupSPKIds.get(groupId) === spkId;
|
|
297
|
+
}
|
|
298
|
+
/** 签名并上传 group SPK 到 group.v2.put_group_pk。 */
|
|
299
|
+
async _publishGroupSPK(groupId, spkId, pubDer, callFn) {
|
|
300
|
+
const spkTimestamp = Math.floor(this._nowFn() / 1000);
|
|
301
|
+
const signData = Buffer.concat([
|
|
302
|
+
Buffer.from(pubDer),
|
|
303
|
+
Buffer.from(spkId, 'utf-8'),
|
|
304
|
+
Buffer.from(String(spkTimestamp), 'utf-8'),
|
|
305
|
+
]);
|
|
306
|
+
const signature = ecdsaSignRaw(this._ikPriv, signData);
|
|
307
|
+
await callFn('group.v2.put_group_pk', {
|
|
308
|
+
group_id: groupId,
|
|
309
|
+
key_source: 'group_device_prekey',
|
|
310
|
+
spk_id: spkId,
|
|
311
|
+
spk_pk: Buffer.from(pubDer).toString('base64'),
|
|
312
|
+
spk_signature: Buffer.from(signature).toString('base64'),
|
|
313
|
+
spk_timestamp: spkTimestamp,
|
|
314
|
+
});
|
|
315
|
+
this._lastUploadedGroupSPKIds.set(groupId, spkId);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/v2/session/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AUN E2EE V2: state_commitment 计算
|
|
3
|
+
*
|
|
4
|
+
* 规范引用:§6.2
|
|
5
|
+
*
|
|
6
|
+
* state_commitment = SHA256(
|
|
7
|
+
* "AUN-V2-SC-v1" ||
|
|
8
|
+
* group_id ||
|
|
9
|
+
* uint32(epoch, big-endian) ||
|
|
10
|
+
* canonical_json({
|
|
11
|
+
* "members": [...sorted by aid, devices sorted by device_id...],
|
|
12
|
+
* "audit_aids": [...sorted...],
|
|
13
|
+
* "join_policy_hash": "64hex" | null,
|
|
14
|
+
* "admin_set": {"admin_aids": [...sorted...], "threshold": N},
|
|
15
|
+
* "recovery_quorum": {...} | null,
|
|
16
|
+
* "history_policy": "none" | "recent_N_days" | "full",
|
|
17
|
+
* "wrap_protocol": "3DH" | "1DH"
|
|
18
|
+
* })
|
|
19
|
+
* )
|
|
20
|
+
*
|
|
21
|
+
* 排序在内部完成,调用方无需预排序。
|
|
22
|
+
*/
|
|
23
|
+
export declare const STATE_PREFIX: Uint8Array;
|
|
24
|
+
export interface MemberDevice {
|
|
25
|
+
device_id?: string;
|
|
26
|
+
fp?: string;
|
|
27
|
+
[k: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
export interface Member {
|
|
30
|
+
aid?: string;
|
|
31
|
+
devices?: MemberDevice[];
|
|
32
|
+
[k: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface AdminSet {
|
|
35
|
+
admin_aids?: string[];
|
|
36
|
+
threshold?: number;
|
|
37
|
+
[k: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
export interface RecoveryQuorum {
|
|
40
|
+
trigger?: string;
|
|
41
|
+
quorum_aids?: string[];
|
|
42
|
+
threshold?: number;
|
|
43
|
+
[k: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
export interface StatePayload {
|
|
46
|
+
members?: Member[];
|
|
47
|
+
audit_aids?: string[];
|
|
48
|
+
join_policy_hash?: string | null;
|
|
49
|
+
admin_set?: AdminSet;
|
|
50
|
+
recovery_quorum?: RecoveryQuorum | null;
|
|
51
|
+
history_policy?: string;
|
|
52
|
+
wrap_protocol?: string;
|
|
53
|
+
[k: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 计算 state_commitment(hex)。
|
|
57
|
+
*/
|
|
58
|
+
export declare function computeStateCommitment(groupId: string, epoch: number, statePayload: StatePayload): string;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AUN E2EE V2: state_commitment 计算
|
|
3
|
+
*
|
|
4
|
+
* 规范引用:§6.2
|
|
5
|
+
*
|
|
6
|
+
* state_commitment = SHA256(
|
|
7
|
+
* "AUN-V2-SC-v1" ||
|
|
8
|
+
* group_id ||
|
|
9
|
+
* uint32(epoch, big-endian) ||
|
|
10
|
+
* canonical_json({
|
|
11
|
+
* "members": [...sorted by aid, devices sorted by device_id...],
|
|
12
|
+
* "audit_aids": [...sorted...],
|
|
13
|
+
* "join_policy_hash": "64hex" | null,
|
|
14
|
+
* "admin_set": {"admin_aids": [...sorted...], "threshold": N},
|
|
15
|
+
* "recovery_quorum": {...} | null,
|
|
16
|
+
* "history_policy": "none" | "recent_N_days" | "full",
|
|
17
|
+
* "wrap_protocol": "3DH" | "1DH"
|
|
18
|
+
* })
|
|
19
|
+
* )
|
|
20
|
+
*
|
|
21
|
+
* 排序在内部完成,调用方无需预排序。
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
import { canonicalJson } from '../crypto/canonical.js';
|
|
25
|
+
export const STATE_PREFIX = new TextEncoder().encode('AUN-V2-SC-v1');
|
|
26
|
+
/** in-place 规范化排序。 */
|
|
27
|
+
function sortPayload(payload) {
|
|
28
|
+
if (Array.isArray(payload.members)) {
|
|
29
|
+
payload.members.sort((a, b) => {
|
|
30
|
+
const ka = a.aid ?? '';
|
|
31
|
+
const kb = b.aid ?? '';
|
|
32
|
+
if (ka === kb)
|
|
33
|
+
return 0;
|
|
34
|
+
return ka < kb ? -1 : 1;
|
|
35
|
+
});
|
|
36
|
+
for (const m of payload.members) {
|
|
37
|
+
if (Array.isArray(m.devices)) {
|
|
38
|
+
m.devices.sort((a, b) => {
|
|
39
|
+
const ka = a.device_id ?? '';
|
|
40
|
+
const kb = b.device_id ?? '';
|
|
41
|
+
if (ka === kb)
|
|
42
|
+
return 0;
|
|
43
|
+
return ka < kb ? -1 : 1;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(payload.audit_aids)) {
|
|
49
|
+
payload.audit_aids.sort();
|
|
50
|
+
}
|
|
51
|
+
if (payload.admin_set && Array.isArray(payload.admin_set.admin_aids)) {
|
|
52
|
+
payload.admin_set.admin_aids.sort();
|
|
53
|
+
}
|
|
54
|
+
if (payload.recovery_quorum && Array.isArray(payload.recovery_quorum.quorum_aids)) {
|
|
55
|
+
payload.recovery_quorum.quorum_aids.sort();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** 大端 uint32 编码。 */
|
|
59
|
+
function uint32BE(value) {
|
|
60
|
+
if (value < 0 || value > 0xffffffff || !Number.isInteger(value)) {
|
|
61
|
+
throw new Error(`epoch out of uint32 range: ${value}`);
|
|
62
|
+
}
|
|
63
|
+
const out = new Uint8Array(4);
|
|
64
|
+
const dv = new DataView(out.buffer);
|
|
65
|
+
dv.setUint32(0, value, false);
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 计算 state_commitment(hex)。
|
|
70
|
+
*/
|
|
71
|
+
export function computeStateCommitment(groupId, epoch, statePayload) {
|
|
72
|
+
// 深拷贝避免修改调用方数据
|
|
73
|
+
const payload = JSON.parse(JSON.stringify(statePayload));
|
|
74
|
+
sortPayload(payload);
|
|
75
|
+
const groupBytes = new TextEncoder().encode(groupId);
|
|
76
|
+
const epochBytes = uint32BE(epoch);
|
|
77
|
+
const payloadBytes = canonicalJson(payload);
|
|
78
|
+
const h = createHash('sha256');
|
|
79
|
+
h.update(STATE_PREFIX);
|
|
80
|
+
h.update(groupBytes);
|
|
81
|
+
h.update(epochBytes);
|
|
82
|
+
h.update(payloadBytes);
|
|
83
|
+
return h.digest('hex');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=commitment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commitment.js","sourceRoot":"","sources":["../../../src/v2/state/commitment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/v2/state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentunion/fastaun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "AUN Protocol Core SDK for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,12 +27,13 @@
|
|
|
27
27
|
"prepack": "python ../scripts/sync_packed_docs.py ts",
|
|
28
28
|
"test": "vitest run",
|
|
29
29
|
"test:unit": "vitest run tests/unit",
|
|
30
|
-
"test:integration": "vitest run tests/integration/e2ee.test.ts",
|
|
31
|
-
"test:e2e": "vitest run tests/e2e/group-
|
|
30
|
+
"test:integration": "vitest run tests/integration/federation-v2-thought.test.ts tests/integration/group-e2ee.test.ts",
|
|
31
|
+
"test:e2e": "vitest run tests/e2e/v2-p2p.test.ts tests/e2e/v2-group.test.ts tests/e2e/v2-thought.test.ts",
|
|
32
32
|
"test:federation": "vitest run tests/integration/federation.test.ts tests/integration/federation-storage.test.ts",
|
|
33
33
|
"test:watch": "vitest"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@noble/curves": "^2.2.0",
|
|
36
37
|
"ws": "^8.18.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|