@mtcute/core 0.1.0 → 0.1.2
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/cjs/base-client.js +4 -1
- package/cjs/base-client.js.map +1 -1
- package/cjs/network/auth-key.d.ts +3 -3
- package/cjs/network/auth-key.js +12 -12
- package/cjs/network/auth-key.js.map +1 -1
- package/cjs/network/auth-key.test.d.ts +1 -0
- package/cjs/network/auth-key.test.js +111 -0
- package/cjs/network/auth-key.test.js.map +1 -0
- package/cjs/network/authorization.js +62 -57
- package/cjs/network/authorization.js.map +1 -1
- package/cjs/network/config-manager.js +2 -1
- package/cjs/network/config-manager.js.map +1 -1
- package/cjs/network/config-manager.test.d.ts +1 -0
- package/cjs/network/config-manager.test.js +170 -0
- package/cjs/network/config-manager.test.js.map +1 -0
- package/cjs/network/mtproto-session.d.ts +2 -2
- package/cjs/network/mtproto-session.js +2 -2
- package/cjs/network/mtproto-session.js.map +1 -1
- package/cjs/network/multi-session-connection.d.ts +1 -1
- package/cjs/network/multi-session-connection.js +2 -2
- package/cjs/network/multi-session-connection.js.map +1 -1
- package/cjs/network/network-manager.d.ts +1 -0
- package/cjs/network/network-manager.js +21 -27
- package/cjs/network/network-manager.js.map +1 -1
- package/cjs/network/persistent-connection.test.d.ts +1 -0
- package/cjs/network/persistent-connection.test.js +157 -0
- package/cjs/network/persistent-connection.test.js.map +1 -0
- package/cjs/network/session-connection.d.ts +2 -1
- package/cjs/network/session-connection.js +51 -37
- package/cjs/network/session-connection.js.map +1 -1
- package/cjs/network/transports/intermediate.d.ts +3 -0
- package/cjs/network/transports/intermediate.js +5 -3
- package/cjs/network/transports/intermediate.js.map +1 -1
- package/cjs/network/transports/intermediate.test.d.ts +1 -0
- package/cjs/network/transports/intermediate.test.js +86 -0
- package/cjs/network/transports/intermediate.test.js.map +1 -0
- package/cjs/network/transports/obfuscated.js +15 -19
- package/cjs/network/transports/obfuscated.js.map +1 -1
- package/cjs/network/transports/obfuscated.test.d.ts +1 -0
- package/cjs/network/transports/obfuscated.test.js +131 -0
- package/cjs/network/transports/obfuscated.test.js.map +1 -0
- package/cjs/network/transports/tcp.js +1 -1
- package/cjs/network/transports/tcp.js.map +1 -1
- package/cjs/network/transports/tcp.test.d.ts +1 -0
- package/cjs/network/transports/tcp.test.js +97 -0
- package/cjs/network/transports/tcp.test.js.map +1 -0
- package/cjs/network/transports/websocket.test.d.ts +1 -0
- package/cjs/network/transports/websocket.test.js +91 -0
- package/cjs/network/transports/websocket.test.js.map +1 -0
- package/cjs/storage/abstract.d.ts +23 -2
- package/cjs/storage/abstract.js.map +1 -1
- package/cjs/storage/json.js +8 -9
- package/cjs/storage/json.js.map +1 -1
- package/cjs/storage/json.test.d.ts +1 -0
- package/cjs/storage/json.test.js +37 -0
- package/cjs/storage/json.test.js.map +1 -0
- package/cjs/storage/localstorage.js +5 -2
- package/cjs/storage/localstorage.js.map +1 -1
- package/cjs/storage/localstorage.test.d.ts +1 -0
- package/cjs/storage/localstorage.test.js +23 -0
- package/cjs/storage/localstorage.test.js.map +1 -0
- package/cjs/storage/memory.d.ts +7 -8
- package/cjs/storage/memory.js +7 -7
- package/cjs/storage/memory.js.map +1 -1
- package/cjs/storage/memory.test.d.ts +1 -0
- package/cjs/storage/memory.test.js +47 -0
- package/cjs/storage/memory.test.js.map +1 -0
- package/cjs/utils/async-lock.test.d.ts +1 -0
- package/cjs/utils/async-lock.test.js +25 -0
- package/cjs/utils/async-lock.test.js.map +1 -0
- package/cjs/utils/bigint-utils.d.ts +18 -11
- package/cjs/utils/bigint-utils.js +148 -47
- package/cjs/utils/bigint-utils.js.map +1 -1
- package/cjs/utils/bigint-utils.test.d.ts +1 -0
- package/cjs/utils/bigint-utils.test.js +150 -0
- package/cjs/utils/bigint-utils.test.js.map +1 -0
- package/cjs/utils/buffer-utils.d.ts +7 -1
- package/cjs/utils/buffer-utils.js +16 -3
- package/cjs/utils/buffer-utils.js.map +1 -1
- package/cjs/utils/buffer-utils.test.d.ts +1 -0
- package/cjs/utils/buffer-utils.test.js +69 -0
- package/cjs/utils/buffer-utils.test.js.map +1 -0
- package/cjs/utils/condition-variable.test.d.ts +1 -0
- package/cjs/utils/condition-variable.test.js +27 -0
- package/cjs/utils/condition-variable.test.js.map +1 -0
- package/cjs/utils/controllable-promise.test.d.ts +1 -0
- package/cjs/utils/controllable-promise.test.js +17 -0
- package/cjs/utils/controllable-promise.test.js.map +1 -0
- package/cjs/utils/crypto/abstract.d.ts +16 -9
- package/cjs/utils/crypto/abstract.js +6 -9
- package/cjs/utils/crypto/abstract.js.map +1 -1
- package/cjs/utils/crypto/factorization.d.ts +2 -1
- package/cjs/utils/crypto/factorization.js +28 -36
- package/cjs/utils/crypto/factorization.js.map +1 -1
- package/cjs/utils/crypto/index.d.ts +4 -0
- package/cjs/utils/crypto/index.js +4 -0
- package/cjs/utils/crypto/index.js.map +1 -1
- package/cjs/utils/crypto/keys.d.ts +2 -2
- package/cjs/utils/crypto/keys.js +4 -4
- package/cjs/utils/crypto/keys.js.map +1 -1
- package/cjs/utils/crypto/keys.test.d.ts +1 -0
- package/cjs/utils/crypto/keys.test.js +40 -0
- package/cjs/utils/crypto/keys.test.js.map +1 -0
- package/cjs/utils/crypto/miller-rabin.d.ts +2 -2
- package/cjs/utils/crypto/miller-rabin.js +20 -22
- package/cjs/utils/crypto/miller-rabin.js.map +1 -1
- package/cjs/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/cjs/utils/crypto/miller-rabin.test.js +60 -0
- package/cjs/utils/crypto/miller-rabin.test.js.map +1 -0
- package/cjs/utils/crypto/mtproto.d.ts +3 -3
- package/cjs/utils/crypto/mtproto.js +12 -12
- package/cjs/utils/crypto/mtproto.js.map +1 -1
- package/cjs/utils/crypto/mtproto.test.d.ts +1 -0
- package/cjs/utils/crypto/mtproto.test.js +47 -0
- package/cjs/utils/crypto/mtproto.test.js.map +1 -0
- package/cjs/utils/crypto/node.d.ts +21 -0
- package/cjs/utils/crypto/node.js +74 -0
- package/cjs/utils/crypto/node.js.map +1 -0
- package/cjs/utils/crypto/node.test.d.ts +1 -0
- package/cjs/utils/crypto/node.test.js +13 -0
- package/cjs/utils/crypto/node.test.js.map +1 -0
- package/cjs/utils/crypto/password.js +22 -33
- package/cjs/utils/crypto/password.js.map +1 -1
- package/cjs/utils/crypto/password.test.d.ts +1 -0
- package/cjs/utils/crypto/password.test.js +95 -0
- package/cjs/utils/crypto/password.test.js.map +1 -0
- package/cjs/utils/crypto/utils.test.d.ts +1 -0
- package/cjs/utils/crypto/utils.test.js +49 -0
- package/cjs/utils/crypto/utils.test.js.map +1 -0
- package/cjs/utils/crypto/wasm.d.ts +22 -0
- package/cjs/utils/crypto/wasm.js +41 -0
- package/cjs/utils/crypto/wasm.js.map +1 -0
- package/cjs/utils/crypto/web.d.ts +11 -0
- package/cjs/utils/crypto/web.js +40 -0
- package/cjs/utils/crypto/web.js.map +1 -0
- package/cjs/utils/crypto/web.test.d.ts +1 -0
- package/cjs/utils/crypto/web.test.js +17 -0
- package/cjs/utils/crypto/web.test.js.map +1 -0
- package/cjs/utils/deque.d.ts +1 -1
- package/cjs/utils/deque.js +9 -3
- package/cjs/utils/deque.js.map +1 -1
- package/cjs/utils/deque.test.d.ts +1 -0
- package/cjs/utils/deque.test.js +128 -0
- package/cjs/utils/deque.test.js.map +1 -0
- package/cjs/utils/function-utils.d.ts +4 -1
- package/cjs/utils/function-utils.js +8 -1
- package/cjs/utils/function-utils.js.map +1 -1
- package/cjs/utils/function-utils.test.d.ts +1 -0
- package/cjs/utils/function-utils.test.js +23 -0
- package/cjs/utils/function-utils.test.js.map +1 -0
- package/cjs/utils/index.d.ts +0 -1
- package/cjs/utils/index.js +0 -1
- package/cjs/utils/index.js.map +1 -1
- package/cjs/utils/linked-list.test.d.ts +1 -0
- package/cjs/utils/linked-list.test.js +36 -0
- package/cjs/utils/linked-list.test.js.map +1 -0
- package/cjs/utils/links/bots.test.d.ts +1 -0
- package/cjs/utils/links/bots.test.js +152 -0
- package/cjs/utils/links/bots.test.js.map +1 -0
- package/cjs/utils/links/chat.test.d.ts +1 -0
- package/cjs/utils/links/chat.test.js +84 -0
- package/cjs/utils/links/chat.test.js.map +1 -0
- package/cjs/utils/links/misc.test.d.ts +1 -0
- package/cjs/utils/links/misc.test.js +153 -0
- package/cjs/utils/links/misc.test.js.map +1 -0
- package/cjs/utils/links/proxy.test.d.ts +1 -0
- package/cjs/utils/links/proxy.test.js +74 -0
- package/cjs/utils/links/proxy.test.js.map +1 -0
- package/cjs/utils/links/user.test.d.ts +1 -0
- package/cjs/utils/links/user.test.js +63 -0
- package/cjs/utils/links/user.test.js.map +1 -0
- package/cjs/utils/logger.d.ts +0 -1
- package/cjs/utils/logger.js +3 -4
- package/cjs/utils/logger.js.map +1 -1
- package/cjs/utils/logger.test.d.ts +1 -0
- package/cjs/utils/logger.test.js +125 -0
- package/cjs/utils/logger.test.js.map +1 -0
- package/cjs/utils/long-utils.test.d.ts +1 -0
- package/cjs/utils/long-utils.test.js +158 -0
- package/cjs/utils/long-utils.test.js.map +1 -0
- package/cjs/utils/lru-map.d.ts +1 -0
- package/cjs/utils/lru-map.js +6 -0
- package/cjs/utils/lru-map.js.map +1 -1
- package/cjs/utils/lru-map.test.d.ts +1 -0
- package/cjs/utils/lru-map.test.js +96 -0
- package/cjs/utils/lru-map.test.js.map +1 -0
- package/cjs/utils/lru-set.test.d.ts +1 -0
- package/cjs/utils/lru-set.test.js +77 -0
- package/cjs/utils/lru-set.test.js.map +1 -0
- package/cjs/utils/peer-utils.js +5 -1
- package/cjs/utils/peer-utils.js.map +1 -1
- package/cjs/utils/peer-utils.test.d.ts +1 -0
- package/cjs/utils/peer-utils.test.js +122 -0
- package/cjs/utils/peer-utils.test.js.map +1 -0
- package/cjs/utils/platform/crypto.js +2 -2
- package/cjs/utils/platform/crypto.js.map +1 -1
- package/cjs/utils/platform/crypto.web.js +2 -2
- package/cjs/utils/platform/crypto.web.js.map +1 -1
- package/cjs/utils/sorted-array.test.d.ts +1 -0
- package/cjs/utils/sorted-array.test.js +66 -0
- package/cjs/utils/sorted-array.test.js.map +1 -0
- package/cjs/utils/string-session.js +4 -2
- package/cjs/utils/string-session.js.map +1 -1
- package/cjs/utils/string-session.test.d.ts +1 -0
- package/cjs/utils/string-session.test.js +106 -0
- package/cjs/utils/string-session.test.js.map +1 -0
- package/cjs/utils/tl-json.test.d.ts +1 -0
- package/cjs/utils/tl-json.test.js +83 -0
- package/cjs/utils/tl-json.test.js.map +1 -0
- package/cjs/utils/type-assertions.test.d.ts +1 -0
- package/cjs/utils/type-assertions.test.js +67 -0
- package/cjs/utils/type-assertions.test.js.map +1 -0
- package/esm/base-client.js +4 -1
- package/esm/base-client.js.map +1 -1
- package/esm/network/auth-key.d.ts +3 -3
- package/esm/network/auth-key.js +13 -13
- package/esm/network/auth-key.js.map +1 -1
- package/esm/network/auth-key.test.d.ts +1 -0
- package/esm/network/auth-key.test.js +106 -0
- package/esm/network/auth-key.test.js.map +1 -0
- package/esm/network/authorization.js +64 -59
- package/esm/network/authorization.js.map +1 -1
- package/esm/network/config-manager.js +2 -1
- package/esm/network/config-manager.js.map +1 -1
- package/esm/network/config-manager.test.d.ts +1 -0
- package/esm/network/config-manager.test.js +168 -0
- package/esm/network/config-manager.test.js.map +1 -0
- package/esm/network/mtproto-session.d.ts +2 -2
- package/esm/network/mtproto-session.js +2 -2
- package/esm/network/mtproto-session.js.map +1 -1
- package/esm/network/multi-session-connection.d.ts +1 -1
- package/esm/network/multi-session-connection.js +2 -2
- package/esm/network/multi-session-connection.js.map +1 -1
- package/esm/network/network-manager.d.ts +1 -0
- package/esm/network/network-manager.js +21 -27
- package/esm/network/network-manager.js.map +1 -1
- package/esm/network/persistent-connection.test.d.ts +1 -0
- package/esm/network/persistent-connection.test.js +155 -0
- package/esm/network/persistent-connection.test.js.map +1 -0
- package/esm/network/session-connection.d.ts +2 -1
- package/esm/network/session-connection.js +53 -39
- package/esm/network/session-connection.js.map +1 -1
- package/esm/network/transports/intermediate.d.ts +3 -0
- package/esm/network/transports/intermediate.js +6 -4
- package/esm/network/transports/intermediate.js.map +1 -1
- package/esm/network/transports/intermediate.test.d.ts +1 -0
- package/esm/network/transports/intermediate.test.js +84 -0
- package/esm/network/transports/intermediate.test.js.map +1 -0
- package/esm/network/transports/obfuscated.js +16 -20
- package/esm/network/transports/obfuscated.js.map +1 -1
- package/esm/network/transports/obfuscated.test.d.ts +1 -0
- package/esm/network/transports/obfuscated.test.js +129 -0
- package/esm/network/transports/obfuscated.test.js.map +1 -0
- package/esm/network/transports/tcp.js +1 -1
- package/esm/network/transports/tcp.js.map +1 -1
- package/esm/network/transports/tcp.test.d.ts +1 -0
- package/esm/network/transports/tcp.test.js +95 -0
- package/esm/network/transports/tcp.test.js.map +1 -0
- package/esm/network/transports/websocket.test.d.ts +1 -0
- package/esm/network/transports/websocket.test.js +89 -0
- package/esm/network/transports/websocket.test.js.map +1 -0
- package/esm/storage/abstract.d.ts +23 -2
- package/esm/storage/abstract.js.map +1 -1
- package/esm/storage/json.js +8 -9
- package/esm/storage/json.js.map +1 -1
- package/esm/storage/json.test.d.ts +1 -0
- package/esm/storage/json.test.js +35 -0
- package/esm/storage/json.test.js.map +1 -0
- package/esm/storage/localstorage.js +5 -2
- package/esm/storage/localstorage.js.map +1 -1
- package/esm/storage/localstorage.test.d.ts +1 -0
- package/esm/storage/localstorage.test.js +21 -0
- package/esm/storage/localstorage.test.js.map +1 -0
- package/esm/storage/memory.d.ts +7 -8
- package/esm/storage/memory.js +7 -7
- package/esm/storage/memory.js.map +1 -1
- package/esm/storage/memory.test.d.ts +1 -0
- package/esm/storage/memory.test.js +45 -0
- package/esm/storage/memory.test.js.map +1 -0
- package/esm/utils/async-lock.test.d.ts +1 -0
- package/esm/utils/async-lock.test.js +23 -0
- package/esm/utils/async-lock.test.js.map +1 -0
- package/esm/utils/bigint-utils.d.ts +18 -11
- package/esm/utils/bigint-utils.js +142 -44
- package/esm/utils/bigint-utils.js.map +1 -1
- package/esm/utils/bigint-utils.test.d.ts +1 -0
- package/esm/utils/bigint-utils.test.js +148 -0
- package/esm/utils/bigint-utils.test.js.map +1 -0
- package/esm/utils/buffer-utils.d.ts +7 -1
- package/esm/utils/buffer-utils.js +14 -1
- package/esm/utils/buffer-utils.js.map +1 -1
- package/esm/utils/buffer-utils.test.d.ts +1 -0
- package/esm/utils/buffer-utils.test.js +67 -0
- package/esm/utils/buffer-utils.test.js.map +1 -0
- package/esm/utils/condition-variable.test.d.ts +1 -0
- package/esm/utils/condition-variable.test.js +25 -0
- package/esm/utils/condition-variable.test.js.map +1 -0
- package/esm/utils/controllable-promise.test.d.ts +1 -0
- package/esm/utils/controllable-promise.test.js +15 -0
- package/esm/utils/controllable-promise.test.js.map +1 -0
- package/esm/utils/crypto/abstract.d.ts +16 -9
- package/esm/utils/crypto/abstract.js +6 -9
- package/esm/utils/crypto/abstract.js.map +1 -1
- package/esm/utils/crypto/factorization.d.ts +2 -1
- package/esm/utils/crypto/factorization.js +29 -34
- package/esm/utils/crypto/factorization.js.map +1 -1
- package/esm/utils/crypto/index.d.ts +4 -0
- package/esm/utils/crypto/index.js +4 -0
- package/esm/utils/crypto/index.js.map +1 -1
- package/esm/utils/crypto/keys.d.ts +2 -2
- package/esm/utils/crypto/keys.js +4 -4
- package/esm/utils/crypto/keys.js.map +1 -1
- package/esm/utils/crypto/keys.test.d.ts +1 -0
- package/esm/utils/crypto/keys.test.js +38 -0
- package/esm/utils/crypto/keys.test.js.map +1 -0
- package/esm/utils/crypto/miller-rabin.d.ts +2 -2
- package/esm/utils/crypto/miller-rabin.js +21 -20
- package/esm/utils/crypto/miller-rabin.js.map +1 -1
- package/esm/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/esm/utils/crypto/miller-rabin.test.js +58 -0
- package/esm/utils/crypto/miller-rabin.test.js.map +1 -0
- package/esm/utils/crypto/mtproto.d.ts +3 -3
- package/esm/utils/crypto/mtproto.js +12 -12
- package/esm/utils/crypto/mtproto.js.map +1 -1
- package/esm/utils/crypto/mtproto.test.d.ts +1 -0
- package/esm/utils/crypto/mtproto.test.js +45 -0
- package/esm/utils/crypto/mtproto.test.js.map +1 -0
- package/esm/utils/crypto/node.d.ts +21 -0
- package/esm/utils/crypto/node.js +69 -0
- package/esm/utils/crypto/node.js.map +1 -0
- package/esm/utils/crypto/node.test.d.ts +1 -0
- package/esm/utils/crypto/node.test.js +11 -0
- package/esm/utils/crypto/node.test.js.map +1 -0
- package/esm/utils/crypto/password.js +24 -32
- package/esm/utils/crypto/password.js.map +1 -1
- package/esm/utils/crypto/password.test.d.ts +1 -0
- package/esm/utils/crypto/password.test.js +90 -0
- package/esm/utils/crypto/password.test.js.map +1 -0
- package/esm/utils/crypto/utils.test.d.ts +1 -0
- package/esm/utils/crypto/utils.test.js +47 -0
- package/esm/utils/crypto/utils.test.js.map +1 -0
- package/esm/utils/crypto/wasm.d.ts +22 -0
- package/esm/utils/crypto/wasm.js +37 -0
- package/esm/utils/crypto/wasm.js.map +1 -0
- package/esm/utils/crypto/web.d.ts +11 -0
- package/esm/utils/crypto/web.js +36 -0
- package/esm/utils/crypto/web.js.map +1 -0
- package/esm/utils/crypto/web.test.d.ts +1 -0
- package/esm/utils/crypto/web.test.js +15 -0
- package/esm/utils/crypto/web.test.js.map +1 -0
- package/esm/utils/deque.d.ts +1 -1
- package/esm/utils/deque.js +9 -3
- package/esm/utils/deque.js.map +1 -1
- package/esm/utils/deque.test.d.ts +1 -0
- package/esm/utils/deque.test.js +126 -0
- package/esm/utils/deque.test.js.map +1 -0
- package/esm/utils/function-utils.d.ts +4 -1
- package/esm/utils/function-utils.js +8 -1
- package/esm/utils/function-utils.js.map +1 -1
- package/esm/utils/function-utils.test.d.ts +1 -0
- package/esm/utils/function-utils.test.js +21 -0
- package/esm/utils/function-utils.test.js.map +1 -0
- package/esm/utils/index.d.ts +0 -1
- package/esm/utils/index.js +0 -1
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/linked-list.test.d.ts +1 -0
- package/esm/utils/linked-list.test.js +34 -0
- package/esm/utils/linked-list.test.js.map +1 -0
- package/esm/utils/links/bots.test.d.ts +1 -0
- package/esm/utils/links/bots.test.js +150 -0
- package/esm/utils/links/bots.test.js.map +1 -0
- package/esm/utils/links/chat.test.d.ts +1 -0
- package/esm/utils/links/chat.test.js +82 -0
- package/esm/utils/links/chat.test.js.map +1 -0
- package/esm/utils/links/misc.test.d.ts +1 -0
- package/esm/utils/links/misc.test.js +151 -0
- package/esm/utils/links/misc.test.js.map +1 -0
- package/esm/utils/links/proxy.test.d.ts +1 -0
- package/esm/utils/links/proxy.test.js +72 -0
- package/esm/utils/links/proxy.test.js.map +1 -0
- package/esm/utils/links/user.test.d.ts +1 -0
- package/esm/utils/links/user.test.js +61 -0
- package/esm/utils/links/user.test.js.map +1 -0
- package/esm/utils/logger.d.ts +0 -1
- package/esm/utils/logger.js +3 -4
- package/esm/utils/logger.js.map +1 -1
- package/esm/utils/logger.test.d.ts +1 -0
- package/esm/utils/logger.test.js +120 -0
- package/esm/utils/logger.test.js.map +1 -0
- package/esm/utils/long-utils.test.d.ts +1 -0
- package/esm/utils/long-utils.test.js +153 -0
- package/esm/utils/long-utils.test.js.map +1 -0
- package/esm/utils/lru-map.d.ts +1 -0
- package/esm/utils/lru-map.js +6 -0
- package/esm/utils/lru-map.js.map +1 -1
- package/esm/utils/lru-map.test.d.ts +1 -0
- package/esm/utils/lru-map.test.js +94 -0
- package/esm/utils/lru-map.test.js.map +1 -0
- package/esm/utils/lru-set.test.d.ts +1 -0
- package/esm/utils/lru-set.test.js +72 -0
- package/esm/utils/lru-set.test.js.map +1 -0
- package/esm/utils/peer-utils.js +5 -1
- package/esm/utils/peer-utils.js.map +1 -1
- package/esm/utils/peer-utils.test.d.ts +1 -0
- package/esm/utils/peer-utils.test.js +117 -0
- package/esm/utils/peer-utils.test.js.map +1 -0
- package/esm/utils/platform/crypto.js +1 -1
- package/esm/utils/platform/crypto.js.map +1 -1
- package/esm/utils/platform/crypto.web.js +2 -2
- package/esm/utils/platform/crypto.web.js.map +1 -1
- package/esm/utils/sorted-array.test.d.ts +1 -0
- package/esm/utils/sorted-array.test.js +64 -0
- package/esm/utils/sorted-array.test.js.map +1 -0
- package/esm/utils/string-session.js +4 -2
- package/esm/utils/string-session.js.map +1 -1
- package/esm/utils/string-session.test.d.ts +1 -0
- package/esm/utils/string-session.test.js +104 -0
- package/esm/utils/string-session.test.js.map +1 -0
- package/esm/utils/tl-json.test.d.ts +1 -0
- package/esm/utils/tl-json.test.js +81 -0
- package/esm/utils/tl-json.test.js.map +1 -0
- package/esm/utils/type-assertions.test.d.ts +1 -0
- package/esm/utils/type-assertions.test.js +65 -0
- package/esm/utils/type-assertions.test.js.map +1 -0
- package/package.json +4 -5
- package/cjs/utils/crypto/common.d.ts +0 -12
- package/cjs/utils/crypto/common.js +0 -54
- package/cjs/utils/crypto/common.js.map +0 -1
- package/cjs/utils/crypto/node-crypto.d.ts +0 -10
- package/cjs/utils/crypto/node-crypto.js +0 -46
- package/cjs/utils/crypto/node-crypto.js.map +0 -1
- package/cjs/utils/crypto/subtle.d.ts +0 -12
- package/cjs/utils/crypto/subtle.js +0 -86
- package/cjs/utils/crypto/subtle.js.map +0 -1
- package/cjs/utils/flood-control.d.ts +0 -14
- package/cjs/utils/flood-control.js +0 -65
- package/cjs/utils/flood-control.js.map +0 -1
- package/cjs/utils/platform/random.d.ts +0 -1
- package/cjs/utils/platform/random.js +0 -7
- package/cjs/utils/platform/random.js.map +0 -1
- package/cjs/utils/platform/random.web.d.ts +0 -1
- package/cjs/utils/platform/random.web.js +0 -10
- package/cjs/utils/platform/random.web.js.map +0 -1
- package/esm/utils/crypto/common.d.ts +0 -12
- package/esm/utils/crypto/common.js +0 -50
- package/esm/utils/crypto/common.js.map +0 -1
- package/esm/utils/crypto/node-crypto.d.ts +0 -10
- package/esm/utils/crypto/node-crypto.js +0 -42
- package/esm/utils/crypto/node-crypto.js.map +0 -1
- package/esm/utils/crypto/subtle.d.ts +0 -12
- package/esm/utils/crypto/subtle.js +0 -59
- package/esm/utils/crypto/subtle.js.map +0 -1
- package/esm/utils/flood-control.d.ts +0 -14
- package/esm/utils/flood-control.js +0 -61
- package/esm/utils/flood-control.js.map +0 -1
- package/esm/utils/platform/random.d.ts +0 -1
- package/esm/utils/platform/random.js +0 -4
- package/esm/utils/platform/random.js.map +0 -1
- package/esm/utils/platform/random.web.d.ts +0 -1
- package/esm/utils/platform/random.web.js +0 -6
- package/esm/utils/platform/random.web.js.map +0 -1
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export function millerRabin(n, rounds = 20) {
|
|
1
|
+
import { bigIntBitLength, bigIntModPow, randomBigIntBits, twoMultiplicity } from '../bigint-utils.js';
|
|
2
|
+
export function millerRabin(crypto, n, rounds = 20) {
|
|
4
3
|
// small numbers: 0, 1 are not prime, 2, 3 are prime
|
|
5
|
-
if (n
|
|
6
|
-
return n
|
|
7
|
-
if (n
|
|
4
|
+
if (n < 4n)
|
|
5
|
+
return n > 1n;
|
|
6
|
+
if (n % 2n === 0n || n < 0n)
|
|
8
7
|
return false;
|
|
9
|
-
const nBits = n
|
|
10
|
-
const nSub = n
|
|
8
|
+
const nBits = bigIntBitLength(n);
|
|
9
|
+
const nSub = n - 1n;
|
|
11
10
|
const r = twoMultiplicity(nSub);
|
|
12
|
-
const d = nSub
|
|
11
|
+
const d = nSub >> r;
|
|
13
12
|
for (let i = 0; i < rounds; i++) {
|
|
14
13
|
let base;
|
|
15
14
|
do {
|
|
16
|
-
base = randomBigIntBits(nBits);
|
|
17
|
-
} while (base
|
|
18
|
-
let x = base
|
|
19
|
-
if (x.eq(bigInt.one) || x.eq(nSub))
|
|
15
|
+
base = randomBigIntBits(crypto, nBits);
|
|
16
|
+
} while (base <= 1n || base >= nSub);
|
|
17
|
+
let x = bigIntModPow(base, d, n);
|
|
18
|
+
// if (x.eq(bigInt.one) || x.eq(nSub)) continue
|
|
19
|
+
if (x === 1n || x === nSub)
|
|
20
20
|
continue;
|
|
21
|
-
let i =
|
|
21
|
+
let i = 0n;
|
|
22
22
|
let y;
|
|
23
|
-
while (i
|
|
24
|
-
y = x.modPow(bigInt[2], n)
|
|
25
|
-
|
|
23
|
+
while (i < r) {
|
|
24
|
+
// y = x.modPow(bigInt[2], n)
|
|
25
|
+
y = bigIntModPow(x, 2n, n);
|
|
26
|
+
if (x === 1n)
|
|
26
27
|
return false;
|
|
27
|
-
if (x
|
|
28
|
+
if (x === nSub)
|
|
28
29
|
break;
|
|
29
|
-
i
|
|
30
|
+
i += 1n;
|
|
30
31
|
x = y;
|
|
31
32
|
}
|
|
32
|
-
if (i
|
|
33
|
+
if (i === r)
|
|
33
34
|
return false;
|
|
34
35
|
}
|
|
35
36
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"miller-rabin.js","sourceRoot":"","sources":["../../../../src/utils/crypto/miller-rabin.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"miller-rabin.js","sourceRoot":"","sources":["../../../../src/utils/crypto/miller-rabin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGrG,MAAM,UAAU,WAAW,CAAC,MAAuB,EAAE,CAAS,EAAE,MAAM,GAAG,EAAE;IACvE,oDAAoD;IACpD,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,KAAK,CAAA;IAEzC,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;IAChC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAA;IAEnB,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;IAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;QAC7B,IAAI,IAAI,CAAA;QAER,GAAG;YACC,IAAI,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;SACzC,QAAQ,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,EAAC;QAEpC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAChC,+CAA+C;QAC/C,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI;YAAE,SAAQ;QAEpC,IAAI,CAAC,GAAG,EAAE,CAAA;QACV,IAAI,CAAS,CAAA;QAEb,OAAO,CAAC,GAAG,CAAC,EAAE;YACV,6BAA6B;YAC7B,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAE1B,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,KAAK,CAAA;YAC1B,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAK;YACrB,CAAC,IAAI,EAAE,CAAA;YAEP,CAAC,GAAG,CAAC,CAAA;SACR;QAED,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;KAC5B;IAED,OAAO,IAAI,CAAA;AACf,CAAC","sourcesContent":["import { bigIntBitLength, bigIntModPow, randomBigIntBits, twoMultiplicity } from '../bigint-utils.js'\nimport { ICryptoProvider } from './abstract.js'\n\nexport function millerRabin(crypto: ICryptoProvider, n: bigint, rounds = 20): boolean {\n // small numbers: 0, 1 are not prime, 2, 3 are prime\n if (n < 4n) return n > 1n\n if (n % 2n === 0n || n < 0n) return false\n\n const nBits = bigIntBitLength(n)\n const nSub = n - 1n\n\n const r = twoMultiplicity(nSub)\n const d = nSub >> r\n\n for (let i = 0; i < rounds; i++) {\n let base\n\n do {\n base = randomBigIntBits(crypto, nBits)\n } while (base <= 1n || base >= nSub)\n\n let x = bigIntModPow(base, d, n)\n // if (x.eq(bigInt.one) || x.eq(nSub)) continue\n if (x === 1n || x === nSub) continue\n\n let i = 0n\n let y: bigint\n\n while (i < r) {\n // y = x.modPow(bigInt[2], n)\n y = bigIntModPow(x, 2n, n)\n\n if (x === 1n) return false\n if (x === nSub) break\n i += 1n\n\n x = y\n }\n\n if (i === r) return false\n }\n\n return true\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { defaultCryptoProviderFactory } from './index.js';
|
|
3
|
+
import { millerRabin } from './miller-rabin.js';
|
|
4
|
+
describe('miller-rabin test', function () {
|
|
5
|
+
// miller-rabin factorization relies on RNG, so we should use a real random number generator
|
|
6
|
+
const c = defaultCryptoProviderFactory();
|
|
7
|
+
const testMillerRabin = (n, isPrime) => {
|
|
8
|
+
expect(millerRabin(c, BigInt(n))).eq(isPrime);
|
|
9
|
+
};
|
|
10
|
+
it('should correctly label small primes as probable primes', () => {
|
|
11
|
+
const smallOddPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
|
|
12
|
+
for (const prime of smallOddPrimes) {
|
|
13
|
+
testMillerRabin(prime, true);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
it('should correctly label small odd composite numbers as composite', () => {
|
|
17
|
+
const smallOddPrimes = [9, 15, 21, 25, 27, 33, 35];
|
|
18
|
+
for (const prime of smallOddPrimes) {
|
|
19
|
+
testMillerRabin(prime, false);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// primes are generated using `openssl prime -generate -bits <bits>`
|
|
23
|
+
it('should work for 512-bit numbers', () => {
|
|
24
|
+
testMillerRabin('8411445470921866378538628788380866906358949375899610911537071281076627385046125382763689993349183284546479522400013151510610266158235924343045768103605519', true);
|
|
25
|
+
testMillerRabin('11167561990563990242158096122232207092938761092751537312016255867850441858086589598418467012717458858604863547175649456433632887622140170743409535470973399', true);
|
|
26
|
+
testMillerRabin('11006717791910450367418249787526506184731090161438431250022510598653874155081488487035840577645711578911087148186160668569071839053453201592321650008610329', true);
|
|
27
|
+
testMillerRabin('12224330340162812215033324917156282302617911690617664923428569636370785775561435789211091021550357876767050350997458404009005800772805534351607294516706177', true);
|
|
28
|
+
// above numbers but -2 (not prime)
|
|
29
|
+
testMillerRabin('8411445470921866378538628788380866906358949375899610911537071281076627385046125382763689993349183284546479522400013151510610266158235924343045768103605517', false);
|
|
30
|
+
testMillerRabin('11167561990563990242158096122232207092938761092751537312016255867850441858086589598418467012717458858604863547175649456433632887622140170743409535470973397', false);
|
|
31
|
+
testMillerRabin('11006717791910450367418249787526506184731090161438431250022510598653874155081488487035840577645711578911087148186160668569071839053453201592321650008610327', false);
|
|
32
|
+
testMillerRabin('12224330340162812215033324917156282302617911690617664923428569636370785775561435789211091021550357876767050350997458404009005800772805534351607294516706175', false);
|
|
33
|
+
});
|
|
34
|
+
it('should work for 1024-bit numbers', () => {
|
|
35
|
+
testMillerRabin('94163180970530844245052892199633535954736903357996153321496979115367320260897793334681106861766748541439161886270777106456088209508872459550450259737267142959061663564218457086654112219462515165219295402175541003899136060178102898376369981338103600856012709228116661479275753497725541132207243717937379815409', true);
|
|
36
|
+
testMillerRabin('97324962433497727515811278760066576725849776656602017497363465683978397629803148191267105308901733336070351381654371470561376353774017284623969415330564867697353080030917333974193741719718950105404732792050882127213356260415251087867407489400712288570880407613514781891914135956778687719588061176455381937003', true);
|
|
37
|
+
testMillerRabin('92511311413226091818378551616231701579277597795073142338527410334932345968554993390789667936819230228388142960299649466238701015865565141753710450319875546944139442823075990348978746055937500467483161699883905850192191164043687791185635729923497381849380102040768674652775240505782671289535260164547714030567', true);
|
|
38
|
+
testMillerRabin('98801756216479639848708157708947504990501845258427605711852570166662700681215707617225664134994147912417941920327932092748574265476658124536672887141144222716123085451749764522435906007567360583062117498919471220566974634924384147341592903939264267901029640119196259026154529723870788246284629644039137378253', true);
|
|
39
|
+
// above numbers but -2 (not prime)
|
|
40
|
+
testMillerRabin('94163180970530844245052892199633535954736903357996153321496979115367320260897793334681106861766748541439161886270777106456088209508872459550450259737267142959061663564218457086654112219462515165219295402175541003899136060178102898376369981338103600856012709228116661479275753497725541132207243717937379815407', false);
|
|
41
|
+
testMillerRabin('97324962433497727515811278760066576725849776656602017497363465683978397629803148191267105308901733336070351381654371470561376353774017284623969415330564867697353080030917333974193741719718950105404732792050882127213356260415251087867407489400712288570880407613514781891914135956778687719588061176455381937001', false);
|
|
42
|
+
testMillerRabin('92511311413226091818378551616231701579277597795073142338527410334932345968554993390789667936819230228388142960299649466238701015865565141753710450319875546944139442823075990348978746055937500467483161699883905850192191164043687791185635729923497381849380102040768674652775240505782671289535260164547714030565', false);
|
|
43
|
+
testMillerRabin('98801756216479639848708157708947504990501845258427605711852570166662700681215707617225664134994147912417941920327932092748574265476658124536672887141144222716123085451749764522435906007567360583062117498919471220566974634924384147341592903939264267901029640119196259026154529723870788246284629644039137378251', false);
|
|
44
|
+
});
|
|
45
|
+
it('should work for 2048-bit numbers', () => {
|
|
46
|
+
testMillerRabin('28608382334358769588283288249494859626901014972463291352091976543138105382282108662849885913053034513852843449409838151123568984617793641641937583673207501643041336002587032201383537626393235736734494131431069043382068545865505150651648610506542819001961332454611129372758714288168807328523359776577571626967649079147416191592855529888846889532625386469236278694936872628305052827422772792103722178298844645210242389265273407924858034431614414896134561928996888883994953322861399988094086562513898527391555490352156627307769278185444897960555995383228897584818577375695810423475039211516849716140051437120083274285367', true);
|
|
47
|
+
testMillerRabin('30244022694659482453371920976249272809817388822378671144866806600284132009663832003348737406289715119965835410140834733465553787513841966120831322372642881643693711233087233983267648392814127424201572290931937482043046169402667397610783447368703776842799852222745601531140231486417855517072392416789672922529566643118973930252809010605519948446055538976582290902060054788109497630796585770940656002892943575479533099350429655210881833493066716819282707441553612603960556051122162329171373373251909387401572866056121964608595895425640834764028568120995397759283490218181167000161310959711677055741632674632758727382743', true);
|
|
48
|
+
testMillerRabin('30560953105766401423987964658775999222308579908395527900931049506803845883459894704297458477118152899910620180302473409631442956208933061650967001020981432894530064472547770442696756724169958362395601360296775798187903794894866967342028337982275745956538015473621792510615113531964380246815875830970404687926061637030085629909804357717955251735074071072456074274947993921828878633638119117086342305530526661796817095624933200483138188878398983149622639425550360394901699701985050966685840649129419227936413574227792077082510807968104733387734970009620450108276446659342203263759999068046251645984039420643003580284779', true);
|
|
49
|
+
// above numbers but -2 (not prime)
|
|
50
|
+
testMillerRabin('28608382334358769588283288249494859626901014972463291352091976543138105382282108662849885913053034513852843449409838151123568984617793641641937583673207501643041336002587032201383537626393235736734494131431069043382068545865505150651648610506542819001961332454611129372758714288168807328523359776577571626967649079147416191592855529888846889532625386469236278694936872628305052827422772792103722178298844645210242389265273407924858034431614414896134561928996888883994953322861399988094086562513898527391555490352156627307769278185444897960555995383228897584818577375695810423475039211516849716140051437120083274285365', false);
|
|
51
|
+
testMillerRabin('30244022694659482453371920976249272809817388822378671144866806600284132009663832003348737406289715119965835410140834733465553787513841966120831322372642881643693711233087233983267648392814127424201572290931937482043046169402667397610783447368703776842799852222745601531140231486417855517072392416789672922529566643118973930252809010605519948446055538976582290902060054788109497630796585770940656002892943575479533099350429655210881833493066716819282707441553612603960556051122162329171373373251909387401572866056121964608595895425640834764028568120995397759283490218181167000161310959711677055741632674632758727382741', false);
|
|
52
|
+
testMillerRabin('30560953105766401423987964658775999222308579908395527900931049506803845883459894704297458477118152899910620180302473409631442956208933061650967001020981432894530064472547770442696756724169958362395601360296775798187903794894866967342028337982275745956538015473621792510615113531964380246815875830970404687926061637030085629909804357717955251735074071072456074274947993921828878633638119117086342305530526661796817095624933200483138188878398983149622639425550360394901699701985050966685840649129419227936413574227792077082510807968104733387734970009620450108276446659342203263759999068046251645984039420643003580284777', false);
|
|
53
|
+
// dh_prime used by telegram, as seen in https://core.telegram.org/mtproto/security_guidelines
|
|
54
|
+
const telegramDhPrime = 'C7 1C AE B9 C6 B1 C9 04 8E 6C 52 2F 70 F1 3F 73 98 0D 40 23 8E 3E 21 C1 49 34 D0 37 56 3D 93 0F 48 19 8A 0A A7 C1 40 58 22 94 93 D2 25 30 F4 DB FA 33 6F 6E 0A C9 25 13 95 43 AE D4 4C CE 7C 37 20 FD 51 F6 94 58 70 5A C6 8C D4 FE 6B 6B 13 AB DC 97 46 51 29 69 32 84 54 F1 8F AF 8C 59 5F 64 24 77 FE 96 BB 2A 94 1D 5B CD 1D 4A C8 CC 49 88 07 08 FA 9B 37 8E 3C 4F 3A 90 60 BE E6 7C F9 A4 A4 A6 95 81 10 51 90 7E 16 27 53 B5 6B 0F 6B 41 0D BA 74 D8 A8 4B 2A 14 B3 14 4E 0E F1 28 47 54 FD 17 ED 95 0D 59 65 B4 B9 DD 46 58 2D B1 17 8D 16 9C 6B C4 65 B0 D6 FF 9C A3 92 8F EF 5B 9A E4 E4 18 FC 15 E8 3E BE A0 F8 7F A9 FF 5E ED 70 05 0D ED 28 49 F4 7B F9 59 D9 56 85 0C E9 29 85 1F 0D 81 15 F6 35 B1 05 EE 2E 4E 15 D0 4B 24 54 BF 6F 4F AD F0 34 B1 04 03 11 9C D8 E3 B9 2F CC 5B';
|
|
55
|
+
testMillerRabin(BigInt('0x' + telegramDhPrime.replace(/ /g, '')), true);
|
|
56
|
+
});
|
|
57
|
+
}, { timeout: 10000 }); // since miller-rabin factorization relies on RNG, it may take a while (or may not!)
|
|
58
|
+
//# sourceMappingURL=miller-rabin.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"miller-rabin.test.js","sourceRoot":"","sources":["../../../../src/utils/crypto/miller-rabin.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { defaultCryptoProviderFactory } from './index.js'\nimport { millerRabin } from './miller-rabin.js'\n\ndescribe(\n 'miller-rabin test',\n function () {\n // miller-rabin factorization relies on RNG, so we should use a real random number generator\n const c = defaultCryptoProviderFactory()\n\n const testMillerRabin = (n: number | string | bigint, isPrime: boolean) => {\n expect(millerRabin(c, BigInt(n))).eq(isPrime)\n }\n\n it('should correctly label small primes as probable primes', () => {\n const smallOddPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]\n\n for (const prime of smallOddPrimes) {\n testMillerRabin(prime, true)\n }\n })\n\n it('should correctly label small odd composite numbers as composite', () => {\n const smallOddPrimes = [9, 15, 21, 25, 27, 33, 35]\n\n for (const prime of smallOddPrimes) {\n testMillerRabin(prime, false)\n }\n })\n\n // primes are generated using `openssl prime -generate -bits <bits>`\n\n it('should work for 512-bit numbers', () => {\n testMillerRabin(\n '8411445470921866378538628788380866906358949375899610911537071281076627385046125382763689993349183284546479522400013151510610266158235924343045768103605519',\n true,\n )\n testMillerRabin(\n '11167561990563990242158096122232207092938761092751537312016255867850441858086589598418467012717458858604863547175649456433632887622140170743409535470973399',\n true,\n )\n testMillerRabin(\n '11006717791910450367418249787526506184731090161438431250022510598653874155081488487035840577645711578911087148186160668569071839053453201592321650008610329',\n true,\n )\n testMillerRabin(\n '12224330340162812215033324917156282302617911690617664923428569636370785775561435789211091021550357876767050350997458404009005800772805534351607294516706177',\n true,\n )\n\n // above numbers but -2 (not prime)\n testMillerRabin(\n '8411445470921866378538628788380866906358949375899610911537071281076627385046125382763689993349183284546479522400013151510610266158235924343045768103605517',\n false,\n )\n testMillerRabin(\n '11167561990563990242158096122232207092938761092751537312016255867850441858086589598418467012717458858604863547175649456433632887622140170743409535470973397',\n false,\n )\n testMillerRabin(\n '11006717791910450367418249787526506184731090161438431250022510598653874155081488487035840577645711578911087148186160668569071839053453201592321650008610327',\n false,\n )\n testMillerRabin(\n '12224330340162812215033324917156282302617911690617664923428569636370785775561435789211091021550357876767050350997458404009005800772805534351607294516706175',\n false,\n )\n })\n\n it('should work for 1024-bit numbers', () => {\n testMillerRabin(\n '94163180970530844245052892199633535954736903357996153321496979115367320260897793334681106861766748541439161886270777106456088209508872459550450259737267142959061663564218457086654112219462515165219295402175541003899136060178102898376369981338103600856012709228116661479275753497725541132207243717937379815409',\n true,\n )\n testMillerRabin(\n '97324962433497727515811278760066576725849776656602017497363465683978397629803148191267105308901733336070351381654371470561376353774017284623969415330564867697353080030917333974193741719718950105404732792050882127213356260415251087867407489400712288570880407613514781891914135956778687719588061176455381937003',\n true,\n )\n testMillerRabin(\n '92511311413226091818378551616231701579277597795073142338527410334932345968554993390789667936819230228388142960299649466238701015865565141753710450319875546944139442823075990348978746055937500467483161699883905850192191164043687791185635729923497381849380102040768674652775240505782671289535260164547714030567',\n true,\n )\n testMillerRabin(\n '98801756216479639848708157708947504990501845258427605711852570166662700681215707617225664134994147912417941920327932092748574265476658124536672887141144222716123085451749764522435906007567360583062117498919471220566974634924384147341592903939264267901029640119196259026154529723870788246284629644039137378253',\n true,\n )\n\n // above numbers but -2 (not prime)\n testMillerRabin(\n '94163180970530844245052892199633535954736903357996153321496979115367320260897793334681106861766748541439161886270777106456088209508872459550450259737267142959061663564218457086654112219462515165219295402175541003899136060178102898376369981338103600856012709228116661479275753497725541132207243717937379815407',\n false,\n )\n testMillerRabin(\n '97324962433497727515811278760066576725849776656602017497363465683978397629803148191267105308901733336070351381654371470561376353774017284623969415330564867697353080030917333974193741719718950105404732792050882127213356260415251087867407489400712288570880407613514781891914135956778687719588061176455381937001',\n false,\n )\n testMillerRabin(\n '92511311413226091818378551616231701579277597795073142338527410334932345968554993390789667936819230228388142960299649466238701015865565141753710450319875546944139442823075990348978746055937500467483161699883905850192191164043687791185635729923497381849380102040768674652775240505782671289535260164547714030565',\n false,\n )\n testMillerRabin(\n '98801756216479639848708157708947504990501845258427605711852570166662700681215707617225664134994147912417941920327932092748574265476658124536672887141144222716123085451749764522435906007567360583062117498919471220566974634924384147341592903939264267901029640119196259026154529723870788246284629644039137378251',\n false,\n )\n })\n\n it('should work for 2048-bit numbers', () => {\n testMillerRabin(\n '28608382334358769588283288249494859626901014972463291352091976543138105382282108662849885913053034513852843449409838151123568984617793641641937583673207501643041336002587032201383537626393235736734494131431069043382068545865505150651648610506542819001961332454611129372758714288168807328523359776577571626967649079147416191592855529888846889532625386469236278694936872628305052827422772792103722178298844645210242389265273407924858034431614414896134561928996888883994953322861399988094086562513898527391555490352156627307769278185444897960555995383228897584818577375695810423475039211516849716140051437120083274285367',\n true,\n )\n testMillerRabin(\n '30244022694659482453371920976249272809817388822378671144866806600284132009663832003348737406289715119965835410140834733465553787513841966120831322372642881643693711233087233983267648392814127424201572290931937482043046169402667397610783447368703776842799852222745601531140231486417855517072392416789672922529566643118973930252809010605519948446055538976582290902060054788109497630796585770940656002892943575479533099350429655210881833493066716819282707441553612603960556051122162329171373373251909387401572866056121964608595895425640834764028568120995397759283490218181167000161310959711677055741632674632758727382743',\n true,\n )\n testMillerRabin(\n '30560953105766401423987964658775999222308579908395527900931049506803845883459894704297458477118152899910620180302473409631442956208933061650967001020981432894530064472547770442696756724169958362395601360296775798187903794894866967342028337982275745956538015473621792510615113531964380246815875830970404687926061637030085629909804357717955251735074071072456074274947993921828878633638119117086342305530526661796817095624933200483138188878398983149622639425550360394901699701985050966685840649129419227936413574227792077082510807968104733387734970009620450108276446659342203263759999068046251645984039420643003580284779',\n true,\n )\n\n // above numbers but -2 (not prime)\n testMillerRabin(\n '28608382334358769588283288249494859626901014972463291352091976543138105382282108662849885913053034513852843449409838151123568984617793641641937583673207501643041336002587032201383537626393235736734494131431069043382068545865505150651648610506542819001961332454611129372758714288168807328523359776577571626967649079147416191592855529888846889532625386469236278694936872628305052827422772792103722178298844645210242389265273407924858034431614414896134561928996888883994953322861399988094086562513898527391555490352156627307769278185444897960555995383228897584818577375695810423475039211516849716140051437120083274285365',\n false,\n )\n testMillerRabin(\n '30244022694659482453371920976249272809817388822378671144866806600284132009663832003348737406289715119965835410140834733465553787513841966120831322372642881643693711233087233983267648392814127424201572290931937482043046169402667397610783447368703776842799852222745601531140231486417855517072392416789672922529566643118973930252809010605519948446055538976582290902060054788109497630796585770940656002892943575479533099350429655210881833493066716819282707441553612603960556051122162329171373373251909387401572866056121964608595895425640834764028568120995397759283490218181167000161310959711677055741632674632758727382741',\n false,\n )\n testMillerRabin(\n '30560953105766401423987964658775999222308579908395527900931049506803845883459894704297458477118152899910620180302473409631442956208933061650967001020981432894530064472547770442696756724169958362395601360296775798187903794894866967342028337982275745956538015473621792510615113531964380246815875830970404687926061637030085629909804357717955251735074071072456074274947993921828878633638119117086342305530526661796817095624933200483138188878398983149622639425550360394901699701985050966685840649129419227936413574227792077082510807968104733387734970009620450108276446659342203263759999068046251645984039420643003580284777',\n false,\n )\n\n // dh_prime used by telegram, as seen in https://core.telegram.org/mtproto/security_guidelines\n const telegramDhPrime =\n 'C7 1C AE B9 C6 B1 C9 04 8E 6C 52 2F 70 F1 3F 73 98 0D 40 23 8E 3E 21 C1 49 34 D0 37 56 3D 93 0F 48 19 8A 0A A7 C1 40 58 22 94 93 D2 25 30 F4 DB FA 33 6F 6E 0A C9 25 13 95 43 AE D4 4C CE 7C 37 20 FD 51 F6 94 58 70 5A C6 8C D4 FE 6B 6B 13 AB DC 97 46 51 29 69 32 84 54 F1 8F AF 8C 59 5F 64 24 77 FE 96 BB 2A 94 1D 5B CD 1D 4A C8 CC 49 88 07 08 FA 9B 37 8E 3C 4F 3A 90 60 BE E6 7C F9 A4 A4 A6 95 81 10 51 90 7E 16 27 53 B5 6B 0F 6B 41 0D BA 74 D8 A8 4B 2A 14 B3 14 4E 0E F1 28 47 54 FD 17 ED 95 0D 59 65 B4 B9 DD 46 58 2D B1 17 8D 16 9C 6B C4 65 B0 D6 FF 9C A3 92 8F EF 5B 9A E4 E4 18 FC 15 E8 3E BE A0 F8 7F A9 FF 5E ED 70 05 0D ED 28 49 F4 7B F9 59 D9 56 85 0C E9 29 85 1F 0D 81 15 F6 35 B1 05 EE 2E 4E 15 D0 4B 24 54 BF 6F 4F AD F0 34 B1 04 03 11 9C D8 E3 B9 2F CC 5B'\n testMillerRabin(BigInt('0x' + telegramDhPrime.replace(/ /g, '')), true)\n })\n },\n { timeout: 10000 },\n) // since miller-rabin factorization relies on RNG, it may take a while (or may not!)\n"]}
|
|
@@ -8,7 +8,7 @@ import { ICryptoProvider, IEncryptionScheme } from './abstract.js';
|
|
|
8
8
|
* @param newNonce New nonce
|
|
9
9
|
* @returns Tuple: `[key, iv]`
|
|
10
10
|
*/
|
|
11
|
-
export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serverNonce: Uint8Array, newNonce: Uint8Array):
|
|
11
|
+
export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serverNonce: Uint8Array, newNonce: Uint8Array): [Uint8Array, Uint8Array];
|
|
12
12
|
/**
|
|
13
13
|
* Create AES IGE instance for message (given auth key and message key)
|
|
14
14
|
* as defined by MTProto v2.
|
|
@@ -18,7 +18,7 @@ export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serve
|
|
|
18
18
|
* @param messageKey Message key
|
|
19
19
|
* @param client Whether this is a client to server message
|
|
20
20
|
*/
|
|
21
|
-
export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean):
|
|
21
|
+
export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean): IEncryptionScheme;
|
|
22
22
|
/**
|
|
23
23
|
* Create AES IGE instance for file (given auth key and message key)
|
|
24
24
|
* as defined by MTProto v1.
|
|
@@ -28,4 +28,4 @@ export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey:
|
|
|
28
28
|
* @param messageKey Message key
|
|
29
29
|
* @param client Whether this is a client to server message
|
|
30
30
|
*/
|
|
31
|
-
export declare function createAesIgeForMessageOld(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean):
|
|
31
|
+
export declare function createAesIgeForMessageOld(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean): IEncryptionScheme;
|
|
@@ -8,10 +8,10 @@ import { concatBuffers } from '../buffer-utils.js';
|
|
|
8
8
|
* @param newNonce New nonce
|
|
9
9
|
* @returns Tuple: `[key, iv]`
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
12
|
-
const hash1 =
|
|
13
|
-
const hash2 =
|
|
14
|
-
const hash3 =
|
|
11
|
+
export function generateKeyAndIvFromNonce(crypto, serverNonce, newNonce) {
|
|
12
|
+
const hash1 = crypto.sha1(concatBuffers([newNonce, serverNonce]));
|
|
13
|
+
const hash2 = crypto.sha1(concatBuffers([serverNonce, newNonce]));
|
|
14
|
+
const hash3 = crypto.sha1(concatBuffers([newNonce, newNonce]));
|
|
15
15
|
const key = concatBuffers([hash1, hash2.subarray(0, 12)]);
|
|
16
16
|
const iv = concatBuffers([hash2.subarray(12, 20), hash3, newNonce.subarray(0, 4)]);
|
|
17
17
|
return [key, iv];
|
|
@@ -25,10 +25,10 @@ export async function generateKeyAndIvFromNonce(crypto, serverNonce, newNonce) {
|
|
|
25
25
|
* @param messageKey Message key
|
|
26
26
|
* @param client Whether this is a client to server message
|
|
27
27
|
*/
|
|
28
|
-
export
|
|
28
|
+
export function createAesIgeForMessage(crypto, authKey, messageKey, client) {
|
|
29
29
|
const x = client ? 0 : 8;
|
|
30
|
-
const sha256a =
|
|
31
|
-
const sha256b =
|
|
30
|
+
const sha256a = crypto.sha256(concatBuffers([messageKey, authKey.subarray(x, 36 + x)]));
|
|
31
|
+
const sha256b = crypto.sha256(concatBuffers([authKey.subarray(40 + x, 76 + x), messageKey]));
|
|
32
32
|
const key = concatBuffers([sha256a.subarray(0, 8), sha256b.subarray(8, 24), sha256a.subarray(24, 32)]);
|
|
33
33
|
const iv = concatBuffers([sha256b.subarray(0, 8), sha256a.subarray(8, 24), sha256b.subarray(24, 32)]);
|
|
34
34
|
return crypto.createAesIge(key, iv);
|
|
@@ -42,12 +42,12 @@ export async function createAesIgeForMessage(crypto, authKey, messageKey, client
|
|
|
42
42
|
* @param messageKey Message key
|
|
43
43
|
* @param client Whether this is a client to server message
|
|
44
44
|
*/
|
|
45
|
-
export
|
|
45
|
+
export function createAesIgeForMessageOld(crypto, authKey, messageKey, client) {
|
|
46
46
|
const x = client ? 0 : 8;
|
|
47
|
-
const sha1a =
|
|
48
|
-
const sha1b =
|
|
49
|
-
const sha1c =
|
|
50
|
-
const sha1d =
|
|
47
|
+
const sha1a = crypto.sha1(concatBuffers([messageKey, authKey.subarray(x, 32 + x)]));
|
|
48
|
+
const sha1b = crypto.sha1(concatBuffers([authKey.subarray(32 + x, 48 + x), messageKey, authKey.subarray(48 + x, 64 + x)]));
|
|
49
|
+
const sha1c = crypto.sha1(concatBuffers([authKey.subarray(64 + x, 96 + x), messageKey]));
|
|
50
|
+
const sha1d = crypto.sha1(concatBuffers([messageKey, authKey.subarray(96 + x, 128 + x)]));
|
|
51
51
|
const key = concatBuffers([sha1a.subarray(0, 8), sha1b.subarray(8, 20), sha1c.subarray(4, 16)]);
|
|
52
52
|
const iv = concatBuffers([
|
|
53
53
|
sha1a.subarray(8, 20),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mtproto.js","sourceRoot":"","sources":["../../../../src/utils/crypto/mtproto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD;;;;;;;;GAQG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"mtproto.js","sourceRoot":"","sources":["../../../../src/utils/crypto/mtproto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACrC,MAAuB,EACvB,WAAuB,EACvB,QAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAE9D,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACzD,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAElF,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACpB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAClC,MAAuB,EACvB,OAAmB,EACnB,UAAsB,EACtB,MAAe;IAEf,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvF,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAE5F,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACtG,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAErG,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACrC,MAAuB,EACvB,OAAmB,EACnB,UAAsB,EACtB,MAAe;IAEf,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACrB,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAClG,CAAA;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACxF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEzF,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/F,MAAM,EAAE,GAAG,aAAa,CAAC;QACrB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;QACrB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QACpB,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;QACtB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;KACvB,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACvC,CAAC","sourcesContent":["import { concatBuffers } from '../buffer-utils.js'\nimport { ICryptoProvider, IEncryptionScheme } from './abstract.js'\n\n/**\n * Generate AES key and IV from nonces as defined by MTProto.\n * Used in authorization flow.\n *\n * @param crypto Crypto provider\n * @param serverNonce Server nonce\n * @param newNonce New nonce\n * @returns Tuple: `[key, iv]`\n */\nexport function generateKeyAndIvFromNonce(\n crypto: ICryptoProvider,\n serverNonce: Uint8Array,\n newNonce: Uint8Array,\n): [Uint8Array, Uint8Array] {\n const hash1 = crypto.sha1(concatBuffers([newNonce, serverNonce]))\n const hash2 = crypto.sha1(concatBuffers([serverNonce, newNonce]))\n const hash3 = crypto.sha1(concatBuffers([newNonce, newNonce]))\n\n const key = concatBuffers([hash1, hash2.subarray(0, 12)])\n const iv = concatBuffers([hash2.subarray(12, 20), hash3, newNonce.subarray(0, 4)])\n\n return [key, iv]\n}\n\n/**\n * Create AES IGE instance for message (given auth key and message key)\n * as defined by MTProto v2.\n *\n * @param crypto Crypto provider\n * @param authKey Authorization key\n * @param messageKey Message key\n * @param client Whether this is a client to server message\n */\nexport function createAesIgeForMessage(\n crypto: ICryptoProvider,\n authKey: Uint8Array,\n messageKey: Uint8Array,\n client: boolean,\n): IEncryptionScheme {\n const x = client ? 0 : 8\n const sha256a = crypto.sha256(concatBuffers([messageKey, authKey.subarray(x, 36 + x)]))\n const sha256b = crypto.sha256(concatBuffers([authKey.subarray(40 + x, 76 + x), messageKey]))\n\n const key = concatBuffers([sha256a.subarray(0, 8), sha256b.subarray(8, 24), sha256a.subarray(24, 32)])\n const iv = concatBuffers([sha256b.subarray(0, 8), sha256a.subarray(8, 24), sha256b.subarray(24, 32)])\n\n return crypto.createAesIge(key, iv)\n}\n\n/**\n * Create AES IGE instance for file (given auth key and message key)\n * as defined by MTProto v1.\n *\n * @param crypto Crypto provider\n * @param authKey Authorization key\n * @param messageKey Message key\n * @param client Whether this is a client to server message\n */\nexport function createAesIgeForMessageOld(\n crypto: ICryptoProvider,\n authKey: Uint8Array,\n messageKey: Uint8Array,\n client: boolean,\n): IEncryptionScheme {\n const x = client ? 0 : 8\n const sha1a = crypto.sha1(concatBuffers([messageKey, authKey.subarray(x, 32 + x)]))\n const sha1b = crypto.sha1(\n concatBuffers([authKey.subarray(32 + x, 48 + x), messageKey, authKey.subarray(48 + x, 64 + x)]),\n )\n const sha1c = crypto.sha1(concatBuffers([authKey.subarray(64 + x, 96 + x), messageKey]))\n const sha1d = crypto.sha1(concatBuffers([messageKey, authKey.subarray(96 + x, 128 + x)]))\n\n const key = concatBuffers([sha1a.subarray(0, 8), sha1b.subarray(8, 20), sha1c.subarray(4, 16)])\n const iv = concatBuffers([\n sha1a.subarray(8, 20),\n sha1b.subarray(0, 8),\n sha1c.subarray(16, 20),\n sha1d.subarray(0, 8),\n ])\n\n return crypto.createAesIge(key, iv)\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { createAesIgeForMessage, createAesIgeForMessageOld, generateKeyAndIvFromNonce } from './mtproto.js';
|
|
4
|
+
import { NodeCryptoProvider } from './node.js';
|
|
5
|
+
const authKey = Buffer.alloc(2048 / 8, Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'));
|
|
6
|
+
const messageKey = Buffer.from('25d701f2a29205526757825a99eb2d32');
|
|
7
|
+
describe('mtproto 2.0', () => {
|
|
8
|
+
it('should correctly derive message key and iv for client', () => {
|
|
9
|
+
const crypto = new NodeCryptoProvider();
|
|
10
|
+
const spy = vi.spyOn(crypto, 'createAesIge');
|
|
11
|
+
createAesIgeForMessage(crypto, authKey, messageKey, true);
|
|
12
|
+
expect(spy).toHaveBeenCalledWith(Buffer.from('7acac59ab48cd370e478daf6c64545ab9f32d5c9197f25febe052110f61875ca', 'hex'), Buffer.from('2746ccc19fc260c08f3d2696389f415392103dbcc3a8bf69da9394c3c3d95bd3', 'hex'));
|
|
13
|
+
});
|
|
14
|
+
it('should correctly derive message key and iv for server', () => {
|
|
15
|
+
const crypto = new NodeCryptoProvider();
|
|
16
|
+
const spy = vi.spyOn(crypto, 'createAesIge');
|
|
17
|
+
createAesIgeForMessage(crypto, authKey, messageKey, false);
|
|
18
|
+
expect(spy).toHaveBeenCalledWith(Buffer.from('c7cf179e7ebab144ba87de05415db4157d2fc66df4790b2fd405a6c8cbe4c0b3', 'hex'), Buffer.from('0916a7bd9880eacd4eeb868577a4c6a50e76fca4ac5c1bcfbafe3b9f76ccd806', 'hex'));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('mtproto 1.0', () => {
|
|
22
|
+
it('should correctly derive message key and iv for client', () => {
|
|
23
|
+
const crypto = new NodeCryptoProvider();
|
|
24
|
+
const spy = vi.spyOn(crypto, 'createAesIge');
|
|
25
|
+
createAesIgeForMessageOld(crypto, authKey, messageKey, true);
|
|
26
|
+
expect(spy).toHaveBeenCalledWith(Buffer.from('aad61cb5b7be5e8435174d74665f8a978e85806d0970ad4958642ca49e3c8834', 'hex'), Buffer.from('4065736fe6586e94aad9f024062f1b9988e8a44e2aff4e11aad61cb5b7be5e84', 'hex'));
|
|
27
|
+
});
|
|
28
|
+
it('should correctly derive message key and iv for server', () => {
|
|
29
|
+
const crypto = new NodeCryptoProvider();
|
|
30
|
+
const spy = vi.spyOn(crypto, 'createAesIge');
|
|
31
|
+
createAesIgeForMessageOld(crypto, authKey, messageKey, false);
|
|
32
|
+
expect(spy).toHaveBeenCalledWith(Buffer.from('d57682a17105e43b92bc5025ea80e88ef708240fc19450dfe072a8760f9534da', 'hex'), Buffer.from('07addff7beeb7705ef3a9d5090bd73c992d57291bb8a7079d57682a17105e43b', 'hex'));
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('mtproto key/iv from nonce', () => {
|
|
36
|
+
it('should correctly derive message key and iv for given nonces', () => {
|
|
37
|
+
const crypto = new NodeCryptoProvider();
|
|
38
|
+
const res = generateKeyAndIvFromNonce(crypto, Buffer.from('8af24c551836e5ed7002f5857e6e71b2', 'hex'), Buffer.from('3bf48b2d3152f383d82d1f2b32ac7fb5', 'hex'));
|
|
39
|
+
expect(res).to.eql([
|
|
40
|
+
Buffer.from('b0b5ffeadff0249fa6292f5ae0351556fd6619ba5dd4809601669292456d3e5a', 'hex'),
|
|
41
|
+
Buffer.from('13fef5bfd8c46b12dfd1753013b86cc012e1ce8ed6f8ecdd7bf36f3a3bf48b2d', 'hex'),
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=mtproto.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mtproto.test.js","sourceRoot":"","sources":["../../../../src/utils/crypto/mtproto.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { createAesIgeForMessage, createAesIgeForMessageOld, generateKeyAndIvFromNonce } from './mtproto.js'\nimport { NodeCryptoProvider } from './node.js'\n\nconst authKey = Buffer.alloc(\n 2048 / 8,\n Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'),\n)\nconst messageKey = Buffer.from('25d701f2a29205526757825a99eb2d32')\n\ndescribe('mtproto 2.0', () => {\n it('should correctly derive message key and iv for client', () => {\n const crypto = new NodeCryptoProvider()\n const spy = vi.spyOn(crypto, 'createAesIge')\n\n createAesIgeForMessage(crypto, authKey, messageKey, true)\n\n expect(spy).toHaveBeenCalledWith(\n Buffer.from('7acac59ab48cd370e478daf6c64545ab9f32d5c9197f25febe052110f61875ca', 'hex'),\n Buffer.from('2746ccc19fc260c08f3d2696389f415392103dbcc3a8bf69da9394c3c3d95bd3', 'hex'),\n )\n })\n\n it('should correctly derive message key and iv for server', () => {\n const crypto = new NodeCryptoProvider()\n const spy = vi.spyOn(crypto, 'createAesIge')\n\n createAesIgeForMessage(crypto, authKey, messageKey, false)\n\n expect(spy).toHaveBeenCalledWith(\n Buffer.from('c7cf179e7ebab144ba87de05415db4157d2fc66df4790b2fd405a6c8cbe4c0b3', 'hex'),\n Buffer.from('0916a7bd9880eacd4eeb868577a4c6a50e76fca4ac5c1bcfbafe3b9f76ccd806', 'hex'),\n )\n })\n})\n\ndescribe('mtproto 1.0', () => {\n it('should correctly derive message key and iv for client', () => {\n const crypto = new NodeCryptoProvider()\n const spy = vi.spyOn(crypto, 'createAesIge')\n\n createAesIgeForMessageOld(crypto, authKey, messageKey, true)\n\n expect(spy).toHaveBeenCalledWith(\n Buffer.from('aad61cb5b7be5e8435174d74665f8a978e85806d0970ad4958642ca49e3c8834', 'hex'),\n Buffer.from('4065736fe6586e94aad9f024062f1b9988e8a44e2aff4e11aad61cb5b7be5e84', 'hex'),\n )\n })\n\n it('should correctly derive message key and iv for server', () => {\n const crypto = new NodeCryptoProvider()\n const spy = vi.spyOn(crypto, 'createAesIge')\n\n createAesIgeForMessageOld(crypto, authKey, messageKey, false)\n\n expect(spy).toHaveBeenCalledWith(\n Buffer.from('d57682a17105e43b92bc5025ea80e88ef708240fc19450dfe072a8760f9534da', 'hex'),\n Buffer.from('07addff7beeb7705ef3a9d5090bd73c992d57291bb8a7079d57682a17105e43b', 'hex'),\n )\n })\n})\n\ndescribe('mtproto key/iv from nonce', () => {\n it('should correctly derive message key and iv for given nonces', () => {\n const crypto = new NodeCryptoProvider()\n\n const res = generateKeyAndIvFromNonce(\n crypto,\n Buffer.from('8af24c551836e5ed7002f5857e6e71b2', 'hex'),\n Buffer.from('3bf48b2d3152f383d82d1f2b32ac7fb5', 'hex'),\n )\n\n expect(res).to.eql([\n Buffer.from('b0b5ffeadff0249fa6292f5ae0351556fd6619ba5dd4809601669292456d3e5a', 'hex'),\n Buffer.from('13fef5bfd8c46b12dfd1753013b86cc012e1ce8ed6f8ecdd7bf36f3a3bf48b2d', 'hex'),\n ])\n })\n})\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InitInput } from '@mtcute/wasm';
|
|
2
|
+
import { MaybeAsync } from '../../types/index.js';
|
|
3
|
+
import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js';
|
|
4
|
+
export declare abstract class BaseNodeCryptoProvider extends BaseCryptoProvider {
|
|
5
|
+
createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr;
|
|
6
|
+
pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, keylen?: number, algo?: string): MaybeAsync<Uint8Array>;
|
|
7
|
+
sha1(data: Uint8Array): Uint8Array;
|
|
8
|
+
sha256(data: Uint8Array): Uint8Array;
|
|
9
|
+
hmacSha256(data: Uint8Array, key: Uint8Array): Uint8Array;
|
|
10
|
+
gzip(data: Uint8Array, maxSize: number): Uint8Array | null;
|
|
11
|
+
gunzip(data: Uint8Array): Uint8Array;
|
|
12
|
+
randomFill(buf: Uint8Array): void;
|
|
13
|
+
}
|
|
14
|
+
export declare class NodeCryptoProvider extends BaseNodeCryptoProvider implements ICryptoProvider {
|
|
15
|
+
private wasmInput?;
|
|
16
|
+
constructor(params?: {
|
|
17
|
+
wasmInput?: InitInput;
|
|
18
|
+
});
|
|
19
|
+
initialize(): Promise<void>;
|
|
20
|
+
createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme;
|
|
21
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports
|
|
2
|
+
import { createCipheriv, createHash, createHmac, pbkdf2, randomFillSync } from 'crypto';
|
|
3
|
+
import { deflateSync, gunzipSync } from 'zlib';
|
|
4
|
+
import { ige256Decrypt, ige256Encrypt, initAsync } from '@mtcute/wasm';
|
|
5
|
+
import { BaseCryptoProvider } from './abstract.js';
|
|
6
|
+
export class BaseNodeCryptoProvider extends BaseCryptoProvider {
|
|
7
|
+
createAesCtr(key, iv) {
|
|
8
|
+
const cipher = createCipheriv(`aes-${key.length * 8}-ctr`, key, iv);
|
|
9
|
+
const update = (data) => cipher.update(data);
|
|
10
|
+
return {
|
|
11
|
+
process: update,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
pbkdf2(password, salt, iterations, keylen = 64, algo = 'sha512') {
|
|
15
|
+
return new Promise((resolve, reject) => pbkdf2(password, salt, iterations, keylen, algo, (err, buf) => err !== null ? reject(err) : resolve(buf)));
|
|
16
|
+
}
|
|
17
|
+
sha1(data) {
|
|
18
|
+
return createHash('sha1').update(data).digest();
|
|
19
|
+
}
|
|
20
|
+
sha256(data) {
|
|
21
|
+
return createHash('sha256').update(data).digest();
|
|
22
|
+
}
|
|
23
|
+
hmacSha256(data, key) {
|
|
24
|
+
return createHmac('sha256', key).update(data).digest();
|
|
25
|
+
}
|
|
26
|
+
gzip(data, maxSize) {
|
|
27
|
+
// todo: test if wasm impl is better fit here
|
|
28
|
+
try {
|
|
29
|
+
// telegram accepts both zlib and gzip, but zlib is faster and has less overhead, so we use it here
|
|
30
|
+
return deflateSync(data, {
|
|
31
|
+
maxOutputLength: maxSize,
|
|
32
|
+
});
|
|
33
|
+
// hot path, avoid additional runtime checks
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
if (e.code === 'ERR_BUFFER_TOO_LARGE') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
throw e;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
gunzip(data) {
|
|
44
|
+
return gunzipSync(data);
|
|
45
|
+
}
|
|
46
|
+
randomFill(buf) {
|
|
47
|
+
randomFillSync(buf);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export class NodeCryptoProvider extends BaseNodeCryptoProvider {
|
|
51
|
+
constructor(params) {
|
|
52
|
+
super();
|
|
53
|
+
this.wasmInput = params?.wasmInput;
|
|
54
|
+
}
|
|
55
|
+
initialize() {
|
|
56
|
+
return initAsync(this.wasmInput);
|
|
57
|
+
}
|
|
58
|
+
createAesIge(key, iv) {
|
|
59
|
+
return {
|
|
60
|
+
encrypt(data) {
|
|
61
|
+
return ige256Encrypt(data, key, iv);
|
|
62
|
+
},
|
|
63
|
+
decrypt(data) {
|
|
64
|
+
return ige256Decrypt(data, key, iv);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../src/utils/crypto/node.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createCipheriv, createHash, createHmac, pbkdf2, randomFillSync } from 'crypto'\nimport { deflateSync, gunzipSync } from 'zlib'\n\nimport { ige256Decrypt, ige256Encrypt, initAsync, InitInput } from '@mtcute/wasm'\n\nimport { MaybeAsync } from '../../types/index.js'\nimport { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js'\n\nexport abstract class BaseNodeCryptoProvider extends BaseCryptoProvider {\n createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr {\n const cipher = createCipheriv(`aes-${key.length * 8}-ctr`, key, iv)\n\n const update = (data: Uint8Array) => cipher.update(data)\n\n return {\n process: update,\n }\n }\n\n pbkdf2(\n password: Uint8Array,\n salt: Uint8Array,\n iterations: number,\n keylen = 64,\n algo = 'sha512',\n ): MaybeAsync<Uint8Array> {\n return new Promise((resolve, reject) =>\n pbkdf2(password, salt, iterations, keylen, algo, (err: Error | null, buf: Uint8Array) =>\n err !== null ? reject(err) : resolve(buf),\n ),\n )\n }\n\n sha1(data: Uint8Array): Uint8Array {\n return createHash('sha1').update(data).digest()\n }\n\n sha256(data: Uint8Array): Uint8Array {\n return createHash('sha256').update(data).digest()\n }\n\n hmacSha256(data: Uint8Array, key: Uint8Array): Uint8Array {\n return createHmac('sha256', key).update(data).digest()\n }\n\n gzip(data: Uint8Array, maxSize: number): Uint8Array | null {\n // todo: test if wasm impl is better fit here\n try {\n // telegram accepts both zlib and gzip, but zlib is faster and has less overhead, so we use it here\n return deflateSync(data, {\n maxOutputLength: maxSize,\n })\n // hot path, avoid additional runtime checks\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n if (e.code === 'ERR_BUFFER_TOO_LARGE') {\n return null\n }\n\n throw e\n }\n }\n\n gunzip(data: Uint8Array): Uint8Array {\n return gunzipSync(data)\n }\n\n randomFill(buf: Uint8Array) {\n randomFillSync(buf)\n }\n}\n\nexport class NodeCryptoProvider extends BaseNodeCryptoProvider implements ICryptoProvider {\n private wasmInput?: InitInput\n\n constructor(params?: { wasmInput?: InitInput }) {\n super()\n this.wasmInput = params?.wasmInput\n }\n\n initialize(): Promise<void> {\n return initAsync(this.wasmInput)\n }\n\n createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme {\n return {\n encrypt(data: Uint8Array): Uint8Array {\n return ige256Encrypt(data, key, iv)\n },\n decrypt(data: Uint8Array): Uint8Array {\n return ige256Decrypt(data, key, iv)\n },\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe } from 'vitest';
|
|
2
|
+
import { testCryptoProvider } from '@mtcute/test';
|
|
3
|
+
import { NodeCryptoProvider } from './node.js';
|
|
4
|
+
describe('NodeCryptoProvider', () => {
|
|
5
|
+
if (typeof process === 'undefined') {
|
|
6
|
+
console.warn('Skipping NodeCryptoProvider tests');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
testCryptoProvider(new NodeCryptoProvider());
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=node.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.test.js","sourceRoot":"","sources":["../../../../src/utils/crypto/node.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAE9C,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAChC,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE;QAChC,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;QAEjD,OAAM;KACT;IAED,kBAAkB,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAA;AAChD,CAAC,CAAC,CAAA","sourcesContent":["import { describe } from 'vitest'\n\nimport { testCryptoProvider } from '@mtcute/test'\n\nimport { NodeCryptoProvider } from './node.js'\n\ndescribe('NodeCryptoProvider', () => {\n if (typeof process === 'undefined') {\n console.warn('Skipping NodeCryptoProvider tests')\n\n return\n }\n\n testCryptoProvider(new NodeCryptoProvider())\n})\n"]}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import bigInt from 'big-integer';
|
|
2
1
|
import { utf8EncodeToBuffer } from '@mtcute/tl-runtime';
|
|
3
2
|
import { MtSecurityError, MtUnsupportedError } from '../../types/errors.js';
|
|
4
|
-
import { bigIntToBuffer, bufferToBigInt } from '../bigint-utils.js';
|
|
5
|
-
import { concatBuffers
|
|
3
|
+
import { bigIntModPow, bigIntToBuffer, bufferToBigInt } from '../bigint-utils.js';
|
|
4
|
+
import { concatBuffers } from '../buffer-utils.js';
|
|
6
5
|
import { xorBuffer } from './utils.js';
|
|
7
6
|
/**
|
|
8
7
|
* Compute password hash as defined by MTProto.
|
|
@@ -16,8 +15,8 @@ import { xorBuffer } from './utils.js';
|
|
|
16
15
|
*/
|
|
17
16
|
export async function computePasswordHash(crypto, password, salt1, salt2) {
|
|
18
17
|
const SH = (data, salt) => crypto.sha256(concatBuffers([salt, data, salt]));
|
|
19
|
-
const PH1 =
|
|
20
|
-
return SH(await crypto.pbkdf2(
|
|
18
|
+
const PH1 = (pwd, salt1, salt2) => SH(SH(pwd, salt1), salt2);
|
|
19
|
+
return SH(await crypto.pbkdf2(PH1(password, salt1, salt2), salt1, 100000), salt2);
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* Compute new password SRP hash as defined by MTProto.
|
|
@@ -27,12 +26,15 @@ export async function computePasswordHash(crypto, password, salt1, salt2) {
|
|
|
27
26
|
* @param password Password
|
|
28
27
|
*/
|
|
29
28
|
export async function computeNewPasswordHash(crypto, algo, password) {
|
|
30
|
-
|
|
29
|
+
const salt1 = new Uint8Array(algo.salt1.length + 32);
|
|
30
|
+
salt1.set(algo.salt1);
|
|
31
|
+
crypto.randomFill(salt1.subarray(algo.salt1.length));
|
|
32
|
+
algo.salt1 = salt1;
|
|
31
33
|
const _x = await computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2);
|
|
32
|
-
const g =
|
|
34
|
+
const g = BigInt(algo.g);
|
|
33
35
|
const p = bufferToBigInt(algo.p);
|
|
34
36
|
const x = bufferToBigInt(_x);
|
|
35
|
-
return bigIntToBuffer(g
|
|
37
|
+
return bigIntToBuffer(bigIntModPow(g, x, p), 256);
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Compute SRP check parameters for 2fa password as defined by MTProto.
|
|
@@ -55,38 +57,28 @@ export async function computeSrpParams(crypto, request, password) {
|
|
|
55
57
|
if (!request.srpId) {
|
|
56
58
|
throw new MtSecurityError('SRP_ID is not present in the request');
|
|
57
59
|
}
|
|
58
|
-
const g =
|
|
60
|
+
const g = BigInt(algo.g);
|
|
59
61
|
const _g = bigIntToBuffer(g, 256);
|
|
60
62
|
const p = bufferToBigInt(algo.p);
|
|
61
63
|
const gB = bufferToBigInt(request.srpB);
|
|
62
|
-
const a = bufferToBigInt(randomBytes(256));
|
|
63
|
-
const gA = g
|
|
64
|
+
const a = bufferToBigInt(crypto.randomBytes(256));
|
|
65
|
+
const gA = bigIntModPow(g, a, p);
|
|
64
66
|
const _gA = bigIntToBuffer(gA, 256);
|
|
65
67
|
const H = (data) => crypto.sha256(data);
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/* u = */ crypto.sha256(concatBuffers([_gA, request.srpB])),
|
|
70
|
-
/* x = */ computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2),
|
|
71
|
-
]);
|
|
68
|
+
const _k = crypto.sha256(concatBuffers([algo.p, _g]));
|
|
69
|
+
const _u = crypto.sha256(concatBuffers([_gA, request.srpB]));
|
|
70
|
+
const _x = await computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2);
|
|
72
71
|
const k = bufferToBigInt(_k);
|
|
73
72
|
const u = bufferToBigInt(_u);
|
|
74
73
|
const x = bufferToBigInt(_x);
|
|
75
|
-
const v = g
|
|
76
|
-
const kV = k
|
|
77
|
-
let t = gB
|
|
78
|
-
if (t
|
|
79
|
-
t
|
|
80
|
-
const sA = t
|
|
81
|
-
const _kA =
|
|
82
|
-
const _M1 =
|
|
83
|
-
xorBuffer(await H(algo.p), await H(_g)),
|
|
84
|
-
await H(algo.salt1),
|
|
85
|
-
await H(algo.salt2),
|
|
86
|
-
_gA,
|
|
87
|
-
request.srpB,
|
|
88
|
-
_kA,
|
|
89
|
-
]));
|
|
74
|
+
const v = bigIntModPow(g, x, p);
|
|
75
|
+
const kV = (k * v) % p;
|
|
76
|
+
let t = gB - kV;
|
|
77
|
+
if (t < 0n)
|
|
78
|
+
t += p;
|
|
79
|
+
const sA = bigIntModPow(t, a + u * x, p);
|
|
80
|
+
const _kA = H(bigIntToBuffer(sA, 256));
|
|
81
|
+
const _M1 = H(concatBuffers([xorBuffer(H(algo.p), H(_g)), H(algo.salt1), H(algo.salt2), _gA, request.srpB, _kA]));
|
|
90
82
|
return {
|
|
91
83
|
_: 'inputCheckPasswordSRP',
|
|
92
84
|
srpId: request.srpId,
|