@agentunion/fastaun-browser 0.2.20 → 0.3.0

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.
Files changed (119) hide show
  1. package/CHANGELOG.md +50 -26
  2. package/_packed_docs/CHANGELOG.md +50 -26
  3. 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
  4. package/_packed_docs/protocol/index.md +13 -3
  5. package/_packed_docs/python-sdk-v2-only-changelog.md +189 -0
  6. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +39 -16
  7. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +90 -39
  8. package/dist/auth.d.ts.map +1 -1
  9. package/dist/auth.js +20 -3
  10. package/dist/auth.js.map +1 -1
  11. package/dist/bundle.js +14300 -0
  12. package/dist/client.d.ts +179 -187
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +3007 -4012
  15. package/dist/client.js.map +1 -1
  16. package/dist/config.d.ts +0 -4
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +0 -4
  19. package/dist/config.js.map +1 -1
  20. package/dist/crypto.d.ts +8 -1
  21. package/dist/crypto.d.ts.map +1 -1
  22. package/dist/crypto.js +114 -1
  23. package/dist/crypto.js.map +1 -1
  24. package/dist/e2ee.d.ts +5 -210
  25. package/dist/e2ee.d.ts.map +1 -1
  26. package/dist/e2ee.js +4 -1379
  27. package/dist/e2ee.js.map +1 -1
  28. package/dist/index.d.ts +7 -3
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +5 -4
  31. package/dist/index.js.map +1 -1
  32. package/dist/namespaces/auth.d.ts.map +1 -1
  33. package/dist/namespaces/auth.js +5 -4
  34. package/dist/namespaces/auth.js.map +1 -1
  35. package/dist/protected-headers.d.ts +14 -0
  36. package/dist/protected-headers.d.ts.map +1 -0
  37. package/dist/protected-headers.js +47 -0
  38. package/dist/protected-headers.js.map +1 -0
  39. package/dist/seq-tracker.d.ts +7 -2
  40. package/dist/seq-tracker.d.ts.map +1 -1
  41. package/dist/seq-tracker.js +31 -10
  42. package/dist/seq-tracker.js.map +1 -1
  43. package/dist/v2/crypto/aead.d.ts +26 -0
  44. package/dist/v2/crypto/aead.d.ts.map +1 -0
  45. package/dist/v2/crypto/aead.js +63 -0
  46. package/dist/v2/crypto/aead.js.map +1 -0
  47. package/dist/v2/crypto/canonical.d.ts +21 -0
  48. package/dist/v2/crypto/canonical.d.ts.map +1 -0
  49. package/dist/v2/crypto/canonical.js +111 -0
  50. package/dist/v2/crypto/canonical.js.map +1 -0
  51. package/dist/v2/crypto/dh-path.d.ts +21 -0
  52. package/dist/v2/crypto/dh-path.d.ts.map +1 -0
  53. package/dist/v2/crypto/dh-path.js +50 -0
  54. package/dist/v2/crypto/dh-path.js.map +1 -0
  55. package/dist/v2/crypto/ecdh.d.ts +19 -0
  56. package/dist/v2/crypto/ecdh.d.ts.map +1 -0
  57. package/dist/v2/crypto/ecdh.js +101 -0
  58. package/dist/v2/crypto/ecdh.js.map +1 -0
  59. package/dist/v2/crypto/ecdsa.d.ts +16 -0
  60. package/dist/v2/crypto/ecdsa.d.ts.map +1 -0
  61. package/dist/v2/crypto/ecdsa.js +52 -0
  62. package/dist/v2/crypto/ecdsa.js.map +1 -0
  63. package/dist/v2/crypto/hkdf.d.ts +21 -0
  64. package/dist/v2/crypto/hkdf.d.ts.map +1 -0
  65. package/dist/v2/crypto/hkdf.js +32 -0
  66. package/dist/v2/crypto/hkdf.js.map +1 -0
  67. package/dist/v2/crypto/index.d.ts +9 -0
  68. package/dist/v2/crypto/index.d.ts.map +1 -0
  69. package/dist/v2/crypto/index.js +8 -0
  70. package/dist/v2/crypto/index.js.map +1 -0
  71. package/dist/v2/crypto/recipients.d.ts +43 -0
  72. package/dist/v2/crypto/recipients.d.ts.map +1 -0
  73. package/dist/v2/crypto/recipients.js +188 -0
  74. package/dist/v2/crypto/recipients.js.map +1 -0
  75. package/dist/v2/e2ee/decrypt.d.ts +13 -0
  76. package/dist/v2/e2ee/decrypt.d.ts.map +1 -0
  77. package/dist/v2/e2ee/decrypt.js +176 -0
  78. package/dist/v2/e2ee/decrypt.js.map +1 -0
  79. package/dist/v2/e2ee/encrypt-group.d.ts +14 -0
  80. package/dist/v2/e2ee/encrypt-group.d.ts.map +1 -0
  81. package/dist/v2/e2ee/encrypt-group.js +196 -0
  82. package/dist/v2/e2ee/encrypt-group.js.map +1 -0
  83. package/dist/v2/e2ee/encrypt-p2p.d.ts +15 -0
  84. package/dist/v2/e2ee/encrypt-p2p.d.ts.map +1 -0
  85. package/dist/v2/e2ee/encrypt-p2p.js +240 -0
  86. package/dist/v2/e2ee/encrypt-p2p.js.map +1 -0
  87. package/dist/v2/e2ee/index.d.ts +9 -0
  88. package/dist/v2/e2ee/index.d.ts.map +1 -0
  89. package/dist/v2/e2ee/index.js +9 -0
  90. package/dist/v2/e2ee/index.js.map +1 -0
  91. package/dist/v2/e2ee/metadata-auth.d.ts +9 -0
  92. package/dist/v2/e2ee/metadata-auth.d.ts.map +1 -0
  93. package/dist/v2/e2ee/metadata-auth.js +60 -0
  94. package/dist/v2/e2ee/metadata-auth.js.map +1 -0
  95. package/dist/v2/e2ee/types.d.ts +57 -0
  96. package/dist/v2/e2ee/types.d.ts.map +1 -0
  97. package/dist/v2/e2ee/types.js +7 -0
  98. package/dist/v2/e2ee/types.js.map +1 -0
  99. package/dist/v2/session/index.d.ts +4 -0
  100. package/dist/v2/session/index.d.ts.map +1 -0
  101. package/dist/v2/session/index.js +3 -0
  102. package/dist/v2/session/index.js.map +1 -0
  103. package/dist/v2/session/keystore.d.ts +48 -0
  104. package/dist/v2/session/keystore.d.ts.map +1 -0
  105. package/dist/v2/session/keystore.js +184 -0
  106. package/dist/v2/session/keystore.js.map +1 -0
  107. package/dist/v2/session/session.d.ts +98 -0
  108. package/dist/v2/session/session.d.ts.map +1 -0
  109. package/dist/v2/session/session.js +270 -0
  110. package/dist/v2/session/session.js.map +1 -0
  111. package/dist/v2/state/commitment.d.ts +10 -0
  112. package/dist/v2/state/commitment.d.ts.map +1 -0
  113. package/dist/v2/state/commitment.js +86 -0
  114. package/dist/v2/state/commitment.js.map +1 -0
  115. package/dist/v2/state/index.d.ts +2 -0
  116. package/dist/v2/state/index.d.ts.map +1 -0
  117. package/dist/v2/state/index.js +2 -0
  118. package/dist/v2/state/index.js.map +1 -0
  119. package/package.json +8 -5
