@meshline/sdk 0.0.0-stage → 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +43 -2
- package/dist/channels/repository.d.ts +73 -0
- package/dist/channels/repository.d.ts.map +1 -0
- package/dist/channels/repository.js +367 -0
- package/dist/channels/repository.js.map +1 -0
- package/dist/client/account-operations.d.ts +41 -0
- package/dist/client/account-operations.d.ts.map +1 -0
- package/dist/client/account-operations.js +304 -0
- package/dist/client/account-operations.js.map +1 -0
- package/dist/client/conversations.d.ts +36 -0
- package/dist/client/conversations.d.ts.map +1 -0
- package/dist/client/conversations.js +144 -0
- package/dist/client/conversations.js.map +1 -0
- package/dist/client.d.ts +53 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +162 -0
- package/dist/client.js.map +1 -0
- package/dist/components/account.d.ts +38 -0
- package/dist/components/account.d.ts.map +1 -0
- package/dist/components/account.js +243 -0
- package/dist/components/account.js.map +1 -0
- package/dist/components/channel.d.ts +78 -0
- package/dist/components/channel.d.ts.map +1 -0
- package/dist/components/channel.js +475 -0
- package/dist/components/channel.js.map +1 -0
- package/dist/components/component.d.ts +49 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/component.js +194 -0
- package/dist/components/component.js.map +1 -0
- package/dist/components/device.d.ts +60 -0
- package/dist/components/device.d.ts.map +1 -0
- package/dist/components/device.js +648 -0
- package/dist/components/device.js.map +1 -0
- package/dist/components/group.d.ts +141 -0
- package/dist/components/group.d.ts.map +1 -0
- package/dist/components/group.js +933 -0
- package/dist/components/group.js.map +1 -0
- package/dist/components/message.d.ts +63 -0
- package/dist/components/message.d.ts.map +1 -0
- package/dist/components/message.js +439 -0
- package/dist/components/message.js.map +1 -0
- package/dist/components/profile.d.ts +37 -0
- package/dist/components/profile.d.ts.map +1 -0
- package/dist/components/profile.js +232 -0
- package/dist/components/profile.js.map +1 -0
- package/dist/crypto/groups.d.ts +56 -0
- package/dist/crypto/groups.d.ts.map +1 -0
- package/dist/crypto/groups.js +163 -0
- package/dist/crypto/groups.js.map +1 -0
- package/dist/crypto/messages.d.ts +52 -0
- package/dist/crypto/messages.d.ts.map +1 -0
- package/dist/crypto/messages.js +180 -0
- package/dist/crypto/messages.js.map +1 -0
- package/dist/crypto/primitives.d.ts +30 -0
- package/dist/crypto/primitives.d.ts.map +1 -0
- package/dist/crypto/primitives.js +102 -0
- package/dist/crypto/primitives.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -0
- package/dist/groups/account-sync.d.ts +28 -0
- package/dist/groups/account-sync.d.ts.map +1 -0
- package/dist/groups/account-sync.js +235 -0
- package/dist/groups/account-sync.js.map +1 -0
- package/dist/groups/messages.d.ts +39 -0
- package/dist/groups/messages.d.ts.map +1 -0
- package/dist/groups/messages.js +141 -0
- package/dist/groups/messages.js.map +1 -0
- package/dist/groups/operations.d.ts +57 -0
- package/dist/groups/operations.d.ts.map +1 -0
- package/dist/groups/operations.js +225 -0
- package/dist/groups/operations.js.map +1 -0
- package/dist/groups/repository.d.ts +56 -0
- package/dist/groups/repository.d.ts.map +1 -0
- package/dist/groups/repository.js +254 -0
- package/dist/groups/repository.js.map +1 -0
- package/dist/groups/secrets.d.ts +67 -0
- package/dist/groups/secrets.d.ts.map +1 -0
- package/dist/groups/secrets.js +452 -0
- package/dist/groups/secrets.js.map +1 -0
- package/dist/groups/state.d.ts +39 -0
- package/dist/groups/state.d.ts.map +1 -0
- package/dist/groups/state.js +201 -0
- package/dist/groups/state.js.map +1 -0
- package/dist/identity/identifiers.d.ts +9 -0
- package/dist/identity/identifiers.d.ts.map +1 -0
- package/dist/identity/identifiers.js +37 -0
- package/dist/identity/identifiers.js.map +1 -0
- package/dist/identity/neo.d.ts +11 -0
- package/dist/identity/neo.d.ts.map +1 -0
- package/dist/identity/neo.js +77 -0
- package/dist/identity/neo.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions.d.ts +31 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +2 -0
- package/dist/interactions.js.map +1 -0
- package/dist/messages/account-sender.d.ts +9 -0
- package/dist/messages/account-sender.d.ts.map +1 -0
- package/dist/messages/account-sender.js +46 -0
- package/dist/messages/account-sender.js.map +1 -0
- package/dist/messages/contacts.d.ts +103 -0
- package/dist/messages/contacts.d.ts.map +1 -0
- package/dist/messages/contacts.js +525 -0
- package/dist/messages/contacts.js.map +1 -0
- package/dist/messages/outbox.d.ts +66 -0
- package/dist/messages/outbox.d.ts.map +1 -0
- package/dist/messages/outbox.js +167 -0
- package/dist/messages/outbox.js.map +1 -0
- package/dist/messages/receiver.d.ts +35 -0
- package/dist/messages/receiver.d.ts.map +1 -0
- package/dist/messages/receiver.js +113 -0
- package/dist/messages/receiver.js.map +1 -0
- package/dist/messages/repository.d.ts +89 -0
- package/dist/messages/repository.d.ts.map +1 -0
- package/dist/messages/repository.js +295 -0
- package/dist/messages/repository.js.map +1 -0
- package/dist/models/authentication.d.ts +37 -0
- package/dist/models/authentication.d.ts.map +1 -0
- package/dist/models/authentication.js +53 -0
- package/dist/models/authentication.js.map +1 -0
- package/dist/models/channels.d.ts +141 -0
- package/dist/models/channels.d.ts.map +1 -0
- package/dist/models/channels.js +258 -0
- package/dist/models/channels.js.map +1 -0
- package/dist/models/contacts.d.ts +68 -0
- package/dist/models/contacts.d.ts.map +1 -0
- package/dist/models/contacts.js +186 -0
- package/dist/models/contacts.js.map +1 -0
- package/dist/models/content.d.ts +37 -0
- package/dist/models/content.d.ts.map +1 -0
- package/dist/models/content.js +137 -0
- package/dist/models/content.js.map +1 -0
- package/dist/models/device-state.d.ts +8 -0
- package/dist/models/device-state.d.ts.map +1 -0
- package/dist/models/device-state.js +22 -0
- package/dist/models/device-state.js.map +1 -0
- package/dist/models/group-admission.d.ts +111 -0
- package/dist/models/group-admission.d.ts.map +1 -0
- package/dist/models/group-admission.js +153 -0
- package/dist/models/group-admission.js.map +1 -0
- package/dist/models/group-keys.d.ts +30 -0
- package/dist/models/group-keys.d.ts.map +1 -0
- package/dist/models/group-keys.js +52 -0
- package/dist/models/group-keys.js.map +1 -0
- package/dist/models/group-management.d.ts +190 -0
- package/dist/models/group-management.d.ts.map +1 -0
- package/dist/models/group-management.js +263 -0
- package/dist/models/group-management.js.map +1 -0
- package/dist/models/groups.d.ts +81 -0
- package/dist/models/groups.d.ts.map +1 -0
- package/dist/models/groups.js +127 -0
- package/dist/models/groups.js.map +1 -0
- package/dist/models/identity.d.ts +47 -0
- package/dist/models/identity.d.ts.map +1 -0
- package/dist/models/identity.js +136 -0
- package/dist/models/identity.js.map +1 -0
- package/dist/models/messages.d.ts +104 -0
- package/dist/models/messages.d.ts.map +1 -0
- package/dist/models/messages.js +168 -0
- package/dist/models/messages.js.map +1 -0
- package/dist/models/profile.d.ts +24 -0
- package/dist/models/profile.d.ts.map +1 -0
- package/dist/models/profile.js +47 -0
- package/dist/models/profile.js.map +1 -0
- package/dist/models/relay.d.ts +39 -0
- package/dist/models/relay.d.ts.map +1 -0
- package/dist/models/relay.js +160 -0
- package/dist/models/relay.js.map +1 -0
- package/dist/protocol/codec.d.ts +36 -0
- package/dist/protocol/codec.d.ts.map +1 -0
- package/dist/protocol/codec.js +144 -0
- package/dist/protocol/codec.js.map +1 -0
- package/dist/protocol/context.d.ts +14 -0
- package/dist/protocol/context.d.ts.map +1 -0
- package/dist/protocol/context.js +43 -0
- package/dist/protocol/context.js.map +1 -0
- package/dist/protocol/encoding.d.ts +15 -0
- package/dist/protocol/encoding.d.ts.map +1 -0
- package/dist/protocol/encoding.js +133 -0
- package/dist/protocol/encoding.js.map +1 -0
- package/dist/protocol/json.d.ts +16 -0
- package/dist/protocol/json.d.ts.map +1 -0
- package/dist/protocol/json.js +172 -0
- package/dist/protocol/json.js.map +1 -0
- package/dist/protocol/validation.d.ts +4 -0
- package/dist/protocol/validation.d.ts.map +1 -0
- package/dist/protocol/validation.js +18 -0
- package/dist/protocol/validation.js.map +1 -0
- package/dist/runtime/abort.d.ts +6 -0
- package/dist/runtime/abort.d.ts.map +1 -0
- package/dist/runtime/abort.js +32 -0
- package/dist/runtime/abort.js.map +1 -0
- package/dist/runtime/async-gate.d.ts +6 -0
- package/dist/runtime/async-gate.d.ts.map +1 -0
- package/dist/runtime/async-gate.js +15 -0
- package/dist/runtime/async-gate.js.map +1 -0
- package/dist/runtime/async-pulse.d.ts +7 -0
- package/dist/runtime/async-pulse.d.ts.map +1 -0
- package/dist/runtime/async-pulse.js +23 -0
- package/dist/runtime/async-pulse.js.map +1 -0
- package/dist/runtime/clock.d.ts +16 -0
- package/dist/runtime/clock.d.ts.map +1 -0
- package/dist/runtime/clock.js +62 -0
- package/dist/runtime/clock.js.map +1 -0
- package/dist/runtime/events.d.ts +11 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/runtime/events.js +45 -0
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/url.d.ts +3 -0
- package/dist/runtime/url.d.ts.map +1 -0
- package/dist/runtime/url.js +23 -0
- package/dist/runtime/url.js.map +1 -0
- package/dist/storage/signed-request.d.ts +14 -0
- package/dist/storage/signed-request.d.ts.map +1 -0
- package/dist/storage/signed-request.js +26 -0
- package/dist/storage/signed-request.js.map +1 -0
- package/dist/storage/store.d.ts +58 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +52 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/transaction.d.ts +7 -0
- package/dist/storage/transaction.d.ts.map +1 -0
- package/dist/storage/transaction.js +22 -0
- package/dist/storage/transaction.js.map +1 -0
- package/dist/transport/client.d.ts +61 -0
- package/dist/transport/client.d.ts.map +1 -0
- package/dist/transport/client.js +392 -0
- package/dist/transport/client.js.map +1 -0
- package/dist/transport/discovery.d.ts +19 -0
- package/dist/transport/discovery.d.ts.map +1 -0
- package/dist/transport/discovery.js +75 -0
- package/dist/transport/discovery.js.map +1 -0
- package/dist/transport/endpoint.d.ts +6 -0
- package/dist/transport/endpoint.d.ts.map +1 -0
- package/dist/transport/endpoint.js +35 -0
- package/dist/transport/endpoint.js.map +1 -0
- package/dist/transport/http.d.ts +52 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +128 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/pool.d.ts +31 -0
- package/dist/transport/pool.d.ts.map +1 -0
- package/dist/transport/pool.js +137 -0
- package/dist/transport/pool.js.map +1 -0
- package/dist/transport/relay-error.d.ts +23 -0
- package/dist/transport/relay-error.d.ts.map +1 -0
- package/dist/transport/relay-error.js +47 -0
- package/dist/transport/relay-error.js.map +1 -0
- package/dist/transport/rpc.d.ts +31 -0
- package/dist/transport/rpc.d.ts.map +1 -0
- package/dist/transport/rpc.js +56 -0
- package/dist/transport/rpc.js.map +1 -0
- package/dist/transport/session.d.ts +49 -0
- package/dist/transport/session.d.ts.map +1 -0
- package/dist/transport/session.js +169 -0
- package/dist/transport/session.js.map +1 -0
- package/dist/transport/socket.d.ts +55 -0
- package/dist/transport/socket.d.ts.map +1 -0
- package/dist/transport/socket.js +266 -0
- package/dist/transport/socket.js.map +1 -0
- package/dist/transport/subscription.d.ts +36 -0
- package/dist/transport/subscription.d.ts.map +1 -0
- package/dist/transport/subscription.js +169 -0
- package/dist/transport/subscription.js.map +1 -0
- package/package.json +35 -4
- package/src/channels/repository.ts +244 -0
- package/src/client/account-operations.ts +183 -0
- package/src/client/conversations.ts +95 -0
- package/src/client.ts +108 -0
- package/src/components/account.ts +206 -0
- package/src/components/channel.ts +253 -0
- package/src/components/component.ts +151 -0
- package/src/components/device.ts +455 -0
- package/src/components/group.ts +546 -0
- package/src/components/message.ts +253 -0
- package/src/components/profile.ts +179 -0
- package/src/crypto/groups.ts +107 -0
- package/src/crypto/messages.ts +129 -0
- package/src/crypto/primitives.ts +103 -0
- package/src/errors.ts +13 -0
- package/src/groups/account-sync.ts +144 -0
- package/src/groups/messages.ts +89 -0
- package/src/groups/operations.ts +145 -0
- package/src/groups/repository.ts +161 -0
- package/src/groups/secrets.ts +256 -0
- package/src/groups/state.ts +138 -0
- package/src/identity/identifiers.ts +41 -0
- package/src/identity/neo.ts +72 -0
- package/src/index.ts +52 -0
- package/src/interactions.ts +35 -0
- package/src/messages/account-sender.ts +33 -0
- package/src/messages/contacts.ts +379 -0
- package/src/messages/outbox.ts +152 -0
- package/src/messages/receiver.ts +86 -0
- package/src/messages/repository.ts +230 -0
- package/src/models/authentication.ts +63 -0
- package/src/models/channels.ts +155 -0
- package/src/models/contacts.ts +141 -0
- package/src/models/content.ts +105 -0
- package/src/models/device-state.ts +18 -0
- package/src/models/group-admission.ts +110 -0
- package/src/models/group-keys.ts +34 -0
- package/src/models/group-management.ts +182 -0
- package/src/models/groups.ts +100 -0
- package/src/models/identity.ts +164 -0
- package/src/models/messages.ts +139 -0
- package/src/models/profile.ts +46 -0
- package/src/models/relay.ts +151 -0
- package/src/protocol/codec.ts +144 -0
- package/src/protocol/context.ts +39 -0
- package/src/protocol/encoding.ts +106 -0
- package/src/protocol/json.ts +140 -0
- package/src/protocol/validation.ts +13 -0
- package/src/runtime/abort.ts +27 -0
- package/src/runtime/async-gate.ts +16 -0
- package/src/runtime/async-pulse.ts +20 -0
- package/src/runtime/clock.ts +63 -0
- package/src/runtime/events.ts +31 -0
- package/src/runtime/url.ts +17 -0
- package/src/storage/signed-request.ts +26 -0
- package/src/storage/store.ts +90 -0
- package/src/storage/transaction.ts +17 -0
- package/src/transport/client.ts +328 -0
- package/src/transport/discovery.ts +64 -0
- package/src/transport/endpoint.ts +32 -0
- package/src/transport/http.ts +129 -0
- package/src/transport/pool.ts +115 -0
- package/src/transport/relay-error.ts +46 -0
- package/src/transport/rpc.ts +56 -0
- package/src/transport/session.ts +154 -0
- package/src/transport/socket.ts +248 -0
- package/src/transport/subscription.ts +117 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { ProtocolError } from '../errors.js';
|
|
2
|
+
import { validateIdentifier } from '../identity/identifiers.js';
|
|
3
|
+
import { validateAccountId } from '../identity/neo.js';
|
|
4
|
+
import { contactAuthorizationCodec } from '../models/contacts.js';
|
|
5
|
+
import { certificateId, deviceCertificateCodec, validateCertificate } from '../models/identity.js';
|
|
6
|
+
import { messageEnvelopeCodec, messageEnvelopeInput, messageKeyBoxCodec, messagePayloadCodec, validateMessageKeyBox, validateMessageSendRequest, verifyMessageEnvelope } from '../models/messages.js';
|
|
7
|
+
import { signingInput } from '../protocol/context.js';
|
|
8
|
+
import { concatBytes, encodeBase64Url, encodeUtf8 } from '../protocol/encoding.js';
|
|
9
|
+
import { canonicalBytes, parseJson, requireSafeInteger } from '../protocol/json.js';
|
|
10
|
+
import { throwIfAborted } from '../runtime/clock.js';
|
|
11
|
+
import { agreeKey, decryptAes, deriveKey, encryptAes, encryptionPublicKey, requireLength, sha256, systemRandom } from './primitives.js';
|
|
12
|
+
const keyBoxSalt = sha256(encodeUtf8('Meshline/keybox-salt/v1'));
|
|
13
|
+
function validateHeader(value) {
|
|
14
|
+
validateIdentifier('message', value.messageId);
|
|
15
|
+
validateIdentifier('device', value.fromDeviceId);
|
|
16
|
+
validateAccountId(value.from);
|
|
17
|
+
validateAccountId(value.to);
|
|
18
|
+
requireSafeInteger(value.createdAt, 0);
|
|
19
|
+
}
|
|
20
|
+
/** Fixed protocol projection; envelope extensions are signed but are not part of payload AAD. */
|
|
21
|
+
export function messageAad(value, context) {
|
|
22
|
+
validateHeader(value);
|
|
23
|
+
return signingInput({ $type: 'meshline.message.aad', message_id: value.messageId, created_at: value.createdAt, from: value.from, from_device_id: value.fromDeviceId, to: value.to }, context);
|
|
24
|
+
}
|
|
25
|
+
/** Fixed projection shared by HKDF info and AES-GCM key wrapping AAD. */
|
|
26
|
+
export function messageKeyBoxAad(value, box, account, context) {
|
|
27
|
+
validateHeader(value);
|
|
28
|
+
validateAccountId(account);
|
|
29
|
+
validateIdentifier('device', box.deviceId);
|
|
30
|
+
requireLength(box.enc, 32, 'Ephemeral public key');
|
|
31
|
+
if (account !== value.from && account !== value.to)
|
|
32
|
+
throw new ProtocolError('invalid_identity', 'Key box account must be a message participant.');
|
|
33
|
+
if (box.alg !== 'X25519-HKDF-SHA256-AES256GCM' || value.payload.alg !== 'AES-256-GCM')
|
|
34
|
+
throw new ProtocolError('unsupported_algorithm', 'Unsupported message key wrapping algorithms.');
|
|
35
|
+
return signingInput({ $type: 'meshline.message.key_box.aad', alg: box.alg, payload_alg: value.payload.alg, message_id: value.messageId,
|
|
36
|
+
created_at: value.createdAt, from: value.from, from_device_id: value.fromDeviceId, account, device_id: box.deviceId, enc: encodeBase64Url(box.enc) }, context);
|
|
37
|
+
}
|
|
38
|
+
/** Builds immutable delivery material. Device lists must come from current authoritative states, checked by the calling manager. */
|
|
39
|
+
export async function encryptMessage(options) {
|
|
40
|
+
const { context, signer, messageId, createdAt, recipient, signal } = options;
|
|
41
|
+
throwIfAborted(signal);
|
|
42
|
+
const random = options.random ?? systemRandom;
|
|
43
|
+
const certificate = deviceCertificateCodec.decode(deviceCertificateCodec.encode(signer.certificate));
|
|
44
|
+
validateCertificate(certificate, context);
|
|
45
|
+
const senderId = certificateId(certificate, context);
|
|
46
|
+
const recipients = copyDevices(options.recipientDevices, recipient, createdAt, context);
|
|
47
|
+
const senders = recipient === certificate.account ? undefined : copyDevices(options.senderDevices ?? [certificate], certificate.account, createdAt, context);
|
|
48
|
+
const authorization = options.authorization === undefined ? undefined : contactAuthorizationCodec.decode(contactAuthorizationCodec.encode(options.authorization));
|
|
49
|
+
if (createdAt < certificate.notBefore || createdAt >= certificate.expiresAt)
|
|
50
|
+
throw new ProtocolError('unauthorized_device', 'Message signer certificate is outside its validity window.');
|
|
51
|
+
if (recipient === certificate.account && (authorization !== undefined || options.senderDevices !== undefined))
|
|
52
|
+
throw new ProtocolError('invalid_self_delivery', 'Self messages must omit sender devices and authorization.');
|
|
53
|
+
const header = { messageId, createdAt, from: certificate.account, fromDeviceId: senderId, to: recipient };
|
|
54
|
+
const aad = messageAad(header, context);
|
|
55
|
+
const plaintext = canonicalBytes(messagePayloadCodec.decode(options.payload));
|
|
56
|
+
let contentKey;
|
|
57
|
+
try {
|
|
58
|
+
contentKey = random.bytes(32);
|
|
59
|
+
requireLength(contentKey, 32, 'Content key');
|
|
60
|
+
const nonce = random.bytes(12);
|
|
61
|
+
requireLength(nonce, 12, 'Payload nonce');
|
|
62
|
+
let envelope = { ...header, payload: { alg: 'AES-256-GCM', nonce, ciphertext: encryptAes(contentKey, nonce, plaintext, aad) }, deviceSignature: new Uint8Array(64) };
|
|
63
|
+
envelope = { ...envelope, deviceSignature: (await signer.sign(messageEnvelopeInput(envelope, context), signal)).slice() };
|
|
64
|
+
throwIfAborted(signal);
|
|
65
|
+
if (certificateId(signer.certificate, context) !== senderId)
|
|
66
|
+
throw new ProtocolError('invalid_identity', 'Device signer changed identity during message signing.');
|
|
67
|
+
verifyMessageEnvelope(envelope, certificate, context);
|
|
68
|
+
const recipientBoxes = sealKeys(envelope, recipient, recipients, contentKey, context, random);
|
|
69
|
+
const senderBoxes = senders && sealKeys(envelope, certificate.account, senders, contentKey, context, random);
|
|
70
|
+
const result = { envelope, recipientBoxes, ...(senderBoxes ? { senderBoxes } : {}), ...(authorization ? { authorization } : {}) };
|
|
71
|
+
validateMessageSendRequest(result, createdAt);
|
|
72
|
+
throwIfAborted(signal);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
contentKey?.fill(0);
|
|
77
|
+
plaintext.fill(0);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function copyDevices(values, account, now, context) {
|
|
81
|
+
if (values.length < 1 || values.length > 8)
|
|
82
|
+
throw new ProtocolError('invalid_size', 'Message encryption requires between one and eight devices per account.');
|
|
83
|
+
const ids = new Set();
|
|
84
|
+
return values.map(value => {
|
|
85
|
+
const copy = deviceCertificateCodec.decode(deviceCertificateCodec.encode(value));
|
|
86
|
+
validateCertificate(copy, context);
|
|
87
|
+
if (copy.account !== account || copy.notBefore > now || now >= copy.expiresAt)
|
|
88
|
+
throw new ProtocolError('unauthorized_device', 'Encryption certificate belongs to another account or is outside its validity window.');
|
|
89
|
+
const id = certificateId(copy, context);
|
|
90
|
+
if (ids.has(id))
|
|
91
|
+
throw new ProtocolError('duplicate_device', 'Duplicate encryption device.');
|
|
92
|
+
ids.add(id);
|
|
93
|
+
return copy;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function sealKeys(envelope, account, certificates, contentKey, context, random) {
|
|
97
|
+
return certificates.map(certificate => {
|
|
98
|
+
let ephemeral;
|
|
99
|
+
let shared;
|
|
100
|
+
let wrappingKey;
|
|
101
|
+
try {
|
|
102
|
+
ephemeral = random.bytes(32);
|
|
103
|
+
requireLength(ephemeral, 32, 'Ephemeral private key');
|
|
104
|
+
const box = { deviceId: certificateId(certificate, context), alg: 'X25519-HKDF-SHA256-AES256GCM', enc: encryptionPublicKey(ephemeral) };
|
|
105
|
+
shared = agreeKey(ephemeral, certificate.encryptionPublicKey);
|
|
106
|
+
const aad = messageKeyBoxAad(envelope, box, account, context);
|
|
107
|
+
wrappingKey = deriveKey(shared, keyBoxSalt, aad);
|
|
108
|
+
const nonce = random.bytes(12);
|
|
109
|
+
requireLength(nonce, 12, 'Key box nonce');
|
|
110
|
+
return { ...box, sealedKey: concatBytes(nonce, encryptAes(wrappingKey, nonce, contentKey, aad)) };
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
ephemeral?.fill(0);
|
|
114
|
+
shared?.fill(0);
|
|
115
|
+
wrappingKey?.fill(0);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/** Local key access failures are retryable reception failures, never grounds for discarding a remote message. */
|
|
120
|
+
export class MessageKeyAccessError extends Error {
|
|
121
|
+
name = 'MessageKeyAccessError';
|
|
122
|
+
}
|
|
123
|
+
/** Verifies signature before key agreement and returns no plaintext until both GCM authentications and complete JSON validation pass. */
|
|
124
|
+
export async function decryptMessage(options) {
|
|
125
|
+
const { context, receiver, signal } = options;
|
|
126
|
+
throwIfAborted(signal);
|
|
127
|
+
const envelope = messageEnvelopeCodec.decode(messageEnvelopeCodec.encode(options.envelope));
|
|
128
|
+
const box = messageKeyBoxCodec.decode(messageKeyBoxCodec.encode(options.keyBox));
|
|
129
|
+
const sender = deviceCertificateCodec.decode(deviceCertificateCodec.encode(options.sender));
|
|
130
|
+
verifyMessageEnvelope(envelope, sender, context);
|
|
131
|
+
validateMessageKeyBox(box);
|
|
132
|
+
// Public low-order-point validation distinguishes malformed remote input from failures opening local protected keys.
|
|
133
|
+
const probe = agreeKey(new Uint8Array(32).fill(1), box.enc);
|
|
134
|
+
probe.fill(0);
|
|
135
|
+
let local;
|
|
136
|
+
try {
|
|
137
|
+
local = deviceCertificateCodec.decode(deviceCertificateCodec.encode(receiver.certificate));
|
|
138
|
+
validateCertificate(local, context);
|
|
139
|
+
}
|
|
140
|
+
catch (cause) {
|
|
141
|
+
throw new MessageKeyAccessError('Local device certificate is unavailable or invalid.', { cause });
|
|
142
|
+
}
|
|
143
|
+
const localId = certificateId(local, context);
|
|
144
|
+
if (local.account !== envelope.from && local.account !== envelope.to || box.deviceId !== localId)
|
|
145
|
+
throw new ProtocolError('invalid_identity', 'Message or key box belongs to another account or device.');
|
|
146
|
+
let shared;
|
|
147
|
+
let wrappingKey;
|
|
148
|
+
let contentKey;
|
|
149
|
+
let plaintext;
|
|
150
|
+
try {
|
|
151
|
+
try {
|
|
152
|
+
shared = await receiver.deriveSharedSecret(box.enc.slice(), signal);
|
|
153
|
+
throwIfAborted(signal);
|
|
154
|
+
if (certificateId(receiver.certificate, context) !== localId)
|
|
155
|
+
throw new Error('Decrypting device changed identity during key agreement.');
|
|
156
|
+
requireLength(shared, 32, 'X25519 shared secret');
|
|
157
|
+
if (shared.every(byte => byte === 0))
|
|
158
|
+
throw new MessageKeyAccessError('Device key agreement produced an all-zero shared secret.');
|
|
159
|
+
}
|
|
160
|
+
catch (cause) {
|
|
161
|
+
throwIfAborted(signal);
|
|
162
|
+
if (cause instanceof MessageKeyAccessError)
|
|
163
|
+
throw cause;
|
|
164
|
+
throw new MessageKeyAccessError('Local device key agreement failed.', { cause });
|
|
165
|
+
}
|
|
166
|
+
const aad = messageKeyBoxAad(envelope, box, local.account, context);
|
|
167
|
+
wrappingKey = deriveKey(shared, keyBoxSalt, aad);
|
|
168
|
+
contentKey = decryptAes(wrappingKey, box.sealedKey.subarray(0, 12), box.sealedKey.subarray(12), aad);
|
|
169
|
+
requireLength(contentKey, 32, 'Content key');
|
|
170
|
+
plaintext = decryptAes(contentKey, envelope.payload.nonce, envelope.payload.ciphertext, messageAad(envelope, context));
|
|
171
|
+
return messagePayloadCodec.decode(parseJson(plaintext));
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
shared?.fill(0);
|
|
175
|
+
wrappingKey?.fill(0);
|
|
176
|
+
contentKey?.fill(0);
|
|
177
|
+
plaintext?.fill(0);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/crypto/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAA6B,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,mBAAmB,EAA0B,MAAM,uBAAuB,CAAC;AAC3H,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,qBAAqB,EAC/F,MAAM,uBAAuB,CAAC;AACrG,OAAO,EAAE,YAAY,EAAuB,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,kBAAkB,EAAmB,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAqB,MAAM,iBAAiB,CAAC;AAE3J,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAEjE,SAAS,cAAc,CAAC,KAAoB;IACxC,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAAC,kBAAkB,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AACzM,CAAC;AACD,iGAAiG;AACjG,MAAM,UAAU,UAAU,CAAC,KAAoB,EAAE,OAAuB;IACpE,cAAc,CAAC,KAAK,CAAC,CAAC;IACtB,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;AAClM,CAAC;AACD,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAqE,EAAE,GAAoD,EAAE,OAAe,EAAE,OAAuB;IAClM,cAAc,CAAC,KAAK,CAAC,CAAC;IAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAAC,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAClJ,IAAI,OAAO,KAAK,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,gDAAgD,CAAC,CAAC;IAClJ,IAAI,GAAG,CAAC,GAAG,KAAK,8BAA8B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,aAAa;QAAE,MAAM,IAAI,aAAa,CAAC,uBAAuB,EAAE,8CAA8C,CAAC,CAAC;IACxL,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS;QAClI,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACvK,CAAC;AAMD,oIAAoI;AACpI,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IAC/D,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACrG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC;IAC9C,MAAM,WAAW,GAAG,sBAAsB,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAChJ,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,SAAS,KAAK,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7J,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAClK,IAAI,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,SAAS,IAAI,WAAW,CAAC,SAAS;QAAE,MAAM,IAAI,aAAa,CAAC,qBAAqB,EAAE,4DAA4D,CAAC,CAAC;IAC1L,IAAI,SAAS,KAAK,WAAW,CAAC,OAAO,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,uBAAuB,EAAE,2DAA2D,CAAC,CAAC;IAC7N,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IAC1G,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,cAAc,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9E,IAAI,UAAkC,CAAC;IACvC,IAAI,CAAC;QACD,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAAC,aAAa,CAAC,UAAU,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1E,IAAI,QAAQ,GAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,eAAe,EAAE,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACtL,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,eAAe,EAAE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAC1H,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,QAAQ;YAAE,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,wDAAwD,CAAC,CAAC;QACnK,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9F,MAAM,WAAW,GAAG,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7G,MAAM,MAAM,GAAuB,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtJ,0BAA0B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,MAAM,CAAC;IACzF,CAAC;YAAS,CAAC;QAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;AACzD,CAAC;AACD,SAAS,WAAW,CAAC,MAAoC,EAAE,OAAe,EAAE,GAAW,EAAE,OAAuB;IAC5G,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,cAAc,EAAE,wEAAwE,CAAC,CAAC;IAC9J,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACtB,MAAM,IAAI,GAAG,sBAAsB,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrH,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,aAAa,CAAC,qBAAqB,EAAE,sFAAsF,CAAC,CAAC;QACtN,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAAC,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IACpK,CAAC,CAAC,CAAC;AACP,CAAC;AACD,SAAS,QAAQ,CAAC,QAAyB,EAAE,OAAe,EAAE,YAA0C,EAAE,UAAsB,EAAE,OAAuB,EAAE,MAAoB;IAC3K,OAAO,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;QAClC,IAAI,SAAiC,CAAC;QAAC,IAAI,MAA8B,CAAC;QAAC,IAAI,WAAmC,CAAC;QACnH,IAAI,CAAC;YACD,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAAC,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAC;YACpF,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,8BAA8B,EAAE,GAAG,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACxI,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,mBAAmB,CAAC,CAAC;YAC9D,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAAC,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;YAChH,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC;YAC1E,OAAO,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACtG,CAAC;gBAAS,CAAC;YAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACP,CAAC;AAGD,iHAAiH;AACjH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAAqB,IAAI,GAAG,uBAAuB,CAAC;CAAE;AAKtG,yIAAyI;AACzI,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IAC/D,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5F,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC7E,qHAAqH;IACrH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAwB,CAAC;IAC7B,IAAI,CAAC;QAAC,KAAK,GAAG,sBAAsB,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC;IACxI,OAAO,KAAK,EAAE,CAAC;QAAC,MAAM,IAAI,qBAAqB,CAAC,qDAAqD,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAAC,CAAC;IACpH,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,EAAE,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;QAAE,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,0DAA0D,CAAC,CAAC;IAC1M,IAAI,MAA8B,CAAC;IAAC,IAAI,WAAmC,CAAC;IAAC,IAAI,UAAkC,CAAC;IAAC,IAAI,SAAiC,CAAC;IAC3J,IAAI,CAAC;QACD,IAAI,CAAC;YACD,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;YAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC5F,IAAI,aAAa,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAC1I,aAAa,CAAC,MAAM,EAAE,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;gBAAE,MAAM,IAAI,qBAAqB,CAAC,0DAA0D,CAAC,CAAC;QACtI,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,IAAI,KAAK,YAAY,qBAAqB;gBAAE,MAAM,KAAK,CAAC;YACxD,MAAM,IAAI,qBAAqB,CAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAAC,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACtH,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACrG,aAAa,CAAC,UAAU,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;QAC7C,SAAS,GAAG,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QACvH,OAAO,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;YAAS,CAAC;QAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;AACjG,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
2
|
+
export { sha256 };
|
|
3
|
+
/** Platform cryptographic random source; implementations must never use Math.random. */
|
|
4
|
+
export interface RandomSource {
|
|
5
|
+
bytes(length: number): Uint8Array;
|
|
6
|
+
}
|
|
7
|
+
/** Browser and Node.js random source. Expo supplies an explicit native source. */
|
|
8
|
+
export declare const systemRandom: RandomSource;
|
|
9
|
+
export declare function requireLength(value: Uint8Array, length: number, name: string): void;
|
|
10
|
+
/** Ed25519 public key derived from a 32-byte seed. */
|
|
11
|
+
export declare function devicePublicKey(seed: Uint8Array): Uint8Array;
|
|
12
|
+
/** Signs the exact supplied bytes with Ed25519. */
|
|
13
|
+
export declare function signDevice(input: Uint8Array, seed: Uint8Array): Uint8Array;
|
|
14
|
+
/** Uses strict RFC 8032 verification, not permissive ZIP215 acceptance. */
|
|
15
|
+
export declare function verifyDevice(input: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;
|
|
16
|
+
/** Compressed P-256 public key, in the format used by Neo N3 accounts. */
|
|
17
|
+
export declare function accountPublicKey(privateKey: Uint8Array): Uint8Array;
|
|
18
|
+
/** Verifies SHA-256 / P-256 compact signatures; both valid high-S and low-S forms are accepted. */
|
|
19
|
+
export declare function verifyAccount(input: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;
|
|
20
|
+
/** Low-level signing helper; application signers retain ownership of account keys. */
|
|
21
|
+
export declare function signAccount(input: Uint8Array, privateKey: Uint8Array, random?: RandomSource): Uint8Array;
|
|
22
|
+
export declare function encryptionPublicKey(privateKey: Uint8Array): Uint8Array;
|
|
23
|
+
export declare function agreeKey(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;
|
|
24
|
+
export declare function hash160(value: Uint8Array): Uint8Array;
|
|
25
|
+
export declare function deriveKey(secret: Uint8Array, salt: Uint8Array, info: Uint8Array, length?: number): Uint8Array;
|
|
26
|
+
/** AES-256-GCM ciphertext followed by a 16-byte tag. The caller guarantees nonce uniqueness. */
|
|
27
|
+
export declare function encryptAes(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): Uint8Array;
|
|
28
|
+
/** Authenticates before exposing plaintext; malformed ciphertext is a protocol failure. */
|
|
29
|
+
export declare function decryptAes(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array, aad: Uint8Array): Uint8Array;
|
|
30
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/crypto/primitives.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAM/C,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,wFAAwF;AACxF,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE;AAEnE,kFAAkF;AAClF,eAAO,MAAM,YAAY,EAAE,YAU1B,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGnF;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAG5D;AAED,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAG1E;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAGrG;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAGnE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAGtG;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAE,YAA2B,GAAG,UAAU,CAMtH;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAGtE;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAKlF;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAqC;AAE3F,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,SAAK,GAAG,UAAU,CAEzG;AAED,gGAAgG;AAChG,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAIjH;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAMlH"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ed25519, x25519 } from '@noble/curves/ed25519.js';
|
|
2
|
+
import { p256 } from '@noble/curves/nist.js';
|
|
3
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
4
|
+
import { ripemd160 } from '@noble/hashes/legacy.js';
|
|
5
|
+
import { hkdf } from '@noble/hashes/hkdf.js';
|
|
6
|
+
import { gcm } from '@noble/ciphers/aes.js';
|
|
7
|
+
import { ProtocolError } from '../errors.js';
|
|
8
|
+
export { sha256 };
|
|
9
|
+
/** Browser and Node.js random source. Expo supplies an explicit native source. */
|
|
10
|
+
export const systemRandom = {
|
|
11
|
+
bytes(length) {
|
|
12
|
+
if (!Number.isSafeInteger(length) || length < 0)
|
|
13
|
+
throw new RangeError('Invalid random byte count.');
|
|
14
|
+
if (!globalThis.crypto?.getRandomValues)
|
|
15
|
+
throw new ProtocolError('random_unavailable', 'A cryptographic random source is required.');
|
|
16
|
+
const result = new Uint8Array(length);
|
|
17
|
+
for (let offset = 0; offset < length; offset += 65_536)
|
|
18
|
+
globalThis.crypto.getRandomValues(result.subarray(offset, offset + 65_536));
|
|
19
|
+
return result;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export function requireLength(value, length, name) {
|
|
23
|
+
if (!(value instanceof Uint8Array) || value.length !== length)
|
|
24
|
+
throw new ProtocolError('invalid_length', `${name} must contain ${length} bytes.`);
|
|
25
|
+
}
|
|
26
|
+
/** Ed25519 public key derived from a 32-byte seed. */
|
|
27
|
+
export function devicePublicKey(seed) {
|
|
28
|
+
requireLength(seed, 32, 'Ed25519 seed');
|
|
29
|
+
return ed25519.getPublicKey(seed);
|
|
30
|
+
}
|
|
31
|
+
/** Signs the exact supplied bytes with Ed25519. */
|
|
32
|
+
export function signDevice(input, seed) {
|
|
33
|
+
requireLength(seed, 32, 'Ed25519 seed');
|
|
34
|
+
return ed25519.sign(input, seed);
|
|
35
|
+
}
|
|
36
|
+
/** Uses strict RFC 8032 verification, not permissive ZIP215 acceptance. */
|
|
37
|
+
export function verifyDevice(input, signature, publicKey) {
|
|
38
|
+
if (signature.length !== 64 || publicKey.length !== 32)
|
|
39
|
+
return false;
|
|
40
|
+
return ed25519.verify(signature, input, publicKey, { zip215: false });
|
|
41
|
+
}
|
|
42
|
+
/** Compressed P-256 public key, in the format used by Neo N3 accounts. */
|
|
43
|
+
export function accountPublicKey(privateKey) {
|
|
44
|
+
requireLength(privateKey, 32, 'P-256 private key');
|
|
45
|
+
return p256.getPublicKey(privateKey, true);
|
|
46
|
+
}
|
|
47
|
+
/** Verifies SHA-256 / P-256 compact signatures; both valid high-S and low-S forms are accepted. */
|
|
48
|
+
export function verifyAccount(input, signature, publicKey) {
|
|
49
|
+
if (signature.length !== 64 || publicKey.length !== 33 || (publicKey[0] !== 2 && publicKey[0] !== 3))
|
|
50
|
+
return false;
|
|
51
|
+
return p256.verify(signature, input, publicKey, { prehash: true, lowS: false, format: 'compact' });
|
|
52
|
+
}
|
|
53
|
+
/** Low-level signing helper; application signers retain ownership of account keys. */
|
|
54
|
+
export function signAccount(input, privateKey, random = systemRandom) {
|
|
55
|
+
requireLength(privateKey, 32, 'P-256 private key');
|
|
56
|
+
const entropy = random.bytes(32);
|
|
57
|
+
requireLength(entropy, 32, 'Signing entropy');
|
|
58
|
+
try {
|
|
59
|
+
return p256.sign(input, privateKey, { prehash: true, lowS: false, format: 'compact', extraEntropy: entropy });
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
entropy.fill(0);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function encryptionPublicKey(privateKey) {
|
|
66
|
+
requireLength(privateKey, 32, 'X25519 private key');
|
|
67
|
+
return x25519.getPublicKey(privateKey);
|
|
68
|
+
}
|
|
69
|
+
export function agreeKey(privateKey, publicKey) {
|
|
70
|
+
requireLength(privateKey, 32, 'X25519 private key');
|
|
71
|
+
requireLength(publicKey, 32, 'X25519 public key');
|
|
72
|
+
try {
|
|
73
|
+
return x25519.getSharedSecret(privateKey, publicKey);
|
|
74
|
+
}
|
|
75
|
+
catch (cause) {
|
|
76
|
+
throw new ProtocolError('invalid_key', 'X25519 agreement failed, including an all-zero shared secret.', { cause });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function hash160(value) { return ripemd160(sha256(value)); }
|
|
80
|
+
export function deriveKey(secret, salt, info, length = 32) {
|
|
81
|
+
return hkdf(sha256, secret, salt, info, length);
|
|
82
|
+
}
|
|
83
|
+
/** AES-256-GCM ciphertext followed by a 16-byte tag. The caller guarantees nonce uniqueness. */
|
|
84
|
+
export function encryptAes(key, nonce, plaintext, aad) {
|
|
85
|
+
requireLength(key, 32, 'AES-256 key');
|
|
86
|
+
requireLength(nonce, 12, 'GCM nonce');
|
|
87
|
+
return gcm(key, nonce, aad).encrypt(plaintext);
|
|
88
|
+
}
|
|
89
|
+
/** Authenticates before exposing plaintext; malformed ciphertext is a protocol failure. */
|
|
90
|
+
export function decryptAes(key, nonce, ciphertext, aad) {
|
|
91
|
+
requireLength(key, 32, 'AES-256 key');
|
|
92
|
+
requireLength(nonce, 12, 'GCM nonce');
|
|
93
|
+
if (ciphertext.length < 16)
|
|
94
|
+
throw new ProtocolError('invalid_ciphertext', 'Missing GCM tag.');
|
|
95
|
+
try {
|
|
96
|
+
return gcm(key, nonce, aad).decrypt(ciphertext);
|
|
97
|
+
}
|
|
98
|
+
catch (cause) {
|
|
99
|
+
throw new ProtocolError('invalid_ciphertext', 'GCM authentication failed.', { cause });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/crypto/primitives.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** A local encoding, identity, signature, or authorization violation. */
|
|
2
|
+
export declare class ProtocolError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly name = "ProtocolError";
|
|
5
|
+
constructor(code: string, message: string, options?: ErrorOptions);
|
|
6
|
+
}
|
|
7
|
+
/** A persisted operation cannot safely overwrite the current revision. */
|
|
8
|
+
export declare class StateConflictError extends Error {
|
|
9
|
+
readonly name = "StateConflictError";
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,qBAAa,aAAc,SAAQ,KAAK;IAGxB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAFjC,SAAkB,IAAI,mBAAmB;IAEzC,YAAqB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAEzE;CACJ;AAED,0EAA0E;AAC1E,qBAAa,kBAAmB,SAAQ,KAAK;IACzC,SAAkB,IAAI,wBAAwB;CACjD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A local encoding, identity, signature, or authorization violation. */
|
|
2
|
+
export class ProtocolError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
name = 'ProtocolError';
|
|
5
|
+
constructor(code, message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.code = code;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** A persisted operation cannot safely overwrite the current revision. */
|
|
11
|
+
export class StateConflictError extends Error {
|
|
12
|
+
name = 'StateConflictError';
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGf,IAAI;IAFP,IAAI,GAAG,eAAe,CAAC;IAEzC,YAAqB,IAAY,EAAE,OAAe,EAAE,OAAsB;QACtE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBADP,IAAI;IAEzB,CAAC;CACJ;AAED,0EAA0E;AAC1E,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACvB,IAAI,GAAG,oBAAoB,CAAC;CACjD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DeviceManager } from '../components/device.js';
|
|
2
|
+
import type { MessageManager } from '../components/message.js';
|
|
3
|
+
import { ProtocolError } from '../errors.js';
|
|
4
|
+
import { type GroupRef } from '../models/groups.js';
|
|
5
|
+
import type { NetworkContext } from '../protocol/context.js';
|
|
6
|
+
import { type RuntimeClock } from '../runtime/clock.js';
|
|
7
|
+
import type { MeshlineStore } from '../storage/store.js';
|
|
8
|
+
import { type GroupSecrets } from './secrets.js';
|
|
9
|
+
export interface GroupAccountSyncOptions {
|
|
10
|
+
readonly store: MeshlineStore;
|
|
11
|
+
readonly context: NetworkContext;
|
|
12
|
+
readonly accountId: string;
|
|
13
|
+
readonly clock: RuntimeClock;
|
|
14
|
+
readonly device: DeviceManager;
|
|
15
|
+
readonly messages: MessageManager;
|
|
16
|
+
readonly secrets: GroupSecrets;
|
|
17
|
+
rejected(messageId: string, error: ProtocolError): void;
|
|
18
|
+
}
|
|
19
|
+
/** One consumer cursor commits with all key effects; local protection/storage failures remain retryable. */
|
|
20
|
+
export declare class GroupAccountSync {
|
|
21
|
+
#private;
|
|
22
|
+
readonly options: GroupAccountSyncOptions;
|
|
23
|
+
constructor(options: GroupAccountSyncOptions);
|
|
24
|
+
request(signal?: AbortSignal): Promise<void>;
|
|
25
|
+
consume(signal: AbortSignal): Promise<void>;
|
|
26
|
+
shareCurrent(group: GroupRef, signal: AbortSignal): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=account-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-sync.d.ts","sourceRoot":"","sources":["../../src/groups/account-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AAIjE,OAAO,EAC4I,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE9L,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAwD,MAAM,qBAAqB,CAAC;AAG/G,OAAO,EAAmD,KAAK,YAAY,EAA0B,MAAM,cAAc,CAAC;AAE1H,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC1H,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAClG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC3D;AAeD,4GAA4G;AAC5G,qBAAa,gBAAgB;;IACb,QAAQ,CAAC,OAAO,EAAE,uBAAuB;IAArD,YAAqB,OAAO,EAAE,uBAAuB,EAAI;IACzD,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAA+H;IACrK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhD;IAuDK,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAuD;CA+BjI"}
|