zapo-js 0.1.2 → 0.2.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.
- package/README.md +12 -4
- package/dist/appstate/WaAppStateCrypto.js +1 -1
- package/dist/appstate/WaAppStateSyncClient.js +138 -93
- package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/appstate/index.js +8 -6
- package/dist/appstate/utils.js +0 -5
- package/dist/auth/WaAuthClient.js +36 -47
- package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
- package/dist/auth/index.js +1 -6
- package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/auth/pairing/WaPairingFlow.js +13 -3
- package/dist/client/WaClient.js +225 -101
- package/dist/client/WaClientFactory.js +294 -44
- package/dist/client/connection/WaConnectionManager.js +19 -10
- package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
- package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
- package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
- package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
- package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
- package/dist/client/dirty.js +40 -20
- package/dist/client/events/devices.js +72 -0
- package/dist/client/events/group.js +3 -11
- package/dist/client/events/identity.js +22 -0
- package/dist/client/events/privacy-token.js +39 -0
- package/dist/client/history-sync.js +50 -9
- package/dist/client/incoming.js +37 -7
- package/dist/client/mailbox.js +24 -23
- package/dist/client/messages.js +107 -31
- package/dist/client/messaging/fanout.js +21 -11
- package/dist/client/messaging/participants.js +6 -4
- package/dist/client/persistence/WriteBehindPersistence.js +129 -0
- package/dist/client/tokens/cs-token.js +50 -0
- package/dist/client/tokens/tc-token.js +25 -0
- package/dist/crypto/core/index.js +2 -2
- package/dist/crypto/core/keys.js +4 -4
- package/dist/crypto/core/nonce.js +2 -0
- package/dist/crypto/core/primitives.js +0 -8
- package/dist/crypto/core/random.js +22 -0
- package/dist/crypto/curves/X25519.js +25 -6
- package/dist/crypto/index.js +3 -0
- package/dist/crypto/math/constants.js +13 -36
- package/dist/crypto/math/edwards.js +171 -44
- package/dist/crypto/math/fe.js +706 -0
- package/dist/crypto/math/mod.js +10 -3
- package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
- package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
- package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/esm/appstate/index.js +2 -2
- package/dist/esm/appstate/utils.js +2 -5
- package/dist/esm/auth/WaAuthClient.js +36 -47
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
- package/dist/esm/auth/index.js +0 -2
- package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
- package/dist/esm/client/WaClient.js +225 -101
- package/dist/esm/client/WaClientFactory.js +295 -45
- package/dist/esm/client/connection/WaConnectionManager.js +19 -10
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
- package/dist/esm/client/dirty.js +40 -20
- package/dist/esm/client/events/devices.js +68 -0
- package/dist/esm/client/events/group.js +3 -11
- package/dist/esm/client/events/identity.js +19 -0
- package/dist/esm/client/events/privacy-token.js +36 -0
- package/dist/esm/client/history-sync.js +50 -9
- package/dist/esm/client/incoming.js +38 -8
- package/dist/esm/client/mailbox.js +24 -23
- package/dist/esm/client/messages.js +108 -32
- package/dist/esm/client/messaging/fanout.js +22 -12
- package/dist/esm/client/messaging/participants.js +6 -4
- package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
- package/dist/esm/client/tokens/cs-token.js +46 -0
- package/dist/esm/client/tokens/tc-token.js +18 -0
- package/dist/esm/crypto/core/index.js +2 -2
- package/dist/esm/crypto/core/keys.js +1 -1
- package/dist/esm/crypto/core/nonce.js +2 -0
- package/dist/esm/crypto/core/primitives.js +0 -7
- package/dist/esm/crypto/core/random.js +22 -1
- package/dist/esm/crypto/curves/X25519.js +25 -6
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/crypto/math/constants.js +12 -35
- package/dist/esm/crypto/math/edwards.js +174 -47
- package/dist/esm/crypto/math/fe.js +691 -0
- package/dist/esm/crypto/math/mod.js +10 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
- package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/esm/infra/perf/PromiseDedup.js +20 -0
- package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
- package/dist/esm/infra/perf/StoreLock.js +77 -0
- package/dist/esm/media/WaMediaCrypto.js +95 -13
- package/dist/esm/media/WaMediaTransferClient.js +39 -47
- package/dist/esm/media/constants.js +2 -1
- package/dist/esm/message/WaMessageClient.js +26 -19
- package/dist/esm/message/content.js +195 -9
- package/dist/esm/message/icdc.js +76 -0
- package/dist/esm/message/incoming.js +24 -12
- package/dist/esm/message/phash.js +3 -1
- package/dist/esm/message/reporting-token.js +14 -27
- package/dist/esm/protocol/appstate.js +9 -40
- package/dist/esm/protocol/browser.js +10 -18
- package/dist/esm/protocol/constants.js +5 -3
- package/dist/esm/protocol/defaults.js +6 -0
- package/dist/esm/protocol/index.js +1 -2
- package/dist/esm/protocol/jid.js +105 -36
- package/dist/esm/protocol/message.js +61 -1
- package/dist/esm/protocol/nodes.js +2 -0
- package/dist/esm/protocol/notification.js +3 -1
- package/dist/esm/protocol/privacy-token.js +17 -0
- package/dist/esm/protocol/privacy.js +55 -0
- package/dist/esm/protocol/stream.js +26 -1
- package/dist/esm/retry/codec.js +216 -0
- package/dist/esm/retry/constants.js +1 -1
- package/dist/esm/retry/index.js +2 -2
- package/dist/esm/retry/parse.js +50 -30
- package/dist/esm/retry/replay.js +11 -7
- package/dist/esm/retry/tracker.js +50 -12
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
- package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
- package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
- package/dist/esm/signal/api/result-map.js +10 -0
- package/dist/esm/signal/constants.js +0 -4
- package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
- package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
- package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
- package/dist/esm/signal/group/SenderKeyManager.js +125 -106
- package/dist/esm/signal/index.js +1 -0
- package/dist/esm/signal/registration/keygen.js +6 -2
- package/dist/esm/signal/registration/utils.js +1 -0
- package/dist/esm/signal/session/SignalProtocol.js +150 -74
- package/dist/esm/signal/session/resolver.js +137 -102
- package/dist/esm/store/contracts/privacy-token.store.js +1 -0
- package/dist/esm/store/createStore.js +101 -187
- package/dist/esm/store/index.js +1 -10
- package/dist/esm/store/locks/appstate.lock.js +26 -0
- package/dist/esm/store/locks/auth.lock.js +15 -0
- package/dist/esm/store/locks/contact.lock.js +20 -0
- package/dist/esm/store/locks/device-list.lock.js +20 -0
- package/dist/esm/store/locks/message.lock.js +21 -0
- package/dist/esm/store/locks/participants.lock.js +20 -0
- package/dist/esm/store/locks/privacy-token.lock.js +18 -0
- package/dist/esm/store/locks/retry.lock.js +29 -0
- package/dist/esm/store/locks/sender-key.lock.js +52 -0
- package/dist/esm/store/locks/signal.lock.js +63 -0
- package/dist/esm/store/locks/thread.lock.js +21 -0
- package/dist/esm/store/noop.store.js +1 -1
- package/dist/esm/store/providers/memory/appstate.store.js +22 -24
- package/dist/esm/store/providers/memory/device-list.store.js +10 -5
- package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
- package/dist/esm/store/providers/memory/retry.store.js +77 -2
- package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
- package/dist/esm/store/providers/memory/signal.store.js +36 -19
- package/dist/esm/transport/WaComms.js +3 -1
- package/dist/esm/transport/WaWebSocket.js +0 -6
- package/dist/esm/transport/binary/constants.js +0 -30
- package/dist/esm/transport/binary/decoder.js +4 -4
- package/dist/esm/transport/binary/encoder.js +8 -15
- package/dist/esm/transport/binary/index.js +0 -1
- package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
- package/dist/esm/transport/node/builders/business.js +129 -0
- package/dist/esm/transport/node/builders/global.js +370 -0
- package/dist/esm/transport/node/builders/index.js +5 -2
- package/dist/esm/transport/node/builders/message.js +63 -239
- package/dist/esm/transport/node/builders/pairing.js +0 -24
- package/dist/esm/transport/node/builders/privacy-token.js +41 -0
- package/dist/esm/transport/node/builders/privacy.js +48 -0
- package/dist/esm/transport/node/builders/profile.js +70 -0
- package/dist/esm/transport/node/builders/retry.js +10 -22
- package/dist/esm/transport/node/builders/usync.js +6 -2
- package/dist/esm/transport/node/helpers.js +19 -1
- package/dist/esm/transport/node/usync.js +3 -33
- package/dist/esm/transport/node/xml.js +35 -14
- package/dist/esm/transport/noise/WaClientPayload.js +10 -10
- package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
- package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
- package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/esm/transport/stream/parse.js +8 -4
- package/dist/esm/util/bytes.js +22 -18
- package/dist/esm/util/index.js +5 -0
- package/dist/esm/util/primitives.js +3 -2
- package/dist/index.js +7 -1
- package/dist/infra/perf/BackgroundQueue.js +482 -0
- package/dist/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/infra/perf/PromiseDedup.js +24 -0
- package/dist/infra/perf/SharedExclusiveGate.js +113 -0
- package/dist/infra/perf/StoreLock.js +81 -0
- package/dist/media/WaMediaCrypto.js +94 -12
- package/dist/media/WaMediaTransferClient.js +39 -47
- package/dist/media/constants.js +2 -1
- package/dist/message/WaMessageClient.js +26 -19
- package/dist/message/content.js +198 -9
- package/dist/message/icdc.js +81 -0
- package/dist/message/incoming.js +24 -12
- package/dist/message/phash.js +3 -1
- package/dist/message/reporting-token.js +14 -28
- package/dist/protocol/appstate.js +10 -41
- package/dist/protocol/browser.js +10 -18
- package/dist/protocol/constants.js +21 -2
- package/dist/protocol/defaults.js +6 -0
- package/dist/protocol/index.js +8 -5
- package/dist/protocol/jid.js +111 -36
- package/dist/protocol/message.js +62 -2
- package/dist/protocol/nodes.js +2 -0
- package/dist/protocol/notification.js +3 -1
- package/dist/protocol/privacy-token.js +20 -0
- package/dist/protocol/privacy.js +58 -0
- package/dist/protocol/stream.js +27 -2
- package/dist/retry/codec.js +220 -0
- package/dist/retry/constants.js +1 -1
- package/dist/retry/index.js +5 -5
- package/dist/retry/parse.js +51 -30
- package/dist/retry/replay.js +10 -6
- package/dist/retry/tracker.js +50 -12
- package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
- package/dist/signal/api/SignalDigestSyncApi.js +13 -9
- package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
- package/dist/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/signal/api/SignalSessionSyncApi.js +16 -7
- package/dist/signal/api/result-map.js +13 -0
- package/dist/signal/constants.js +1 -5
- package/dist/signal/crypto/WaAdvSignature.js +11 -5
- package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
- package/dist/signal/group/SenderKeyCodec.js +4 -3
- package/dist/signal/group/SenderKeyManager.js +125 -106
- package/dist/signal/index.js +13 -1
- package/dist/signal/registration/keygen.js +6 -2
- package/dist/signal/registration/utils.js +1 -0
- package/dist/signal/session/SignalProtocol.js +150 -74
- package/dist/signal/session/resolver.js +135 -100
- package/dist/store/contracts/privacy-token.store.js +2 -0
- package/dist/store/createStore.js +101 -187
- package/dist/store/index.js +15 -33
- package/dist/store/locks/appstate.lock.js +29 -0
- package/dist/store/locks/auth.lock.js +18 -0
- package/dist/store/locks/contact.lock.js +23 -0
- package/dist/store/locks/device-list.lock.js +23 -0
- package/dist/store/locks/message.lock.js +24 -0
- package/dist/store/locks/participants.lock.js +23 -0
- package/dist/store/locks/privacy-token.lock.js +21 -0
- package/dist/store/locks/retry.lock.js +32 -0
- package/dist/store/locks/sender-key.lock.js +55 -0
- package/dist/store/locks/signal.lock.js +66 -0
- package/dist/store/locks/thread.lock.js +24 -0
- package/dist/store/noop.store.js +1 -1
- package/dist/store/providers/memory/appstate.store.js +22 -24
- package/dist/store/providers/memory/device-list.store.js +10 -5
- package/dist/store/providers/memory/privacy-token.store.js +47 -0
- package/dist/store/providers/memory/retry.store.js +77 -2
- package/dist/store/providers/memory/sender-key.store.js +6 -1
- package/dist/store/providers/memory/signal.store.js +36 -19
- package/dist/transport/WaComms.js +3 -1
- package/dist/transport/WaWebSocket.js +0 -6
- package/dist/transport/binary/constants.js +1 -31
- package/dist/transport/binary/decoder.js +4 -4
- package/dist/transport/binary/encoder.js +8 -15
- package/dist/transport/binary/index.js +0 -4
- package/dist/transport/node/WaNodeOrchestrator.js +24 -18
- package/dist/transport/node/builders/business.js +137 -0
- package/dist/transport/node/builders/global.js +375 -0
- package/dist/transport/node/builders/index.js +18 -9
- package/dist/transport/node/builders/message.js +64 -245
- package/dist/transport/node/builders/pairing.js +0 -26
- package/dist/transport/node/builders/privacy-token.js +46 -0
- package/dist/transport/node/builders/privacy.js +55 -0
- package/dist/transport/node/builders/profile.js +78 -0
- package/dist/transport/node/builders/retry.js +9 -21
- package/dist/transport/node/builders/usync.js +6 -2
- package/dist/transport/node/helpers.js +20 -1
- package/dist/transport/node/usync.js +2 -32
- package/dist/transport/node/xml.js +35 -14
- package/dist/transport/noise/WaClientPayload.js +13 -13
- package/dist/transport/noise/WaNoiseCert.js +2 -2
- package/dist/transport/noise/WaNoiseSession.js +64 -23
- package/dist/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/transport/stream/parse.js +7 -3
- package/dist/types/appstate/encoding.d.ts +7 -0
- package/dist/types/appstate/index.d.ts +3 -3
- package/dist/types/appstate/utils.d.ts +0 -2
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
- package/dist/types/auth/index.d.ts +0 -2
- package/dist/types/auth/types.d.ts +1 -0
- package/dist/types/client/WaClient.d.ts +27 -12
- package/dist/types/client/WaClientFactory.d.ts +12 -4
- package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
- package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
- package/dist/types/client/events/devices.d.ts +20 -0
- package/dist/types/client/events/identity.d.ts +9 -0
- package/dist/types/client/events/privacy-token.d.ts +7 -0
- package/dist/types/client/history-sync.d.ts +9 -6
- package/dist/types/client/incoming.d.ts +3 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/mailbox.d.ts +3 -5
- package/dist/types/client/messages.d.ts +1 -2
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
- package/dist/types/client/tokens/cs-token.d.ts +10 -0
- package/dist/types/client/tokens/tc-token.d.ts +5 -0
- package/dist/types/client/types.d.ts +51 -3
- package/dist/types/crypto/core/index.d.ts +2 -2
- package/dist/types/crypto/core/nonce.d.ts +2 -0
- package/dist/types/crypto/core/primitives.d.ts +0 -1
- package/dist/types/crypto/core/random.d.ts +1 -0
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/crypto/math/constants.d.ts +4 -2
- package/dist/types/crypto/math/fe.d.ts +30 -0
- package/dist/types/crypto/math/mod.d.ts +0 -2
- package/dist/types/crypto/math/types.d.ts +11 -4
- package/dist/types/index.d.ts +5 -3
- package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
- package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
- package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
- package/dist/types/infra/perf/StoreLock.d.ts +10 -0
- package/dist/types/media/WaMediaCrypto.d.ts +3 -2
- package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
- package/dist/types/media/constants.d.ts +1 -1
- package/dist/types/media/index.d.ts +1 -1
- package/dist/types/media/types.d.ts +10 -2
- package/dist/types/message/content.d.ts +8 -0
- package/dist/types/message/icdc.d.ts +13 -0
- package/dist/types/message/reporting-token.d.ts +0 -1
- package/dist/types/message/types.d.ts +45 -6
- package/dist/types/protocol/appstate.d.ts +0 -11
- package/dist/types/protocol/constants.d.ts +7 -3
- package/dist/types/protocol/defaults.d.ts +6 -0
- package/dist/types/protocol/index.d.ts +1 -2
- package/dist/types/protocol/jid.d.ts +19 -2
- package/dist/types/protocol/message.d.ts +60 -0
- package/dist/types/protocol/nodes.d.ts +2 -0
- package/dist/types/protocol/notification.d.ts +2 -0
- package/dist/types/protocol/privacy-token.d.ts +17 -0
- package/dist/types/protocol/privacy.d.ts +75 -0
- package/dist/types/protocol/stream.d.ts +30 -0
- package/dist/types/retry/codec.d.ts +3 -0
- package/dist/types/retry/index.d.ts +3 -3
- package/dist/types/retry/parse.d.ts +5 -2
- package/dist/types/retry/tracker.d.ts +1 -0
- package/dist/types/retry/types.d.ts +6 -1
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
- package/dist/types/signal/api/result-map.d.ts +1 -0
- package/dist/types/signal/constants.d.ts +0 -3
- package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
- package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
- package/dist/types/signal/index.d.ts +2 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
- package/dist/types/signal/session/resolver.d.ts +7 -2
- package/dist/types/store/contracts/appstate.store.d.ts +1 -1
- package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
- package/dist/types/store/contracts/retry.store.d.ts +7 -0
- package/dist/types/store/contracts/signal.store.d.ts +7 -0
- package/dist/types/store/createStore.d.ts +1 -1
- package/dist/types/store/index.d.ts +5 -13
- package/dist/types/store/locks/appstate.lock.d.ts +3 -0
- package/dist/types/store/locks/auth.lock.d.ts +3 -0
- package/dist/types/store/locks/contact.lock.d.ts +3 -0
- package/dist/types/store/locks/device-list.lock.d.ts +2 -0
- package/dist/types/store/locks/message.lock.d.ts +3 -0
- package/dist/types/store/locks/participants.lock.d.ts +2 -0
- package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
- package/dist/types/store/locks/retry.lock.d.ts +2 -0
- package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
- package/dist/types/store/locks/signal.lock.d.ts +3 -0
- package/dist/types/store/locks/thread.lock.d.ts +3 -0
- package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
- package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
- package/dist/types/store/types.d.ts +49 -61
- package/dist/types/transport/WaWebSocket.d.ts +0 -1
- package/dist/types/transport/binary/constants.d.ts +0 -30
- package/dist/types/transport/binary/index.d.ts +0 -1
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
- package/dist/types/transport/node/builders/business.d.ts +29 -0
- package/dist/types/transport/node/builders/global.d.ts +102 -0
- package/dist/types/transport/node/builders/index.d.ts +5 -2
- package/dist/types/transport/node/builders/message.d.ts +8 -7
- package/dist/types/transport/node/builders/pairing.d.ts +0 -2
- package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
- package/dist/types/transport/node/builders/privacy.d.ts +7 -0
- package/dist/types/transport/node/builders/profile.d.ts +8 -0
- package/dist/types/transport/node/builders/retry.d.ts +0 -1
- package/dist/types/transport/node/helpers.d.ts +5 -0
- package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
- package/dist/types/util/bytes.d.ts +1 -1
- package/dist/types/util/index.d.ts +5 -0
- package/dist/types/util/primitives.d.ts +0 -1
- package/dist/util/bytes.js +22 -18
- package/dist/util/index.js +23 -0
- package/dist/util/primitives.js +2 -2
- package/package.json +29 -7
- package/proto/index.js +1 -1
- package/dist/crypto/core/constants.js +0 -4
- package/dist/esm/crypto/core/constants.js +0 -1
- package/dist/esm/retry/outbound.js +0 -82
- package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
- package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
- package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
- package/dist/esm/store/providers/sqlite/connection.js +0 -245
- package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
- package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
- package/dist/esm/store/providers/sqlite/message.store.js +0 -132
- package/dist/esm/store/providers/sqlite/migrations.js +0 -347
- package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
- package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
- package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
- package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
- package/dist/esm/store/providers/sqlite/table-names.js +0 -107
- package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
- package/dist/retry/outbound.js +0 -87
- package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
- package/dist/store/providers/sqlite/appstate.store.js +0 -254
- package/dist/store/providers/sqlite/auth.store.js +0 -180
- package/dist/store/providers/sqlite/connection.js +0 -281
- package/dist/store/providers/sqlite/contact.store.js +0 -78
- package/dist/store/providers/sqlite/device-list.store.js +0 -131
- package/dist/store/providers/sqlite/message.store.js +0 -136
- package/dist/store/providers/sqlite/migrations.js +0 -350
- package/dist/store/providers/sqlite/participants.store.js +0 -81
- package/dist/store/providers/sqlite/retry.store.js +0 -145
- package/dist/store/providers/sqlite/sender-key.store.js +0 -202
- package/dist/store/providers/sqlite/signal.store.js +0 -439
- package/dist/store/providers/sqlite/table-names.js +0 -113
- package/dist/store/providers/sqlite/thread.store.js +0 -89
- package/dist/types/appstate/store/sqlite.d.ts +0 -7
- package/dist/types/crypto/core/constants.d.ts +0 -1
- package/dist/types/retry/outbound.d.ts +0 -4
- package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
- package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
- package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
- package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
- package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
- package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
- package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
- package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PromiseDedup } from '../../infra/perf/PromiseDedup.js';
|
|
2
|
+
import { isHostedDeviceJid, normalizeDeviceJid, splitJid, toUserJid } from '../../protocol/jid.js';
|
|
2
3
|
import { toError } from '../../util/primitives.js';
|
|
3
4
|
export function createDeviceFanoutResolver(options) {
|
|
4
5
|
const { signalDeviceSync, getCurrentMeJid, getCurrentMeLid, logger } = options;
|
|
5
|
-
const
|
|
6
|
-
const meJid = getCurrentMeJid();
|
|
7
|
-
if (meJid) {
|
|
8
|
-
return meJid;
|
|
9
|
-
}
|
|
10
|
-
throw new Error(`${context} requires registered meJid`);
|
|
11
|
-
};
|
|
6
|
+
const dedup = new PromiseDedup();
|
|
12
7
|
const resolveDirectFanoutDeviceJids = async (recipientJid, selfDeviceJidForRecipient) => {
|
|
13
8
|
const recipientUserJid = toUserJid(recipientJid);
|
|
14
9
|
const meUserJid = toUserJid(selfDeviceJidForRecipient);
|
|
15
10
|
const targets = recipientUserJid === meUserJid ? [recipientUserJid] : [recipientUserJid, meUserJid];
|
|
16
11
|
try {
|
|
17
12
|
const synced = await signalDeviceSync.syncDeviceList(targets);
|
|
18
|
-
const byUser = new Map(
|
|
13
|
+
const byUser = new Map();
|
|
14
|
+
for (let index = 0; index < synced.length; index += 1) {
|
|
15
|
+
const entry = synced[index];
|
|
16
|
+
byUser.set(toUserJid(entry.jid), entry.deviceJids);
|
|
17
|
+
}
|
|
19
18
|
const fanout = new Set();
|
|
20
19
|
const recipientDevices = byUser.get(recipientUserJid) ?? [];
|
|
21
20
|
if (recipientDevices.length === 0) {
|
|
@@ -45,7 +44,7 @@ export function createDeviceFanoutResolver(options) {
|
|
|
45
44
|
return [recipientUserJid];
|
|
46
45
|
}
|
|
47
46
|
};
|
|
48
|
-
const
|
|
47
|
+
const resolveGroupParticipantDeviceJidsInternal = async (participantUserJids) => {
|
|
49
48
|
const meDeviceJids = new Set();
|
|
50
49
|
const meJid = getCurrentMeJid();
|
|
51
50
|
if (meJid) {
|
|
@@ -71,7 +70,11 @@ export function createDeviceFanoutResolver(options) {
|
|
|
71
70
|
});
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
|
-
const
|
|
73
|
+
const candidateUserSet = new Set();
|
|
74
|
+
for (let index = 0; index < participantUserJids.length; index += 1) {
|
|
75
|
+
candidateUserSet.add(participantUserJids[index]);
|
|
76
|
+
}
|
|
77
|
+
const candidateUsers = Array.from(candidateUserSet);
|
|
75
78
|
if (candidateUsers.length === 0) {
|
|
76
79
|
return [];
|
|
77
80
|
}
|
|
@@ -89,6 +92,9 @@ export function createDeviceFanoutResolver(options) {
|
|
|
89
92
|
}
|
|
90
93
|
for (const deviceJid of entry.deviceJids) {
|
|
91
94
|
const normalizedDeviceJid = normalizeDeviceJid(deviceJid);
|
|
95
|
+
if (isHostedDeviceJid(normalizedDeviceJid)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
92
98
|
if (meDeviceJids.has(normalizedDeviceJid)) {
|
|
93
99
|
continue;
|
|
94
100
|
}
|
|
@@ -122,7 +128,10 @@ export function createDeviceFanoutResolver(options) {
|
|
|
122
128
|
}
|
|
123
129
|
};
|
|
124
130
|
const resolveOwnPeerDeviceJids = async () => {
|
|
125
|
-
const meJid =
|
|
131
|
+
const meJid = getCurrentMeJid();
|
|
132
|
+
if (!meJid) {
|
|
133
|
+
throw new Error('resolveOwnPeerDeviceJids requires registered meJid');
|
|
134
|
+
}
|
|
126
135
|
const meUserJid = toUserJid(meJid);
|
|
127
136
|
const meDevices = new Set();
|
|
128
137
|
meDevices.add(normalizeDeviceJid(meJid));
|
|
@@ -177,6 +186,7 @@ export function createDeviceFanoutResolver(options) {
|
|
|
177
186
|
}
|
|
178
187
|
return meLid;
|
|
179
188
|
};
|
|
189
|
+
const resolveGroupParticipantDeviceJids = (participantUserJids) => dedup.run(`group:${participantUserJids.join(',')}`, () => resolveGroupParticipantDeviceJidsInternal(participantUserJids));
|
|
180
190
|
return {
|
|
181
191
|
resolveDirectFanoutDeviceJids,
|
|
182
192
|
resolveGroupParticipantDeviceJids,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { PromiseDedup } from '../../infra/perf/PromiseDedup.js';
|
|
1
2
|
import { toUserJid } from '../../protocol/jid.js';
|
|
2
3
|
import { toError } from '../../util/primitives.js';
|
|
3
4
|
export function createGroupParticipantsCache(options) {
|
|
4
5
|
const { participantsStore, queryGroupParticipantJids, logger } = options;
|
|
6
|
+
const dedup = new PromiseDedup();
|
|
5
7
|
const sanitizeParticipantUsers = (participants) => {
|
|
6
8
|
const deduped = new Set();
|
|
7
9
|
for (const participant of participants) {
|
|
@@ -117,7 +119,7 @@ export function createGroupParticipantsCache(options) {
|
|
|
117
119
|
}
|
|
118
120
|
return sanitizeParticipantUsers(candidates);
|
|
119
121
|
};
|
|
120
|
-
const refreshParticipantUsers = async (
|
|
122
|
+
const refreshParticipantUsers = (groupJid) => dedup.run(`refresh:${groupJid}`, async () => {
|
|
121
123
|
const queried = await queryGroupParticipantJids(groupJid);
|
|
122
124
|
const participants = sanitizeParticipantUsers(queried);
|
|
123
125
|
await participantsStore.upsertGroupParticipants({
|
|
@@ -126,14 +128,14 @@ export function createGroupParticipantsCache(options) {
|
|
|
126
128
|
updatedAtMs: Date.now()
|
|
127
129
|
});
|
|
128
130
|
return participants;
|
|
129
|
-
};
|
|
130
|
-
const resolveParticipantUsers = async (
|
|
131
|
+
});
|
|
132
|
+
const resolveParticipantUsers = (groupJid) => dedup.run(`resolve:${groupJid}`, async () => {
|
|
131
133
|
const cached = await participantsStore.getGroupParticipants(groupJid);
|
|
132
134
|
if (cached && cached.participants.length > 0) {
|
|
133
135
|
return sanitizeParticipantUsers(cached.participants);
|
|
134
136
|
}
|
|
135
137
|
return refreshParticipantUsers(groupJid);
|
|
136
|
-
};
|
|
138
|
+
});
|
|
137
139
|
const mutateFromGroupEvent = async (event) => {
|
|
138
140
|
const groupJid = resolveGroupJidForParticipantCacheEvent(event);
|
|
139
141
|
if (!groupJid) {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { BackgroundQueue } from '../../infra/perf/BackgroundQueue.js';
|
|
2
|
+
import { toError } from '../../util/primitives.js';
|
|
3
|
+
function mergeThread(previous, incoming) {
|
|
4
|
+
return {
|
|
5
|
+
jid: incoming.jid,
|
|
6
|
+
name: incoming.name ?? previous.name,
|
|
7
|
+
unreadCount: incoming.unreadCount ?? previous.unreadCount,
|
|
8
|
+
archived: incoming.archived ?? previous.archived,
|
|
9
|
+
pinned: incoming.pinned ?? previous.pinned,
|
|
10
|
+
muteEndMs: incoming.muteEndMs ?? previous.muteEndMs,
|
|
11
|
+
markedAsUnread: incoming.markedAsUnread ?? previous.markedAsUnread,
|
|
12
|
+
ephemeralExpiration: incoming.ephemeralExpiration ?? previous.ephemeralExpiration
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function mergeContact(previous, incoming) {
|
|
16
|
+
return {
|
|
17
|
+
jid: incoming.jid,
|
|
18
|
+
displayName: incoming.displayName ?? previous.displayName,
|
|
19
|
+
pushName: incoming.pushName ?? previous.pushName,
|
|
20
|
+
lid: incoming.lid ?? previous.lid,
|
|
21
|
+
phoneNumber: incoming.phoneNumber ?? previous.phoneNumber,
|
|
22
|
+
lastUpdatedMs: Math.max(previous.lastUpdatedMs, incoming.lastUpdatedMs)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export class WriteBehindPersistence {
|
|
26
|
+
constructor(stores, logger, options = {}) {
|
|
27
|
+
this.logger = logger;
|
|
28
|
+
this.flushTimeoutMs = options.flushTimeoutMs ?? 5000;
|
|
29
|
+
const queueOptions = (domain) => ({
|
|
30
|
+
maxPendingKeys: options.maxPendingKeys ?? 4096,
|
|
31
|
+
maxWriteConcurrency: options.maxWriteConcurrency ?? 4,
|
|
32
|
+
flushTimeoutMs: this.flushTimeoutMs,
|
|
33
|
+
onError: (key, error, attempt) => {
|
|
34
|
+
this.logger.warn('write-behind error', {
|
|
35
|
+
domain,
|
|
36
|
+
key,
|
|
37
|
+
attempt,
|
|
38
|
+
message: toError(error).message
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
onPressure: (pendingKeys) => {
|
|
42
|
+
this.logger.warn('write-behind pressure', {
|
|
43
|
+
domain,
|
|
44
|
+
pendingKeys
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
onDiscard: (key) => {
|
|
48
|
+
this.logger.warn('write-behind discarded pending write', {
|
|
49
|
+
domain,
|
|
50
|
+
key
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
this.queues = {
|
|
55
|
+
messages: new BackgroundQueue((_key, value) => stores.messageStore.upsert(value), queueOptions('messages')),
|
|
56
|
+
threads: new BackgroundQueue((_key, value) => stores.threadStore.upsert(value), {
|
|
57
|
+
...queueOptions('threads'),
|
|
58
|
+
coalesce: (previous, incoming) => mergeThread(previous, incoming)
|
|
59
|
+
}),
|
|
60
|
+
contacts: new BackgroundQueue((_key, value) => stores.contactStore.upsert(value), {
|
|
61
|
+
...queueOptions('contacts'),
|
|
62
|
+
coalesce: (previous, incoming) => mergeContact(previous, incoming)
|
|
63
|
+
})
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
persistMessage(record) {
|
|
67
|
+
this.queues.messages.enqueue(`msg:${record.id}`, record);
|
|
68
|
+
}
|
|
69
|
+
persistMessageAsync(record) {
|
|
70
|
+
return this.queues.messages.enqueueAsync(`msg:${record.id}`, record);
|
|
71
|
+
}
|
|
72
|
+
persistThread(record) {
|
|
73
|
+
this.queues.threads.enqueue(`thread:${record.jid}`, record);
|
|
74
|
+
}
|
|
75
|
+
persistThreadAsync(record) {
|
|
76
|
+
return this.queues.threads.enqueueAsync(`thread:${record.jid}`, record);
|
|
77
|
+
}
|
|
78
|
+
persistContact(record) {
|
|
79
|
+
this.queues.contacts.enqueue(`contact:${record.jid}`, record);
|
|
80
|
+
}
|
|
81
|
+
persistContactAsync(record) {
|
|
82
|
+
return this.queues.contacts.enqueueAsync(`contact:${record.jid}`, record);
|
|
83
|
+
}
|
|
84
|
+
async flush(timeoutMs = this.flushTimeoutMs) {
|
|
85
|
+
const [messages, threads, contacts] = await Promise.all([
|
|
86
|
+
this.queues.messages.flush(timeoutMs),
|
|
87
|
+
this.queues.threads.flush(timeoutMs),
|
|
88
|
+
this.queues.contacts.flush(timeoutMs)
|
|
89
|
+
]);
|
|
90
|
+
const result = this.toDrainResult(messages, threads, contacts);
|
|
91
|
+
if (result.remaining > 0) {
|
|
92
|
+
this.logger.warn('write-behind flush finished with pending writes', {
|
|
93
|
+
messagesRemaining: messages.remaining,
|
|
94
|
+
threadsRemaining: threads.remaining,
|
|
95
|
+
contactsRemaining: contacts.remaining
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
async destroy(timeoutMs = this.flushTimeoutMs) {
|
|
101
|
+
const [messages, threads, contacts] = await Promise.all([
|
|
102
|
+
this.queues.messages.destroy(timeoutMs),
|
|
103
|
+
this.queues.threads.destroy(timeoutMs),
|
|
104
|
+
this.queues.contacts.destroy(timeoutMs)
|
|
105
|
+
]);
|
|
106
|
+
const result = this.toDrainResult(messages, threads, contacts);
|
|
107
|
+
if (result.remaining > 0) {
|
|
108
|
+
this.logger.warn('write-behind destroy finished with pending writes', {
|
|
109
|
+
messagesRemaining: messages.remaining,
|
|
110
|
+
threadsRemaining: threads.remaining,
|
|
111
|
+
contactsRemaining: contacts.remaining
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
toDrainResult(messages, threads, contacts) {
|
|
117
|
+
return {
|
|
118
|
+
messages,
|
|
119
|
+
threads,
|
|
120
|
+
contacts,
|
|
121
|
+
flushed: messages.flushed + threads.flushed + contacts.flushed,
|
|
122
|
+
remaining: messages.remaining + threads.remaining + contacts.remaining
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { hmacSign, importHmacKey } from '../../crypto/core/index.js';
|
|
2
|
+
import { TEXT_ENCODER } from '../../util/bytes.js';
|
|
3
|
+
import { setBoundedMapEntry } from '../../util/collections.js';
|
|
4
|
+
const CS_TOKEN_CACHE_MAX = 5;
|
|
5
|
+
export class CsTokenGenerator {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.cachedKey = null;
|
|
8
|
+
this.cachedSalt = null;
|
|
9
|
+
this.cache = new Map();
|
|
10
|
+
}
|
|
11
|
+
async generate(nctSalt, accountLid) {
|
|
12
|
+
const cached = this.cache.get(accountLid);
|
|
13
|
+
if (cached && this.isSameSalt(nctSalt)) {
|
|
14
|
+
return cached;
|
|
15
|
+
}
|
|
16
|
+
const key = await this.resolveKey(nctSalt);
|
|
17
|
+
const result = await hmacSign(key, TEXT_ENCODER.encode(accountLid));
|
|
18
|
+
setBoundedMapEntry(this.cache, accountLid, result, CS_TOKEN_CACHE_MAX);
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
invalidate() {
|
|
22
|
+
this.cachedKey = null;
|
|
23
|
+
this.cachedSalt = null;
|
|
24
|
+
this.cache.clear();
|
|
25
|
+
}
|
|
26
|
+
isSameSalt(salt) {
|
|
27
|
+
if (!this.cachedSalt || this.cachedSalt.length !== salt.length) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
for (let i = 0; i < salt.length; i += 1) {
|
|
31
|
+
if (this.cachedSalt[i] !== salt[i]) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
async resolveKey(salt) {
|
|
38
|
+
if (this.cachedKey && this.isSameSalt(salt)) {
|
|
39
|
+
return this.cachedKey;
|
|
40
|
+
}
|
|
41
|
+
this.cachedKey = await importHmacKey(salt);
|
|
42
|
+
this.cachedSalt = salt;
|
|
43
|
+
this.cache.clear();
|
|
44
|
+
return this.cachedKey;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function computeBucket(unixTimeS, durationS) {
|
|
2
|
+
return Math.floor(unixTimeS / durationS);
|
|
3
|
+
}
|
|
4
|
+
export function tokenExpirationCutoffS(nowS, durationS, numBuckets) {
|
|
5
|
+
const currentBucket = computeBucket(nowS, durationS);
|
|
6
|
+
const cutoffBucket = currentBucket - numBuckets;
|
|
7
|
+
return cutoffBucket * durationS;
|
|
8
|
+
}
|
|
9
|
+
export function isTokenExpired(tokenTimestampS, nowS, durationS, numBuckets) {
|
|
10
|
+
const cutoff = tokenExpirationCutoffS(nowS, durationS, numBuckets);
|
|
11
|
+
return tokenTimestampS < cutoff;
|
|
12
|
+
}
|
|
13
|
+
export function shouldSendNewToken(senderTimestampS, nowS, senderDurationS) {
|
|
14
|
+
return computeBucket(senderTimestampS, senderDurationS) !== computeBucket(nowS, senderDurationS);
|
|
15
|
+
}
|
|
16
|
+
export function clampDuration(durationS, maxDurationS) {
|
|
17
|
+
return Math.min(durationS, maxDurationS);
|
|
18
|
+
}
|
|
@@ -6,5 +6,5 @@ export { X25519 } from '../curves/X25519.js';
|
|
|
6
6
|
export { hkdf, hkdfSplit } from '../core/hkdf.js';
|
|
7
7
|
export { toSerializedPubKey, toRawPubKey, prependVersion, readVersionedContent } from '../core/keys.js';
|
|
8
8
|
export { buildNonce } from '../core/nonce.js';
|
|
9
|
-
export { randomBytesAsync, randomIntAsync } from '../core/random.js';
|
|
10
|
-
export { sha1, sha256, sha512, importAesGcmKey, aesGcmEncrypt, aesGcmDecrypt, importAesCbcKey, aesCbcEncrypt, aesCbcDecrypt, importHmacKey, importHmacSha512Key, hmacSign, pbkdf2DeriveAesCtrKey, aesCtrEncrypt, aesCtrDecrypt
|
|
9
|
+
export { randomBytesAsync, randomFillAsync, randomIntAsync } from '../core/random.js';
|
|
10
|
+
export { sha1, sha256, sha512, importAesGcmKey, aesGcmEncrypt, aesGcmDecrypt, importAesCbcKey, aesCbcEncrypt, aesCbcDecrypt, importHmacKey, importHmacSha512Key, hmacSign, pbkdf2DeriveAesCtrKey, aesCtrEncrypt, aesCtrDecrypt } from '../core/primitives.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds a 12-byte nonce for AES-GCM encryption with counter in the last 4 bytes.
|
|
3
|
+
* Allocates a new buffer per call because concurrent Noise encrypt/decrypt operations
|
|
4
|
+
* may hold references to different nonces simultaneously.
|
|
3
5
|
* Throws if counter exceeds uint32 range to prevent nonce reuse.
|
|
4
6
|
*/
|
|
5
7
|
export function buildNonce(counter) {
|
|
@@ -90,10 +90,3 @@ export async function aesCtrEncrypt(key, counter, plaintext) {
|
|
|
90
90
|
export async function aesCtrDecrypt(key, counter, ciphertext) {
|
|
91
91
|
return toBytesView(await webcrypto.subtle.decrypt({ name: 'AES-CTR', counter, length: 64 }, key, ciphertext));
|
|
92
92
|
}
|
|
93
|
-
// ============================================
|
|
94
|
-
// Ed25519 raw verify (for Signal variant sigs)
|
|
95
|
-
// ============================================
|
|
96
|
-
export async function ed25519VerifyRaw(publicKey, signature, message) {
|
|
97
|
-
const cryptoKey = await webcrypto.subtle.importKey('raw', publicKey, { name: 'Ed25519' }, false, ['verify']);
|
|
98
|
-
return webcrypto.subtle.verify('Ed25519', cryptoKey, signature, message);
|
|
99
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomBytes, randomInt } from 'node:crypto';
|
|
1
|
+
import { randomBytes, randomFill, randomInt } from 'node:crypto';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import { toBytesView } from '../../util/bytes.js';
|
|
4
4
|
const randomBytesAsyncImpl = promisify(randomBytes);
|
|
@@ -6,4 +6,25 @@ const randomIntAsyncImpl = promisify(randomInt);
|
|
|
6
6
|
export async function randomBytesAsync(size) {
|
|
7
7
|
return toBytesView(await randomBytesAsyncImpl(size));
|
|
8
8
|
}
|
|
9
|
+
export async function randomFillAsync(target, offset, size) {
|
|
10
|
+
await new Promise((resolve, reject) => {
|
|
11
|
+
const onDone = (error) => {
|
|
12
|
+
if (error) {
|
|
13
|
+
reject(error);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
resolve();
|
|
17
|
+
};
|
|
18
|
+
if (offset === undefined) {
|
|
19
|
+
randomFill(target, onDone);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (size === undefined) {
|
|
23
|
+
randomFill(target, offset, onDone);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
randomFill(target, offset, size, onDone);
|
|
27
|
+
});
|
|
28
|
+
return target;
|
|
29
|
+
}
|
|
9
30
|
export const randomIntAsync = randomIntAsyncImpl;
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { webcrypto } from 'node:crypto';
|
|
2
2
|
import { X25519_PKCS8_PREFIX } from '../curves/constants.js';
|
|
3
3
|
import { pkcs8FromRawPrivate } from '../curves/types.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { FE_ONE } from '../math/constants.js';
|
|
5
|
+
import { fe, feAdd, feFromBytes, feInv, feMul, fePack, feSub } from '../math/fe.js';
|
|
6
6
|
import { assertByteLength, decodeBase64Url, toBytesView } from '../../util/bytes.js';
|
|
7
|
+
// Pre-allocated temps for montgomeryToEdwardsPublic (safe: single-threaded)
|
|
8
|
+
const _mx = fe();
|
|
9
|
+
const _m1 = fe();
|
|
10
|
+
const _m2 = fe();
|
|
11
|
+
const _m3 = fe();
|
|
12
|
+
// p-1 = 2^255-20 in LE bytes: 0xEC, 0xFF×30, 0x7F
|
|
13
|
+
// Mask bit 255 before comparing (non-canonical inputs may have it set)
|
|
14
|
+
function isFieldPMinus1(b) {
|
|
15
|
+
if (b[0] !== 0xec || (b[31] & 0x7f) !== 0x7f)
|
|
16
|
+
return false;
|
|
17
|
+
for (let i = 1; i < 31; i++)
|
|
18
|
+
if (b[i] !== 0xff)
|
|
19
|
+
return false;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
7
22
|
export function clampCurvePrivateKeyInPlace(privateKey) {
|
|
8
23
|
assertByteLength(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
|
|
9
24
|
privateKey[0] &= 248;
|
|
@@ -13,12 +28,16 @@ export function clampCurvePrivateKeyInPlace(privateKey) {
|
|
|
13
28
|
}
|
|
14
29
|
export function montgomeryToEdwardsPublic(curvePublicKey, signBit) {
|
|
15
30
|
assertByteLength(curvePublicKey, 32, `invalid curve25519 public key length ${curvePublicKey.length}`);
|
|
16
|
-
|
|
17
|
-
if (x === FIELD_P - 1n) {
|
|
31
|
+
if (isFieldPMinus1(curvePublicKey)) {
|
|
18
32
|
throw new Error('invalid curve25519 low-order public key');
|
|
19
33
|
}
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
feFromBytes(_mx, curvePublicKey);
|
|
35
|
+
feSub(_m1, _mx, FE_ONE);
|
|
36
|
+
feAdd(_m2, _mx, FE_ONE);
|
|
37
|
+
feInv(_m3, _m2);
|
|
38
|
+
feMul(_m1, _m1, _m3);
|
|
39
|
+
const encoded = new Uint8Array(32);
|
|
40
|
+
fePack(encoded, _m1);
|
|
22
41
|
encoded[31] = (encoded[31] & 0x7f) | (signBit & 0x80);
|
|
23
42
|
return encoded;
|
|
24
43
|
}
|
package/dist/esm/crypto/index.js
CHANGED
|
@@ -1,41 +1,18 @@
|
|
|
1
|
+
import { fe, feFromBigInt } from '../math/fe.js';
|
|
1
2
|
export const FIELD_P = (1n << 255n) - 19n;
|
|
2
3
|
export const GROUP_L = (1n << 252n) + 27742317777372353535851937790883648493n;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
function modPowField(base, exponent) {
|
|
8
|
-
let result = 1n;
|
|
9
|
-
let current = modField(base);
|
|
10
|
-
let power = exponent;
|
|
11
|
-
while (power > 0n) {
|
|
12
|
-
if ((power & 1n) === 1n) {
|
|
13
|
-
result = modField(result * current);
|
|
14
|
-
}
|
|
15
|
-
current = modField(current * current);
|
|
16
|
-
power >>= 1n;
|
|
17
|
-
}
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
function modInvField(value) {
|
|
21
|
-
if (value === 0n) {
|
|
22
|
-
throw new Error('field inversion by zero');
|
|
23
|
-
}
|
|
24
|
-
return modPowField(value, FIELD_P - 2n);
|
|
25
|
-
}
|
|
26
|
-
const BASE_X = 15112221349535400772501151409588531511454012693041857206046113283949847762202n;
|
|
27
|
-
const BASE_Y = 46316835694926478169428394003475163141307993866256225615783033603165251855960n;
|
|
28
|
-
export const EDWARDS_D = modField(-121665n * modInvField(121666n));
|
|
29
|
-
export const TWO_D = modField(2n * EDWARDS_D);
|
|
4
|
+
export const FE_TWO_D = feFromBigInt(16295367250680780974490674513165176452449235426866156013048779062215315747161n);
|
|
5
|
+
export const FE_ZERO = fe();
|
|
6
|
+
export const FE_ONE = feFromBigInt(1n);
|
|
30
7
|
export const BASE_POINT = Object.freeze({
|
|
31
|
-
x:
|
|
32
|
-
y:
|
|
33
|
-
z: 1n,
|
|
34
|
-
t:
|
|
8
|
+
x: feFromBigInt(15112221349535400772501151409588531511454012693041857206046113283949847762202n),
|
|
9
|
+
y: feFromBigInt(46316835694926478169428394003475163141307993866256225615783033603165251855960n),
|
|
10
|
+
z: feFromBigInt(1n),
|
|
11
|
+
t: feFromBigInt(46827403850823179245072216630277197565144205554125654976674165829533817101731n)
|
|
35
12
|
});
|
|
36
13
|
export const IDENTITY_POINT = Object.freeze({
|
|
37
|
-
x: 0n,
|
|
38
|
-
y: 1n,
|
|
39
|
-
z: 1n,
|
|
40
|
-
t: 0n
|
|
14
|
+
x: feFromBigInt(0n),
|
|
15
|
+
y: feFromBigInt(1n),
|
|
16
|
+
z: feFromBigInt(1n),
|
|
17
|
+
t: feFromBigInt(0n)
|
|
41
18
|
});
|