@@ -0,0 +1,196 @@
1
+ /**
2
+ * AUN E2EE V2: Group 加密引擎(浏览器版,async)
3
+ *
4
+ * 构造完整的 e2ee.group_encrypted envelope。纯计算,无 IO。
5
+ * 与 P2P 引擎同构,差异在 AAD(含 group_id/epoch/state_commitment)。
6
+ *
7
+ * 参考实现: python/src/aun_core/v2/e2ee/encrypt_group.py
8
+ */
9
+ import { canonicalJson } from '../crypto/canonical';
10
+ import { ecdsaSignRaw } from '../crypto/ecdsa';
11
+ import { aesGcmEncrypt } from '../crypto/aead';
12
+ import { generateP256Keypair } from '../crypto/ecdh';
13
+ import { compute3DHWrap, compute1DHWrap } from '../crypto/dh-path';
14
+ import { sortRecipients, computeRecipientsDigest } from '../crypto/recipients';
15
+ import { SUITE_NAME, } from './types';
16
+ import { withMetadataAuth, PROTECTED_HEADERS_DOMAIN, PROTECTED_CONTEXT_DOMAIN, } from './metadata-auth';
17
+ import { normalizeProtectedHeaders } from './encrypt-p2p';
18
+ const encoder = new TextEncoder();
19
+ async function sha256(data) {
20
+ const buf = await crypto.subtle.digest('SHA-256', data.slice().buffer);
21
+ return new Uint8Array(buf);
22
+ }
23
+ function bytesToBase64(b) {
24
+ let bin = '';
25
+ for (let i = 0; i < b.length; i++)
26
+ bin += String.fromCharCode(b[i]);
27
+ return btoa(bin);
28
+ }
29
+ function bytesToHex(b) {
30
+ let s = '';
31
+ for (let i = 0; i < b.length; i++)
32
+ s += b[i].toString(16).padStart(2, '0');
33
+ return s;
34
+ }
35
+ function hexToBytes(s) {
36
+ if (s.length % 2 !== 0)
37
+ throw new Error('hex length must be even');
38
+ const out = new Uint8Array(s.length / 2);
39
+ for (let i = 0; i < out.length; i++) {
40
+ const hi = parseInt(s.charAt(i * 2), 16);
41
+ const lo = parseInt(s.charAt(i * 2 + 1), 16);
42
+ if (Number.isNaN(hi) || Number.isNaN(lo))
43
+ throw new Error('invalid hex char');
44
+ out[i] = (hi << 4) | lo;
45
+ }
46
+ return out;
47
+ }
48
+ function uuid4Hex() {
49
+ if (typeof crypto.randomUUID === 'function') {
50
+ return crypto.randomUUID().replace(/-/g, '');
51
+ }
52
+ const b = new Uint8Array(16);
53
+ crypto.getRandomValues(b);
54
+ b[6] = (b[6] & 0x0f) | 0x40;
55
+ b[8] = (b[8] & 0x3f) | 0x80;
56
+ return bytesToHex(b);
57
+ }
58
+ function randomBytes(n) {
59
+ const b = new Uint8Array(n);
60
+ crypto.getRandomValues(b);
61
+ return b;
62
+ }
63
+ /**
64
+ * 构造完整的 V2 Group 加密 envelope。
65
+ *
66
+ * @param sender 发送方身份
67
+ * @param groupId 群 ID
68
+ * @param epoch 当前加密 epoch
69
+ * @param targets 所有接收设备列表
70
+ * @param payload 业务 payload(将被加密)
71
+ * @param opts 可选参数(messageId / timestamp)
72
+ * @param stateCommitment 绑定到 AAD 的 state 信息;缺省 → sv=0 占位
73
+ */
74
+ export async function encryptGroupMessage(sender, groupId, epoch, targets, payload, opts = {}, stateCommitment) {
75
+ const masterKey = randomBytes(32);
76
+ const msgNonce = randomBytes(12);
77
+ const messageId = opts.messageId ?? `m-${uuid4Hex()}`;
78
+ const timestamp = opts.timestamp ?? Date.now();
79
+ const protocolSet = new Set();
80
+ for (const t of targets) {
81
+ if (t.spkPkDer
82
+ && (t.keySource === 'peer_device_prekey' || t.keySource === 'group_device_prekey')) {
83
+ protocolSet.add('3DH');
84
+ }
85
+ else {
86
+ protocolSet.add('1DH');
87
+ }
88
+ }
89
+ const wrapProtocolStr = protocolSet.size > 0 ? [...protocolSet].sort().join('+') : '1DH';
90
+ const sc = stateCommitment ?? {};
91
+ const stateCommitmentAad = {
92
+ state_version: Math.trunc(Number(sc.state_version ?? 0)) || 0,
93
+ state_hash: String(sc.state_hash ?? ''),
94
+ state_chain: String(sc.state_chain ?? ''),
95
+ };
96
+ const aad = {
97
+ from: sender.aid,
98
+ from_device: sender.deviceId,
99
+ group_id: groupId,
100
+ epoch,
101
+ message_id: messageId,
102
+ timestamp,
103
+ suite: SUITE_NAME,
104
+ wrap_protocol: wrapProtocolStr,
105
+ state_commitment: stateCommitmentAad,
106
+ };
107
+ const plaintextBytes = canonicalJson(payload);
108
+ const aadBytes = canonicalJson(aad);
109
+ const { ciphertext, tag } = await aesGcmEncrypt(masterKey, msgNonce, plaintextBytes, aadBytes);
110
+ const [senderSessionPriv, senderSessionPubDer] = await generateP256Keypair();
111
+ const suiteBytes = encoder.encode(SUITE_NAME);
112
+ const saltInput = new Uint8Array(aadBytes.length + senderSessionPubDer.length + suiteBytes.length);
113
+ saltInput.set(aadBytes, 0);
114
+ saltInput.set(senderSessionPubDer, aadBytes.length);
115
+ saltInput.set(suiteBytes, aadBytes.length + senderSessionPubDer.length);
116
+ const wrapSalt = (await sha256(saltInput)).subarray(0, 16);
117
+ const recipientsRows = [];
118
+ for (const target of targets) {
119
+ recipientsRows.push(await wrapForRecipient(target, masterKey, senderSessionPriv, sender.ikPriv, wrapSalt));
120
+ }
121
+ const sortedRows = sortRecipients(recipientsRows);
122
+ const digestHex = await computeRecipientsDigest(sortedRows);
123
+ const digestBytes = hexToBytes(digestHex);
124
+ const signInput = new Uint8Array(ciphertext.length + tag.length + aadBytes.length + digestBytes.length);
125
+ let pos = 0;
126
+ signInput.set(ciphertext, pos);
127
+ pos += ciphertext.length;
128
+ signInput.set(tag, pos);
129
+ pos += tag.length;
130
+ signInput.set(aadBytes, pos);
131
+ pos += aadBytes.length;
132
+ signInput.set(digestBytes, pos);
133
+ const senderSig = await ecdsaSignRaw(sender.ikPriv, signInput);
134
+ const certFpHash = bytesToHex(await sha256(sender.ikPubDer));
135
+ const certFp = `sha256:${certFpHash.substring(0, 16)}`;
136
+ const envelope = {
137
+ type: 'e2ee.group_encrypted',
138
+ version: 'v2',
139
+ suite: SUITE_NAME,
140
+ msg_type: 'original',
141
+ group_id: groupId,
142
+ epoch,
143
+ t_send: timestamp,
144
+ t_server: null,
145
+ nonce: bytesToBase64(msgNonce),
146
+ ciphertext: bytesToBase64(ciphertext),
147
+ tag: bytesToBase64(tag),
148
+ sender_signature: bytesToBase64(senderSig),
149
+ sender_cert_fingerprint: certFp,
150
+ sender_session_pk: bytesToBase64(senderSessionPubDer),
151
+ recipients_digest: digestHex,
152
+ recipients: sortedRows,
153
+ aad,
154
+ };
155
+ // protected_headers / context:HMAC 签名(与 V1 对齐),不进 AAD
156
+ // payload_type 自动注入 + value 转 string(与 Python _normalize_headers 对齐)
157
+ const { context } = opts;
158
+ const normalizedHeaders = normalizeProtectedHeaders(opts.protectedHeaders, payload);
159
+ if (Object.keys(normalizedHeaders).length > 0) {
160
+ envelope.protected_headers = await withMetadataAuth(normalizedHeaders, masterKey, PROTECTED_HEADERS_DOMAIN);
161
+ }
162
+ if (context && typeof context === 'object' && Object.keys(context).length > 0) {
163
+ envelope.context = await withMetadataAuth(context, masterKey, PROTECTED_CONTEXT_DOMAIN);
164
+ }
165
+ return envelope;
166
+ }
167
+ async function wrapForRecipient(target, masterKey, senderSessionPriv, senderMasterPriv, wrapSalt) {
168
+ const role = target.role ?? 'member';
169
+ const keySource = target.keySource ?? 'aid_master';
170
+ const fpHash = bytesToHex(await sha256(target.ikPkDer));
171
+ const fp = `sha256:${fpHash.substring(0, 16)}`;
172
+ const wrapNonce = randomBytes(12);
173
+ let wrapKey;
174
+ if (target.spkPkDer
175
+ && (keySource === 'peer_device_prekey' || keySource === 'group_device_prekey')) {
176
+ wrapKey = await compute3DHWrap(senderSessionPriv, senderMasterPriv, target.ikPkDer, target.spkPkDer, wrapSalt);
177
+ }
178
+ else {
179
+ wrapKey = await compute1DHWrap(senderSessionPriv, target.ikPkDer, wrapSalt);
180
+ }
181
+ const { ciphertext: wrappedCt, tag: wrappedTag } = await aesGcmEncrypt(wrapKey, wrapNonce, masterKey, new Uint8Array(0));
182
+ const wrappedKey = new Uint8Array(wrappedCt.length + wrappedTag.length);
183
+ wrappedKey.set(wrappedCt, 0);
184
+ wrappedKey.set(wrappedTag, wrappedCt.length);
185
+ return [
186
+ target.aid,
187
+ target.deviceId,
188
+ role,
189
+ keySource,
190
+ fp,
191
+ target.spkId ?? '',
192
+ bytesToBase64(wrapNonce),
193
+ bytesToBase64(wrappedKey),
194
+ ];
195
+ }
196
+ //# sourceMappingURL=encrypt-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt-group.js","sourceRoot":"","sources":["../../../src/v2/e2ee/encrypt-group.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type Sender, type TargetSet, type EncryptOptions } from './types';
2
+ /**
3
+ * 构造完整的 V2 P2P 加密 envelope。
4
+ *
5
+ * 与 Python `encrypt_p2p_message` 字节级对齐(除了随机字段:master_key/msg_nonce/
6
+ * sender_session keypair/wrap_nonce/message_id/timestamp,以及由此影响的 ciphertext/
7
+ * tag/recipients_digest/sender_signature)。
8
+ */
9
+ export declare function encryptP2PMessage(sender: Sender, targetSet: TargetSet, payload: Record<string, unknown>, opts?: EncryptOptions): Promise<Record<string, unknown>>;
10
+ /**
11
+ * 规范化 protected_headers:value 转 string + 自动注入 payload_type。
12
+ * 与 Python `_normalize_headers` 对齐。
13
+ */
14
+ export declare function normalizeProtectedHeaders(headers: Record<string, unknown> | undefined | null, payload: Record<string, unknown>): Record<string, string>;
15
+ //# sourceMappingURL=encrypt-p2p.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt-p2p.d.ts","sourceRoot":"","sources":["../../../src/v2/e2ee/encrypt-p2p.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,SAAS,CAAC;AAyDjB;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+IlC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,EACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * AUN E2EE V2: P2P 加密引擎(浏览器版,async)
3
+ *
4
+ * 构造完整的 e2ee.p2p_encrypted envelope。纯计算,无 IO。
5
+ *
6
+ * 规范引用: §4 / §5
7
+ *
8
+ * 参考实现: python/src/aun_core/v2/e2ee/encrypt_p2p.py
9
+ */
10
+ import { canonicalJson } from '../crypto/canonical';
11
+ import { ecdsaSignRaw } from '../crypto/ecdsa';
12
+ import { aesGcmEncrypt } from '../crypto/aead';
13
+ import { generateP256Keypair } from '../crypto/ecdh';
14
+ import { compute3DHWrap, compute1DHWrap } from '../crypto/dh-path';
15
+ import { sortRecipients, computeRecipientsDigest } from '../crypto/recipients';
16
+ import { SUITE_NAME, } from './types';
17
+ import { withMetadataAuth, PROTECTED_HEADERS_DOMAIN, PROTECTED_CONTEXT_DOMAIN, } from './metadata-auth';
18
+ const encoder = new TextEncoder();
19
+ async function sha256(data) {
20
+ const buf = await crypto.subtle.digest('SHA-256', data.slice().buffer);
21
+ return new Uint8Array(buf);
22
+ }
23
+ function bytesToBase64(b) {
24
+ let bin = '';
25
+ for (let i = 0; i < b.length; i++)
26
+ bin += String.fromCharCode(b[i]);
27
+ return btoa(bin);
28
+ }
29
+ function bytesToHex(b) {
30
+ let s = '';
31
+ for (let i = 0; i < b.length; i++)
32
+ s += b[i].toString(16).padStart(2, '0');
33
+ return s;
34
+ }
35
+ function hexToBytes(s) {
36
+ if (s.length % 2 !== 0)
37
+ throw new Error('hex length must be even');
38
+ const out = new Uint8Array(s.length / 2);
39
+ for (let i = 0; i < out.length; i++) {
40
+ const hi = parseInt(s.charAt(i * 2), 16);
41
+ const lo = parseInt(s.charAt(i * 2 + 1), 16);
42
+ if (Number.isNaN(hi) || Number.isNaN(lo))
43
+ throw new Error('invalid hex char');
44
+ out[i] = (hi << 4) | lo;
45
+ }
46
+ return out;
47
+ }
48
+ function uuid4Hex() {
49
+ // crypto.randomUUID() 在浏览器和 Node 18+ 都可用,去掉 dash 与 Python uuid4().hex 对齐
50
+ if (typeof crypto.randomUUID === 'function') {
51
+ return crypto.randomUUID().replace(/-/g, '');
52
+ }
53
+ // 降级:用 16B 随机字节构造 v4 hex
54
+ const b = new Uint8Array(16);
55
+ crypto.getRandomValues(b);
56
+ b[6] = (b[6] & 0x0f) | 0x40; // version 4
57
+ b[8] = (b[8] & 0x3f) | 0x80; // variant
58
+ return bytesToHex(b);
59
+ }
60
+ function randomBytes(n) {
61
+ const b = new Uint8Array(n);
62
+ crypto.getRandomValues(b);
63
+ return b;
64
+ }
65
+ /**
66
+ * 构造完整的 V2 P2P 加密 envelope。
67
+ *
68
+ * 与 Python `encrypt_p2p_message` 字节级对齐(除了随机字段:master_key/msg_nonce/
69
+ * sender_session keypair/wrap_nonce/message_id/timestamp,以及由此影响的 ciphertext/
70
+ * tag/recipients_digest/sender_signature)。
71
+ */
72
+ export async function encryptP2PMessage(sender, targetSet, payload, opts = {}) {
73
+ // 1. master_key + msg_nonce
74
+ const masterKey = randomBytes(32);
75
+ const msgNonce = randomBytes(12);
76
+ // 2. 构造 AAD
77
+ const messageId = opts.messageId ?? `m-${uuid4Hex()}`;
78
+ const timestamp = opts.timestamp ?? Date.now();
79
+ // 确定 to(第一个非 audit 的 aid)
80
+ let peerAid = '';
81
+ for (const t of targetSet.targets) {
82
+ if (t.role !== 'audit') {
83
+ peerAid = t.aid;
84
+ break;
85
+ }
86
+ }
87
+ // wrap_protocol_set(防服务端篡改 key_source 引导接收方走 1DH)
88
+ const allTargetsForProto = [
89
+ ...targetSet.targets,
90
+ ...(targetSet.auditRecipients ?? []),
91
+ ];
92
+ const protocolSet = new Set();
93
+ for (const t of allTargetsForProto) {
94
+ if (t.spkPkDer
95
+ && (t.keySource === 'peer_device_prekey' || t.keySource === 'group_device_prekey')) {
96
+ protocolSet.add('3DH');
97
+ }
98
+ else {
99
+ protocolSet.add('1DH');
100
+ }
101
+ }
102
+ const wrapProtocolStr = protocolSet.size > 0 ? [...protocolSet].sort().join('+') : '1DH';
103
+ const aad = {
104
+ from: sender.aid,
105
+ from_device: sender.deviceId,
106
+ to: peerAid,
107
+ message_id: messageId,
108
+ timestamp,
109
+ suite: SUITE_NAME,
110
+ wrap_protocol: wrapProtocolStr,
111
+ };
112
+ // 3. 加密正文
113
+ const plaintextBytes = canonicalJson(payload);
114
+ const aadBytes = canonicalJson(aad);
115
+ const { ciphertext, tag } = await aesGcmEncrypt(masterKey, msgNonce, plaintextBytes, aadBytes);
116
+ // 4. sender_session keypair
117
+ const [senderSessionPriv, senderSessionPubDer] = await generateP256Keypair();
118
+ // wrap_salt = SHA256(canonical_aad || sender_session_pk_der || suite)[:16]
119
+ const suiteBytes = encoder.encode(SUITE_NAME);
120
+ const saltInput = new Uint8Array(aadBytes.length + senderSessionPubDer.length + suiteBytes.length);
121
+ saltInput.set(aadBytes, 0);
122
+ saltInput.set(senderSessionPubDer, aadBytes.length);
123
+ saltInput.set(suiteBytes, aadBytes.length + senderSessionPubDer.length);
124
+ const wrapSalt = (await sha256(saltInput)).subarray(0, 16);
125
+ // 5. 为每个 recipient wrap master_key
126
+ const allTargets = [
127
+ ...targetSet.targets,
128
+ ...(targetSet.auditRecipients ?? []),
129
+ ];
130
+ const recipientsRows = [];
131
+ for (const target of allTargets) {
132
+ recipientsRows.push(await wrapForRecipient(target, masterKey, senderSessionPriv, sender.ikPriv, wrapSalt, 'peer'));
133
+ }
134
+ // 6. sort + 7. digest
135
+ const sortedRows = sortRecipients(recipientsRows);
136
+ const digestHex = await computeRecipientsDigest(sortedRows);
137
+ // 8. sender_signature = ECDSA(ik_priv, ct || tag || aad || digest_bytes)
138
+ const digestBytes = hexToBytes(digestHex);
139
+ const signInput = new Uint8Array(ciphertext.length + tag.length + aadBytes.length + digestBytes.length);
140
+ let pos = 0;
141
+ signInput.set(ciphertext, pos);
142
+ pos += ciphertext.length;
143
+ signInput.set(tag, pos);
144
+ pos += tag.length;
145
+ signInput.set(aadBytes, pos);
146
+ pos += aadBytes.length;
147
+ signInput.set(digestBytes, pos);
148
+ const senderSig = await ecdsaSignRaw(sender.ikPriv, signInput);
149
+ // 9. cert fingerprint = "sha256:" + sha256(ik_pub_der).hex()[:16]
150
+ const certFpHash = bytesToHex(await sha256(sender.ikPubDer));
151
+ const certFp = `sha256:${certFpHash.substring(0, 16)}`;
152
+ // 10. 组装 envelope
153
+ const envelope = {
154
+ type: 'e2ee.p2p_encrypted',
155
+ version: 'v2',
156
+ suite: SUITE_NAME,
157
+ msg_type: 'original',
158
+ t_send: timestamp,
159
+ t_supplement: null,
160
+ t_server: null,
161
+ nonce: bytesToBase64(msgNonce),
162
+ ciphertext: bytesToBase64(ciphertext),
163
+ tag: bytesToBase64(tag),
164
+ sender_signature: bytesToBase64(senderSig),
165
+ sender_cert_fingerprint: certFp,
166
+ sender_session_pk: bytesToBase64(senderSessionPubDer),
167
+ recipients_digest: digestHex,
168
+ recipients: sortedRows,
169
+ aad,
170
+ };
171
+ // 11. protected_headers / context:HMAC 签名(与 V1 对齐),不进 AAD
172
+ // payload_type 自动注入 + value 转 string(与 Python _normalize_headers 对齐)
173
+ const normalizedHeaders = normalizeProtectedHeaders(opts.protectedHeaders, payload);
174
+ if (Object.keys(normalizedHeaders).length > 0) {
175
+ envelope.protected_headers = await withMetadataAuth(normalizedHeaders, masterKey, PROTECTED_HEADERS_DOMAIN);
176
+ }
177
+ const { context } = opts;
178
+ if (context && typeof context === 'object' && Object.keys(context).length > 0) {
179
+ envelope.context = await withMetadataAuth(context, masterKey, PROTECTED_CONTEXT_DOMAIN);
180
+ }
181
+ return envelope;
182
+ }
183
+ /**
184
+ * 规范化 protected_headers:value 转 string + 自动注入 payload_type。
185
+ * 与 Python `_normalize_headers` 对齐。
186
+ */
187
+ export function normalizeProtectedHeaders(headers, payload) {
188
+ const normalized = {};
189
+ if (headers && typeof headers === 'object') {
190
+ for (const [k, v] of Object.entries(headers)) {
191
+ if (k === '_auth')
192
+ continue;
193
+ const sv = v != null ? String(v) : '';
194
+ if (sv)
195
+ normalized[k] = sv;
196
+ }
197
+ }
198
+ // payload_type 自动注入(与 Python 对齐:payload.get("type") → protected_headers["payload_type"])
199
+ const payloadType = typeof payload?.type === 'string' ? payload.type : '';
200
+ if (payloadType && !('payload_type' in normalized)) {
201
+ normalized['payload_type'] = payloadType;
202
+ }
203
+ return normalized;
204
+ }
205
+ /**
206
+ * 为单个 recipient 生成 wrap 行([aid, device_id, role, key_source, fp,
207
+ * spk_id, wrap_nonce_b64, wrapped_key_b64])。
208
+ */
209
+ async function wrapForRecipient(target, masterKey, senderSessionPriv, senderMasterPriv, wrapSalt, defaultRole) {
210
+ const role = target.role ?? defaultRole;
211
+ const keySource = target.keySource ?? 'aid_master';
212
+ // fp = "sha256:" + sha256(ik_pk_der).hex()[:16]
213
+ const fpHash = bytesToHex(await sha256(target.ikPkDer));
214
+ const fp = `sha256:${fpHash.substring(0, 16)}`;
215
+ const wrapNonce = randomBytes(12);
216
+ let wrapKey;
217
+ if (target.spkPkDer
218
+ && (keySource === 'peer_device_prekey' || keySource === 'group_device_prekey')) {
219
+ wrapKey = await compute3DHWrap(senderSessionPriv, senderMasterPriv, target.ikPkDer, target.spkPkDer, wrapSalt);
220
+ }
221
+ else {
222
+ wrapKey = await compute1DHWrap(senderSessionPriv, target.ikPkDer, wrapSalt);
223
+ }
224
+ // wrapped_key = ciphertext (32B) + tag (16B) = 48B
225
+ const { ciphertext: wrappedCt, tag: wrappedTag } = await aesGcmEncrypt(wrapKey, wrapNonce, masterKey, new Uint8Array(0));
226
+ const wrappedKey = new Uint8Array(wrappedCt.length + wrappedTag.length);
227
+ wrappedKey.set(wrappedCt, 0);
228
+ wrappedKey.set(wrappedTag, wrappedCt.length);
229
+ return [
230
+ target.aid,
231
+ target.deviceId,
232
+ role,
233
+ keySource,
234
+ fp,
235
+ target.spkId ?? '',
236
+ bytesToBase64(wrapNonce),
237
+ bytesToBase64(wrappedKey),
238
+ ];
239
+ }
240
+ //# sourceMappingURL=encrypt-p2p.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt-p2p.js","sourceRoot":"","sources":["../../../src/v2/e2ee/encrypt-p2p.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AUN E2EE V2: e2ee 模块统一导出
3
+ */
4
+ export * from './types';
5
+ export { encryptP2PMessage } from './encrypt-p2p';
6
+ export { encryptGroupMessage } from './encrypt-group';
7
+ export { decryptMessage } from './decrypt';
8
+ export { withMetadataAuth, METADATA_KEY_DOMAIN, PROTECTED_HEADERS_DOMAIN, PROTECTED_CONTEXT_DOMAIN, } from './metadata-auth';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v2/e2ee/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AUN E2EE V2: e2ee 模块统一导出
3
+ */
4
+ export * from './types';
5
+ export { encryptP2PMessage } from './encrypt-p2p';
6
+ export { encryptGroupMessage } from './encrypt-group';
7
+ export { decryptMessage } from './decrypt';
8
+ export { withMetadataAuth, METADATA_KEY_DOMAIN, PROTECTED_HEADERS_DOMAIN, PROTECTED_CONTEXT_DOMAIN, } from './metadata-auth';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/v2/e2ee/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const METADATA_KEY_DOMAIN: Uint8Array<ArrayBuffer>;
2
+ export declare const PROTECTED_HEADERS_DOMAIN: Uint8Array<ArrayBuffer>;
3
+ export declare const PROTECTED_CONTEXT_DOMAIN: Uint8Array<ArrayBuffer>;
4
+ /**
5
+ * 对 metadata 对象签名,返回带 _auth 字段的新对象。
6
+ * 如果 metadata 去掉 _auth 后为空,返回空对象。
7
+ */
8
+ export declare function withMetadataAuth(metadata: Record<string, unknown>, key: Uint8Array, domain: Uint8Array): Promise<Record<string, unknown>>;
9
+ //# sourceMappingURL=metadata-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-auth.d.ts","sourceRoot":"","sources":["../../../src/v2/e2ee/metadata-auth.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,mBAAmB,yBAAiD,CAAC;AAClF,eAAO,MAAM,wBAAwB,yBAA6C,CAAC;AACnF,eAAO,MAAM,wBAAwB,yBAA6C,CAAC;AAqCnF;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,GAAG,EAAE,UAAU,EACf,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAclC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * AUN E2EE V2: Metadata HMAC 签名(protected_headers / context)
3
+ *
4
+ * 算法:两级 HMAC-SHA256 key 派生
5
+ * metadataKey = HMAC-SHA256(masterKey, METADATA_KEY_DOMAIN)
6
+ * signInput = domain + "\0" + canonicalJson(body)
7
+ * tag = HMAC-SHA256(metadataKey, signInput)
8
+ *
9
+ * 参考实现: python/src/aun_core/v2/e2ee/encrypt_p2p.py
10
+ */
11
+ import { canonicalJson } from '../crypto/canonical';
12
+ const encoder = new TextEncoder();
13
+ export const METADATA_KEY_DOMAIN = encoder.encode('aun-envelope-metadata-key-v1');
14
+ export const PROTECTED_HEADERS_DOMAIN = encoder.encode('aun-protected-headers-v1');
15
+ export const PROTECTED_CONTEXT_DOMAIN = encoder.encode('aun-protected-context-v1');
16
+ function bytesToBase64(b) {
17
+ let bin = '';
18
+ for (let i = 0; i < b.length; i++)
19
+ bin += String.fromCharCode(b[i]);
20
+ return btoa(bin);
21
+ }
22
+ async function hmacSha256(key, data) {
23
+ const hmacKey = await crypto.subtle.importKey('raw', key.slice().buffer, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
24
+ const sig = await crypto.subtle.sign('HMAC', hmacKey, data.slice().buffer);
25
+ return new Uint8Array(sig);
26
+ }
27
+ /**
28
+ * 计算 metadata auth tag。
29
+ */
30
+ async function metadataAuthTag(key, domain, body) {
31
+ const metadataKey = await hmacSha256(key, METADATA_KEY_DOMAIN);
32
+ const bodyBytes = canonicalJson(body);
33
+ const signInput = new Uint8Array(domain.length + 1 + bodyBytes.length);
34
+ signInput.set(domain, 0);
35
+ signInput[domain.length] = 0; // "\0" 分隔符
36
+ signInput.set(bodyBytes, domain.length + 1);
37
+ return hmacSha256(metadataKey, signInput);
38
+ }
39
+ /**
40
+ * 对 metadata 对象签名,返回带 _auth 字段的新对象。
41
+ * 如果 metadata 去掉 _auth 后为空,返回空对象。
42
+ */
43
+ export async function withMetadataAuth(metadata, key, domain) {
44
+ const body = {};
45
+ for (const [k, v] of Object.entries(metadata)) {
46
+ if (k !== '_auth')
47
+ body[k] = v;
48
+ }
49
+ if (Object.keys(body).length === 0)
50
+ return {};
51
+ const tag = await metadataAuthTag(key, domain, body);
52
+ return {
53
+ ...body,
54
+ _auth: {
55
+ alg: 'HMAC-SHA256',
56
+ tag: bytesToBase64(tag),
57
+ },
58
+ };
59
+ }
60
+ //# sourceMappingURL=metadata-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-auth.js","sourceRoot":"","sources":["../../../src/v2/e2ee/metadata-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * AUN E2EE V2: 加解密引擎类型定义
3
+ *
4
+ * 与 Python `aun_core.v2.e2ee.encrypt_p2p` / `encrypt_group` / `decrypt` 对齐。
5
+ */
6
+ export declare const SUITE_NAME: "P256_HKDF_SHA256_AES_256_GCM";
7
+ /** 发送方身份。 */
8
+ export interface Sender {
9
+ /** 发送方 AID。 */
10
+ aid: string;
11
+ /** 发送方 device_id。 */
12
+ deviceId: string;
13
+ /** 32 字节 P-256 私钥标量(AID 主私钥)。 */
14
+ ikPriv: Uint8Array;
15
+ /** SPKI DER 编码的公钥(用于签名指纹计算)。 */
16
+ ikPubDer: Uint8Array;
17
+ }
18
+ /** 接收方目标设备。 */
19
+ export interface Target {
20
+ aid: string;
21
+ deviceId: string;
22
+ /** "peer" | "member" | "self_sync" | "audit" 等。 */
23
+ role: string;
24
+ /** "peer_device_prekey" | "group_device_prekey" | "aid_master"。 */
25
+ keySource: string;
26
+ /** 接收方 IK 公钥(DER SPKI)。 */
27
+ ikPkDer: Uint8Array;
28
+ /** 接收方 SPK 公钥(DER SPKI);undefined 表示走 1DH 路径。 */
29
+ spkPkDer?: Uint8Array;
30
+ /** SPK 标识;3DH 时为非空字符串,1DH 时为空串/未定义。 */
31
+ spkId?: string;
32
+ }
33
+ /** 接收方集合(P2P)。 */
34
+ export interface TargetSet {
35
+ /** 普通接收设备。 */
36
+ targets: Target[];
37
+ /** 监管方设备(可选)。 */
38
+ auditRecipients?: Target[];
39
+ }
40
+ /** 加密可选参数。 */
41
+ export interface EncryptOptions {
42
+ /** 消息 ID;不传则自动生成 `m-{uuid4 hex}`。 */
43
+ messageId?: string;
44
+ /** 时间戳(毫秒);不传则用 Date.now()。 */
45
+ timestamp?: number;
46
+ /** 受保护头部(HMAC 签名后附加到 envelope.protected_headers)。 */
47
+ protectedHeaders?: Record<string, unknown>;
48
+ /** 上下文元数据(HMAC 签名后附加到 envelope.context)。 */
49
+ context?: Record<string, unknown>;
50
+ }
51
+ /** Group AAD 中的 state_commitment 子结构。 */
52
+ export interface StateCommitmentAAD {
53
+ state_version: number;
54
+ state_hash: string;
55
+ state_chain: string;
56
+ }
57
+ //# sourceMappingURL=types.d.ts.map