@ikyyjee/ikyysinggle 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/WAProto/GenerateStatics.sh +3 -0
  2. package/WAProto/WAProto.proto +8083 -0
  3. package/WAProto/fix-imports.js +85 -0
  4. package/WAProto/index.d.ts +29095 -0
  5. package/WAProto/index.js +172336 -0
  6. package/engine-requirements.js +10 -0
  7. package/lib/Defaults/index.js +194 -0
  8. package/lib/Signal/Group/ciphertext-message.js +12 -0
  9. package/lib/Signal/Group/group-session-builder.js +30 -0
  10. package/lib/Signal/Group/group_cipher.js +82 -0
  11. package/lib/Signal/Group/index.js +12 -0
  12. package/lib/Signal/Group/keyhelper.js +18 -0
  13. package/lib/Signal/Group/sender-chain-key.js +26 -0
  14. package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
  15. package/lib/Signal/Group/sender-key-message.js +66 -0
  16. package/lib/Signal/Group/sender-key-name.js +48 -0
  17. package/lib/Signal/Group/sender-key-record.js +41 -0
  18. package/lib/Signal/Group/sender-key-state.js +84 -0
  19. package/lib/Signal/Group/sender-message-key.js +26 -0
  20. package/lib/Signal/libsignal.js +431 -0
  21. package/lib/Signal/lid-mapping.js +277 -0
  22. package/lib/Socket/Client/index.js +3 -0
  23. package/lib/Socket/Client/types.js +11 -0
  24. package/lib/Socket/Client/websocket.js +102 -0
  25. package/lib/Socket/aigroups.js +221 -0
  26. package/lib/Socket/business.js +379 -0
  27. package/lib/Socket/chats.js +1193 -0
  28. package/lib/Socket/communities.js +431 -0
  29. package/lib/Socket/graphql.js +524 -0
  30. package/lib/Socket/groups.js +408 -0
  31. package/lib/Socket/index.js +49 -0
  32. package/lib/Socket/interop.js +341 -0
  33. package/lib/Socket/luxu.js +510 -0
  34. package/lib/Socket/managed-account.js +99 -0
  35. package/lib/Socket/messages-recv.js +2009 -0
  36. package/lib/Socket/messages-send.js +1608 -0
  37. package/lib/Socket/mex.js +41 -0
  38. package/lib/Socket/newsletter.js +399 -0
  39. package/lib/Socket/privacy.js +128 -0
  40. package/lib/Socket/registration.js +238 -0
  41. package/lib/Socket/socket.js +1000 -0
  42. package/lib/Socket/text-router.js +67 -0
  43. package/lib/Socket/username.js +234 -0
  44. package/lib/Store/index.js +10 -0
  45. package/lib/Store/keyed-db.js +108 -0
  46. package/lib/Store/make-cache-manager-store.js +85 -0
  47. package/lib/Store/make-in-memory-store.js +198 -0
  48. package/lib/Store/make-ordered-dictionary.js +75 -0
  49. package/lib/Store/object-repository.js +32 -0
  50. package/lib/Types/Auth.js +2 -0
  51. package/lib/Types/Bussines.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +8 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +25 -0
  58. package/lib/Types/LabelAssociation.js +7 -0
  59. package/lib/Types/Message.js +11 -0
  60. package/lib/Types/Mex.js +114 -0
  61. package/lib/Types/Product.js +2 -0
  62. package/lib/Types/Signal.js +2 -0
  63. package/lib/Types/Socket.js +3 -0
  64. package/lib/Types/State.js +56 -0
  65. package/lib/Types/USync.js +2 -0
  66. package/lib/Types/index.js +26 -0
  67. package/lib/Utils/adaptive-healing.js +53 -0
  68. package/lib/Utils/auth-utils.js +302 -0
  69. package/lib/Utils/browser-utils.js +50 -0
  70. package/lib/Utils/business.js +231 -0
  71. package/lib/Utils/chat-utils.js +872 -0
  72. package/lib/Utils/command-loader.js +108 -0
  73. package/lib/Utils/companion-reg-client-utils.js +35 -0
  74. package/lib/Utils/consumer-application.js +106 -0
  75. package/lib/Utils/crypto.js +137 -0
  76. package/lib/Utils/curve25519-js.js +262 -0
  77. package/lib/Utils/decode-wa-message.js +498 -0
  78. package/lib/Utils/event-buffer.js +622 -0
  79. package/lib/Utils/generics.js +403 -0
  80. package/lib/Utils/group-history.js +47 -0
  81. package/lib/Utils/history.js +134 -0
  82. package/lib/Utils/identity-change-handler.js +50 -0
  83. package/lib/Utils/index.js +38 -0
  84. package/lib/Utils/jid-display-normalization.js +198 -0
  85. package/lib/Utils/link-preview.js +85 -0
  86. package/lib/Utils/logger.js +3 -0
  87. package/lib/Utils/lt-hash.js +8 -0
  88. package/lib/Utils/make-mutex.js +33 -0
  89. package/lib/Utils/message-composer.js +273 -0
  90. package/lib/Utils/message-retry-manager.js +267 -0
  91. package/lib/Utils/messages-media.js +791 -0
  92. package/lib/Utils/messages.js +1260 -0
  93. package/lib/Utils/meta-ai-msmsg.js +271 -0
  94. package/lib/Utils/native-bridge.js +77 -0
  95. package/lib/Utils/noise-handler.js +201 -0
  96. package/lib/Utils/offline-node-processor.js +40 -0
  97. package/lib/Utils/optimizer.js +90 -0
  98. package/lib/Utils/pre-key-manager.js +106 -0
  99. package/lib/Utils/process-message.js +630 -0
  100. package/lib/Utils/reporting-utils.js +258 -0
  101. package/lib/Utils/session-pool.js +73 -0
  102. package/lib/Utils/signal.js +207 -0
  103. package/lib/Utils/stanza-ack.js +38 -0
  104. package/lib/Utils/sticker.js +139 -0
  105. package/lib/Utils/sync-action-utils.js +49 -0
  106. package/lib/Utils/tc-token-utils.js +163 -0
  107. package/lib/Utils/use-multi-file-auth-state.js +121 -0
  108. package/lib/Utils/use-sqlite-auth-state.js +168 -0
  109. package/lib/Utils/validate-connection.js +203 -0
  110. package/lib/Utils/view-once-cache.js +79 -0
  111. package/lib/Utils/voip-rekey.js +25 -0
  112. package/lib/Utils/warmup.js +117 -0
  113. package/lib/WABinary/constants.js +1301 -0
  114. package/lib/WABinary/decode.js +262 -0
  115. package/lib/WABinary/encode.js +220 -0
  116. package/lib/WABinary/generic-utils.js +204 -0
  117. package/lib/WABinary/index.js +6 -0
  118. package/lib/WABinary/jid-utils.js +98 -0
  119. package/lib/WABinary/types.js +2 -0
  120. package/lib/WAM/BinaryInfo.js +10 -0
  121. package/lib/WAM/constants.js +22853 -0
  122. package/lib/WAM/encode.js +150 -0
  123. package/lib/WAM/index.js +4 -0
  124. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +41 -0
  125. package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
  126. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
  127. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  128. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +52 -0
  129. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +31 -0
  130. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +26 -0
  131. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  132. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +35 -0
  133. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  134. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
  135. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  136. package/lib/WAUSync/Protocols/index.js +13 -0
  137. package/lib/WAUSync/USyncQuery.js +127 -0
  138. package/lib/WAUSync/USyncUser.js +31 -0
  139. package/lib/WAUSync/index.js +4 -0
  140. package/lib/antiban.js +4083 -0
  141. package/lib/index.js +24 -0
  142. package/package.json +147 -0
@@ -0,0 +1,108 @@
1
+ /**
2
+ * lib/Utils/command-loader.js — optional, opt-in "!command" style handler.
3
+ * Loads command modules from a local folder you point it at (each module
4
+ * exports { name, aliases?, execute(ctx) }) and dispatches incoming text
5
+ * messages that start with your chosen prefix to the matching command.
6
+ * Does nothing unless you call this yourself with a real `commandsDir`.
7
+ */
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { createRequire } from 'module';
11
+
12
+ const require = createRequire(import.meta.url);
13
+
14
+ /**
15
+ * @param sock A connected socket (needs `sock.ev`, optionally `sock.logger`).
16
+ * @param options.commandsDir Folder containing your command modules.
17
+ * @param options.prefix Command prefix, default '!'.
18
+ * @param options.logger Optional logger override.
19
+ * @param options.onError Optional (error, msg) => void override for failures.
20
+ */
21
+ export const createCommandHandler = (sock, options) => {
22
+ const prefix = options.prefix ?? '!';
23
+ const logger = options.logger || sock.logger;
24
+ const commands = new Map();
25
+ const load = () => {
26
+ commands.clear();
27
+ const dir = options.commandsDir;
28
+ if (!fs.existsSync(dir)) {
29
+ logger?.warn?.({ dir }, 'commands directory does not exist');
30
+ return;
31
+ }
32
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith('.js'));
33
+ for (const file of files) {
34
+ const fullPath = path.join(dir, file);
35
+ try {
36
+ delete require.cache[require.resolve(fullPath)];
37
+ const mod = require(fullPath);
38
+ const cmd = mod?.default || mod;
39
+ if (!cmd?.name || typeof cmd.execute !== 'function') {
40
+ logger?.warn?.({ file }, 'skipping invalid command module (missing name/execute)');
41
+ continue;
42
+ }
43
+ commands.set(cmd.name.toLowerCase(), cmd);
44
+ for (const alias of cmd.aliases || []) {
45
+ commands.set(alias.toLowerCase(), cmd);
46
+ }
47
+ }
48
+ catch (error) {
49
+ logger?.error?.({ error, file }, 'failed to load command');
50
+ }
51
+ }
52
+ logger?.debug?.({ count: commands.size }, 'commands loaded');
53
+ };
54
+ load();
55
+ const handler = async ({ messages, type }) => {
56
+ if (type !== 'notify') {
57
+ return;
58
+ }
59
+ for (const msg of messages) {
60
+ try {
61
+ if (!msg.message || msg.key.fromMe) {
62
+ continue;
63
+ }
64
+ const body = msg.message.conversation ||
65
+ msg.message.extendedTextMessage?.text ||
66
+ msg.message.imageMessage?.caption ||
67
+ msg.message.videoMessage?.caption ||
68
+ '';
69
+ if (!body.startsWith(prefix)) {
70
+ continue;
71
+ }
72
+ const [cmdName, ...args] = body.slice(prefix.length).trim().split(/\s+/);
73
+ if (!cmdName) {
74
+ continue;
75
+ }
76
+ const cmd = commands.get(cmdName.toLowerCase());
77
+ if (!cmd) {
78
+ continue;
79
+ }
80
+ const jid = msg.key.remoteJid;
81
+ const ctx = {
82
+ sock,
83
+ msg,
84
+ args,
85
+ text: args.join(' '),
86
+ jid,
87
+ sender: msg.key.participant || msg.key.remoteJid,
88
+ isGroup: !!jid && jid.endsWith('@g.us')
89
+ };
90
+ await cmd.execute(ctx);
91
+ }
92
+ catch (error) {
93
+ if (options.onError) {
94
+ options.onError(error, msg);
95
+ }
96
+ else {
97
+ logger?.error?.({ error }, 'command execution failed');
98
+ }
99
+ }
100
+ }
101
+ };
102
+ sock.ev.on('messages.upsert', handler);
103
+ return {
104
+ commands,
105
+ reload: load,
106
+ stop: () => sock.ev.off('messages.upsert', handler)
107
+ };
108
+ };
@@ -0,0 +1,35 @@
1
+ export var CompanionWebClientType;
2
+ (function (CompanionWebClientType) {
3
+ CompanionWebClientType[CompanionWebClientType["UNKNOWN"] = 0] = "UNKNOWN";
4
+ CompanionWebClientType[CompanionWebClientType["CHROME"] = 1] = "CHROME";
5
+ CompanionWebClientType[CompanionWebClientType["EDGE"] = 2] = "EDGE";
6
+ CompanionWebClientType[CompanionWebClientType["FIREFOX"] = 3] = "FIREFOX";
7
+ CompanionWebClientType[CompanionWebClientType["IE"] = 4] = "IE";
8
+ CompanionWebClientType[CompanionWebClientType["OPERA"] = 5] = "OPERA";
9
+ CompanionWebClientType[CompanionWebClientType["SAFARI"] = 6] = "SAFARI";
10
+ CompanionWebClientType[CompanionWebClientType["ELECTRON"] = 7] = "ELECTRON";
11
+ CompanionWebClientType[CompanionWebClientType["UWP"] = 8] = "UWP";
12
+ CompanionWebClientType[CompanionWebClientType["OTHER_WEB_CLIENT"] = 9] = "OTHER_WEB_CLIENT";
13
+ })(CompanionWebClientType || (CompanionWebClientType = {}));
14
+ const BROWSER_TO_COMPANION_WEB_CLIENT = {
15
+ Chrome: CompanionWebClientType.CHROME,
16
+ Edge: CompanionWebClientType.EDGE,
17
+ Firefox: CompanionWebClientType.FIREFOX,
18
+ IE: CompanionWebClientType.IE,
19
+ Opera: CompanionWebClientType.OPERA,
20
+ Safari: CompanionWebClientType.SAFARI
21
+ };
22
+ export const getCompanionWebClientType = ([os, browserName]) => {
23
+ if (browserName === 'Desktop') {
24
+ return os === 'Windows' ? CompanionWebClientType.UWP : CompanionWebClientType.ELECTRON;
25
+ }
26
+ return BROWSER_TO_COMPANION_WEB_CLIENT[browserName] || CompanionWebClientType.OTHER_WEB_CLIENT;
27
+ };
28
+ export const getCompanionPlatformId = (browser) => {
29
+ return getCompanionWebClientType(browser).toString();
30
+ };
31
+ export const buildPairingQRData = (ref, noiseKeyB64, identityKeyB64, advB64, browser) => {
32
+ return ('https://wa.me/settings/linked_devices#' +
33
+ [ref, noiseKeyB64, identityKeyB64, advB64, getCompanionPlatformId(browser)].join(','));
34
+ };
35
+ //# sourceMappingURL=companion-reg-client-utils.js.map
@@ -0,0 +1,106 @@
1
+ /**
2
+ * lib/Utils/consumer-application.js — decode WhatsApp's "ConsumerApplication"
3
+ * envelope (used for messages relayed through interop/cross-app channels)
4
+ * and map it into the same plain Message shape the rest of this library
5
+ * already understands. Pure protobuf decode + object mapping, no I/O.
6
+ */
7
+ import { proto } from '../../WAProto/index.js';
8
+ export const decodeConsumerApplication = buffer => {
9
+ if (!Buffer.isBuffer(buffer) && !(buffer instanceof Uint8Array)) {
10
+ throw new TypeError('decodeConsumerApplication: buffer must be Buffer or Uint8Array');
11
+ }
12
+ return proto.ConsumerApplication.decode(buffer);
13
+ };
14
+ const textOf = mt => (mt && typeof mt.text === 'string' ? mt.text : undefined);
15
+ const mapContent = content => {
16
+ if (!content)
17
+ return null;
18
+ switch (content.content) {
19
+ case 'messageText':
20
+ return { conversation: textOf(content.messageText) ?? '' };
21
+ case 'extendedTextMessage': {
22
+ const e = content.extendedTextMessage;
23
+ return {
24
+ extendedTextMessage: {
25
+ text: textOf(e.text),
26
+ matchedText: e.matchedText,
27
+ canonicalUrl: e.canonicalUrl,
28
+ description: e.description,
29
+ title: e.title
30
+ }
31
+ };
32
+ }
33
+ case 'imageMessage':
34
+ return {
35
+ imageMessage: { mediaPayload: content.imageMessage.image, caption: textOf(content.imageMessage.caption) }
36
+ };
37
+ case 'videoMessage':
38
+ return {
39
+ videoMessage: { mediaPayload: content.videoMessage.video, caption: textOf(content.videoMessage.caption) }
40
+ };
41
+ case 'audioMessage':
42
+ return { audioMessage: { mediaPayload: content.audioMessage.audio, ptt: content.audioMessage.ptt } };
43
+ case 'documentMessage':
44
+ return {
45
+ documentMessage: { mediaPayload: content.documentMessage.document, fileName: content.documentMessage.fileName }
46
+ };
47
+ case 'stickerMessage':
48
+ return { stickerMessage: { mediaPayload: content.stickerMessage.sticker } };
49
+ case 'contactMessage':
50
+ return { contactMessage: { mediaPayload: content.contactMessage.contact } };
51
+ case 'contactsArrayMessage':
52
+ return {
53
+ contactsArrayMessage: {
54
+ displayName: content.contactsArrayMessage.displayName,
55
+ contacts: content.contactsArrayMessage.contacts || []
56
+ }
57
+ };
58
+ case 'locationMessage': {
59
+ const loc = content.locationMessage.location || {};
60
+ return {
61
+ locationMessage: {
62
+ degreesLatitude: loc.degreesLatitude,
63
+ degreesLongitude: loc.degreesLongitude,
64
+ name: loc.name
65
+ }
66
+ };
67
+ }
68
+ case 'liveLocationMessage': {
69
+ const loc = content.liveLocationMessage.location || {};
70
+ return {
71
+ liveLocationMessage: {
72
+ degreesLatitude: loc.degreesLatitude,
73
+ degreesLongitude: loc.degreesLongitude,
74
+ caption: textOf(content.liveLocationMessage.caption)
75
+ }
76
+ };
77
+ }
78
+ case 'reactionMessage':
79
+ return { reactionMessage: content.reactionMessage };
80
+ default:
81
+ return null;
82
+ }
83
+ };
84
+ export const consumerApplicationToMessage = app => {
85
+ const payload = app?.payload;
86
+ if (!payload)
87
+ return null;
88
+ switch (payload.payload) {
89
+ case 'content':
90
+ return mapContent(payload.content);
91
+ case 'applicationData': {
92
+ const ad = payload.applicationData;
93
+ if (ad?.applicationContent === 'revoke' && ad.revoke?.key) {
94
+ return {
95
+ protocolMessage: {
96
+ key: ad.revoke.key,
97
+ type: proto.Message.ProtocolMessage.Type.REVOKE
98
+ }
99
+ };
100
+ }
101
+ return null;
102
+ }
103
+ default:
104
+ return null;
105
+ }
106
+ };
@@ -0,0 +1,137 @@
1
+ import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto';
2
+ import * as curve from 'libsignal/src/curve.js';
3
+ import { KEY_BUNDLE_TYPE } from '../Defaults/index.js';
4
+ import { generateKeyPairJS, sharedKeyJS, signJS, verifyJS } from './curve25519-js.js';
5
+ export { md5, hkdf } from 'whatsapp-rust-bridge';
6
+ // insure browser & node compatibility
7
+ const { subtle } = globalThis.crypto;
8
+ /** prefix version byte to the pub keys, required for some curve crypto functions */
9
+ export const generateSignalPubKey = (pubKey) => pubKey.length === 33 ? pubKey : Buffer.concat([KEY_BUNDLE_TYPE, pubKey]);
10
+ export const Curve = {
11
+ generateKeyPair: () => {
12
+ const { pubKey, privKey } = curve.generateKeyPair();
13
+ return {
14
+ private: Buffer.from(privKey),
15
+ // remove version byte
16
+ public: Buffer.from(pubKey.slice(1))
17
+ };
18
+ },
19
+ sharedKey: (privateKey, publicKey) => {
20
+ const shared = curve.calculateAgreement(generateSignalPubKey(publicKey), privateKey);
21
+ return Buffer.from(shared);
22
+ },
23
+ sign: (privateKey, buf) => curve.calculateSignature(privateKey, buf),
24
+ verify: (pubKey, message, signature) => {
25
+ try {
26
+ curve.verifySignature(generateSignalPubKey(pubKey), message, signature);
27
+ return true;
28
+ }
29
+ catch (error) {
30
+ return false;
31
+ }
32
+ }
33
+ };
34
+ export const signedKeyPair = (identityKeyPair, keyId) => {
35
+ const preKey = Curve.generateKeyPair();
36
+ const pubKey = generateSignalPubKey(preKey.public);
37
+ const signature = Curve.sign(identityKeyPair.private, pubKey);
38
+ return { keyPair: preKey, signature, keyId };
39
+ };
40
+ /**
41
+ * Pure-JS, dependency-free fallback for `Curve` (see curve25519-js.js) — same
42
+ * interface, verified bit-for-bit interoperable with the `libsignal`-backed
43
+ * `Curve` above (cross-checked: a shared key computed one side with `Curve`
44
+ * and the other with `CurveJS` matches). Useful if `libsignal` (currently a
45
+ * `github:` dependency — see package.json / vendor-libsignal.sh) fails to
46
+ * install or load in your environment; not used by default anywhere in this
47
+ * library. See README.md → "Pure-JS Curve25519 fallback" to opt in.
48
+ */
49
+ export const CurveJS = {
50
+ generateKeyPair: () => {
51
+ const { private: privKey, public: pubKey } = generateKeyPairJS();
52
+ return { private: Buffer.from(privKey), public: Buffer.from(pubKey) };
53
+ },
54
+ sharedKey: (privateKey, publicKey) => Buffer.from(sharedKeyJS(privateKey, publicKey)),
55
+ sign: (privateKey, buf) => signJS(privateKey, buf),
56
+ verify: (pubKey, message, signature) => verifyJS(pubKey, message, signature)
57
+ };
58
+ const GCM_TAG_LENGTH = 128 >> 3;
59
+ /**
60
+ * encrypt AES 256 GCM;
61
+ * where the tag tag is suffixed to the ciphertext
62
+ * */
63
+ export function aesEncryptGCM(plaintext, key, iv, additionalData) {
64
+ const cipher = createCipheriv('aes-256-gcm', key, iv);
65
+ cipher.setAAD(additionalData);
66
+ return Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);
67
+ }
68
+ /**
69
+ * decrypt AES 256 GCM;
70
+ * where the auth tag is suffixed to the ciphertext
71
+ * */
72
+ export function aesDecryptGCM(ciphertext, key, iv, additionalData) {
73
+ const decipher = createDecipheriv('aes-256-gcm', key, iv);
74
+ // decrypt additional adata
75
+ const enc = ciphertext.slice(0, ciphertext.length - GCM_TAG_LENGTH);
76
+ const tag = ciphertext.slice(ciphertext.length - GCM_TAG_LENGTH);
77
+ // set additional data
78
+ decipher.setAAD(additionalData);
79
+ decipher.setAuthTag(tag);
80
+ return Buffer.concat([decipher.update(enc), decipher.final()]);
81
+ }
82
+ export function aesEncryptCTR(plaintext, key, iv) {
83
+ const cipher = createCipheriv('aes-256-ctr', key, iv);
84
+ return Buffer.concat([cipher.update(plaintext), cipher.final()]);
85
+ }
86
+ export function aesDecryptCTR(ciphertext, key, iv) {
87
+ const decipher = createDecipheriv('aes-256-ctr', key, iv);
88
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
89
+ }
90
+ /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
91
+ export function aesDecrypt(buffer, key) {
92
+ return aesDecryptWithIV(buffer.subarray(16), key, buffer.subarray(0, 16));
93
+ }
94
+ /** decrypt AES 256 CBC */
95
+ export function aesDecryptWithIV(buffer, key, IV) {
96
+ const aes = createDecipheriv('aes-256-cbc', key, IV);
97
+ return Buffer.concat([aes.update(buffer), aes.final()]);
98
+ }
99
+ // encrypt AES 256 CBC; where a random IV is prefixed to the buffer
100
+ export function aesEncrypt(buffer, key) {
101
+ const IV = randomBytes(16);
102
+ const aes = createCipheriv('aes-256-cbc', key, IV);
103
+ return Buffer.concat([IV, aes.update(buffer), aes.final()]); // prefix IV to the buffer
104
+ }
105
+ // encrypt AES 256 CBC with a given IV
106
+ export function aesEncrypWithIV(buffer, key, IV) {
107
+ const aes = createCipheriv('aes-256-cbc', key, IV);
108
+ return Buffer.concat([aes.update(buffer), aes.final()]); // prefix IV to the buffer
109
+ }
110
+ // sign HMAC using SHA 256
111
+ export function hmacSign(buffer, key, variant = 'sha256') {
112
+ return createHmac(variant, key).update(buffer).digest();
113
+ }
114
+ export function sha256(buffer) {
115
+ return createHash('sha256').update(buffer).digest();
116
+ }
117
+ export async function derivePairingCodeKey(pairingCode, salt) {
118
+ // Convert inputs to formats Web Crypto API can work with
119
+ const encoder = new TextEncoder();
120
+ const pairingCodeBuffer = encoder.encode(pairingCode);
121
+ const saltBuffer = new Uint8Array(salt instanceof Uint8Array ? salt : new Uint8Array(salt));
122
+ // Import the pairing code as key material
123
+ const keyMaterial = await subtle.importKey('raw', pairingCodeBuffer, { name: 'PBKDF2' }, false, [
124
+ 'deriveBits'
125
+ ]);
126
+ // Derive bits using PBKDF2 with the same parameters
127
+ // 2 << 16 = 131,072 iterations
128
+ const derivedBits = await subtle.deriveBits({
129
+ name: 'PBKDF2',
130
+ salt: saltBuffer,
131
+ iterations: 2 << 16,
132
+ hash: 'SHA-256'
133
+ }, keyMaterial, 32 * 8 // 32 bytes * 8 = 256 bits
134
+ );
135
+ return Buffer.from(derivedBits);
136
+ }
137
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1,262 @@
1
+ /**
2
+ * lib/Utils/curve25519-js.js — pure-JavaScript Curve25519 key exchange +
3
+ * XEdDSA-style signing, with zero external/native/git dependencies.
4
+ *
5
+ * Why this exists: the primary `Curve` implementation in crypto.js depends
6
+ * on the `libsignal` package, which is currently a `github:` dependency
7
+ * (see package.json and vendor-libsignal.sh) — meaning it needs `git` to
8
+ * install and, once installed, relies on that package's own native/JS
9
+ * curve implementation. This file is a self-contained fallback that only
10
+ * needs Node's built-in `crypto` module, so it keeps working even in
11
+ * environments where `libsignal` fails to install or load.
12
+ *
13
+ * `generateKeyPairJS`/`sharedKeyJS` delegate to Node's own built-in,
14
+ * standard X25519 support (`crypto.generateKeyPairSync('x25519')` /
15
+ * `crypto.diffieHellman`) — not custom math, low risk. `signJS`/`verifyJS`
16
+ * implement the XEdDSA scheme (sign/verify with a Curve25519 key, the same
17
+ * scheme Signal/WhatsApp use for signed prekeys) using standard Edwards
18
+ * curve arithmetic — publicly documented, not something invented here.
19
+ *
20
+ * This is NOT wired in as the default — see crypto.js's `CurveJS` export
21
+ * and README.md → "Pure-JS Curve25519 fallback" for how to opt into it.
22
+ * Verified via round-trip tests (sign→verify, and ECDH agreement matching
23
+ * between two independently generated keypairs) in the test suite.
24
+ */
25
+ import crypto from 'crypto';
26
+
27
+ const P = 2n ** 255n - 19n;
28
+ const L = 2n ** 252n + 27742317777372353535851937790883648493n;
29
+
30
+ function mod(a, m = P) {
31
+ const r = a % m;
32
+ return r >= 0n ? r : r + m;
33
+ }
34
+ function powmod(b, e, m) {
35
+ b = mod(b, m);
36
+ let r = 1n;
37
+ while (e > 0n) {
38
+ if (e & 1n)
39
+ r = mod(r * b, m);
40
+ b = mod(b * b, m);
41
+ e >>= 1n;
42
+ }
43
+ return r;
44
+ }
45
+ function invert(a, m = P) {
46
+ return powmod(a, m - 2n, m);
47
+ }
48
+ const D = mod(-121665n * invert(121666n));
49
+ const I = powmod(2n, (P - 1n) / 4n, P);
50
+ function pointAdd(p1, p2) {
51
+ const [X1, Y1, Z1, T1] = p1;
52
+ const [X2, Y2, Z2, T2] = p2;
53
+ const A = mod((Y1 - X1) * (Y2 - X2));
54
+ const Bb = mod((Y1 + X1) * (Y2 + X2));
55
+ const C = mod(T1 * 2n * D * T2);
56
+ const Dd = mod(Z1 * 2n * Z2);
57
+ const E = Bb - A;
58
+ const F = Dd - C;
59
+ const G = Dd + C;
60
+ const H = Bb + A;
61
+ return [mod(E * F), mod(G * H), mod(F * G), mod(E * H)];
62
+ }
63
+ function pointDouble(p) {
64
+ const [X1, Y1, Z1] = p;
65
+ const A = mod(X1 * X1);
66
+ const Bb = mod(Y1 * Y1);
67
+ const C = mod(2n * Z1 * Z1);
68
+ const H = A + Bb;
69
+ const E = H - mod((X1 + Y1) * (X1 + Y1));
70
+ const G = A - Bb;
71
+ const F = C + G;
72
+ return [mod(E * F), mod(G * H), mod(F * G), mod(E * H)];
73
+ }
74
+ function scalarMul(s, p) {
75
+ let result = [0n, 1n, 1n, 0n];
76
+ let addend = p;
77
+ s = mod(s, L * 8n);
78
+ if (s < 0n)
79
+ s += L * 8n;
80
+ while (s > 0n) {
81
+ if (s & 1n)
82
+ result = pointAdd(result, addend);
83
+ addend = pointDouble(addend);
84
+ s >>= 1n;
85
+ }
86
+ return result;
87
+ }
88
+ function negatePoint(p) {
89
+ const [X, Y, Z, T] = p;
90
+ return [mod(-X), Y, Z, mod(-T)];
91
+ }
92
+ function recoverX(y, sign) {
93
+ const y2 = y * y;
94
+ const u = mod(y2 - 1n);
95
+ const v = mod(D * y2 + 1n);
96
+ let x = mod(u * invert(v));
97
+ x = powmod(x, (P + 3n) / 8n, P);
98
+ if (mod(x * x - u * invert(v)) !== 0n) {
99
+ x = mod(x * I);
100
+ }
101
+ if (mod(x * x - u * invert(v)) !== 0n) {
102
+ throw new Error('invalid Edwards point (not on curve)');
103
+ }
104
+ if ((x & 1n) !== BigInt(sign)) {
105
+ x = P - x;
106
+ }
107
+ return x;
108
+ }
109
+ const By = mod(4n * invert(5n));
110
+ const Bx = recoverX(By, 0n);
111
+ const BASE = [mod(Bx), mod(By), 1n, mod(mod(Bx) * mod(By))];
112
+ function bigIntToBytesLE(n, len) {
113
+ const out = Buffer.alloc(len);
114
+ for (let i = 0; i < len; i++) {
115
+ out[i] = Number(n & 0xffn);
116
+ n >>= 8n;
117
+ }
118
+ return out;
119
+ }
120
+ function bytesToBigIntLE(buf) {
121
+ let n = 0n;
122
+ for (let i = buf.length - 1; i >= 0; i--) {
123
+ n = (n << 8n) | BigInt(buf[i]);
124
+ }
125
+ return n;
126
+ }
127
+ function encodePoint(p) {
128
+ const [X, Y, Z] = p;
129
+ const zinv = invert(Z);
130
+ const x = mod(X * zinv);
131
+ const y = mod(Y * zinv);
132
+ const bytes = bigIntToBytesLE(y, 32);
133
+ if (x & 1n)
134
+ bytes[31] |= 0x80;
135
+ return bytes;
136
+ }
137
+ function decodePoint(buf) {
138
+ const sign = buf[31] & 0x80 ? 1 : 0;
139
+ const y = bytesToBigIntLE(buf) & ((1n << 255n) - 1n);
140
+ const x = recoverX(y, BigInt(sign));
141
+ return [x, y, 1n, mod(x * y)];
142
+ }
143
+ function sha512(...bufs) {
144
+ const h = crypto.createHash('sha512');
145
+ for (const b of bufs)
146
+ h.update(b);
147
+ return h.digest();
148
+ }
149
+ function hashI(i, ...bufs) {
150
+ const padding = Buffer.alloc(32, 0xff);
151
+ padding[0] = 0xff - i;
152
+ const h = crypto.createHash('sha512');
153
+ h.update(padding);
154
+ for (const b of bufs)
155
+ h.update(b);
156
+ return h.digest();
157
+ }
158
+ function signBit(pointBytes) {
159
+ return pointBytes[31] & 0x80 ? 1 : 0;
160
+ }
161
+ function montgomeryUToEdwardsY(uBuf) {
162
+ const u = mod(bytesToBigIntLE(uBuf), P);
163
+ return mod((u - 1n) * invert(mod(u + 1n, P)), P);
164
+ }
165
+ function encodeYWithSign(y, sign) {
166
+ const yBytes = bigIntToBytesLE(y, 32);
167
+ if (sign)
168
+ yBytes[31] |= 0x80;
169
+ return encodePoint(decodePoint(yBytes));
170
+ }
171
+ function stripKeyTypePrefix(buf) {
172
+ return buf.length === 33 ? buf.subarray(1) : buf;
173
+ }
174
+ function calculateKeyPair(kBuf) {
175
+ const k = bytesToBigIntLE(kBuf);
176
+ const rawPoint = scalarMul(k, BASE);
177
+ const rawEnc = encodePoint(rawPoint);
178
+ let a;
179
+ let A;
180
+ if (signBit(rawEnc) === 1) {
181
+ a = mod(-k, L);
182
+ A = encodePoint(negatePoint(rawPoint));
183
+ }
184
+ else {
185
+ a = mod(k, L);
186
+ A = rawEnc;
187
+ }
188
+ return { a, A };
189
+ }
190
+
191
+ export function signJS(privateKey, message) {
192
+ const Z = crypto.randomBytes(64);
193
+ const { a, A } = calculateKeyPair(privateKey);
194
+ const aBytes = bigIntToBytesLE(a, 32);
195
+ const r = mod(bytesToBigIntLE(hashI(1, aBytes, message, Z)), L);
196
+ const R = scalarMul(r, BASE);
197
+ const REnc = encodePoint(R);
198
+ const h = mod(bytesToBigIntLE(sha512(REnc, A, message)), L);
199
+ const s = mod(r + h * a, L);
200
+ return Buffer.concat([REnc, bigIntToBytesLE(s, 32)]);
201
+ }
202
+
203
+ export function verifyJS(pubKey, message, signature) {
204
+ try {
205
+ const u = stripKeyTypePrefix(pubKey);
206
+ if (u.length !== 32 || signature.length !== 64)
207
+ return false;
208
+ const REnc = signature.subarray(0, 32);
209
+ const s = bytesToBigIntLE(signature.subarray(32, 64));
210
+ if (s >= L)
211
+ return false;
212
+ const A = encodeYWithSign(montgomeryUToEdwardsY(u), 0);
213
+ const APoint = decodePoint(A);
214
+ const h = mod(bytesToBigIntLE(sha512(REnc, A, message)), L);
215
+ const sB = scalarMul(s, BASE);
216
+ const hA = scalarMul(h, APoint);
217
+ const RCheck = pointAdd(sB, negatePoint(hA));
218
+ return encodePoint(RCheck).equals(REnc);
219
+ }
220
+ catch {
221
+ return false;
222
+ }
223
+ }
224
+
225
+ function b64url(buf) {
226
+ return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
227
+ }
228
+ function fromB64url(str) {
229
+ str = str.replace(/-/g, '+').replace(/_/g, '/');
230
+ while (str.length % 4)
231
+ str += '=';
232
+ return Buffer.from(str, 'base64');
233
+ }
234
+
235
+ export function generateKeyPairJS() {
236
+ const { publicKey, privateKey } = crypto.generateKeyPairSync('x25519');
237
+ const priv = fromB64url(privateKey.export({ format: 'jwk' }).d);
238
+ const pub = fromB64url(publicKey.export({ format: 'jwk' }).x);
239
+ return { private: priv, public: pub };
240
+ }
241
+
242
+ function generateKeyPairJS_publicFrom(privateKeyRaw) {
243
+ const k = bytesToBigIntLE(privateKeyRaw);
244
+ const point = scalarMul(k, BASE);
245
+ const [, Y, Z] = point;
246
+ const y = mod(Y * invert(Z));
247
+ const u = mod((1n + y) * invert(mod(1n - y)));
248
+ return bigIntToBytesLE(u, 32);
249
+ }
250
+
251
+ export function sharedKeyJS(privateKey, publicKey) {
252
+ const pub = stripKeyTypePrefix(publicKey);
253
+ const privKey = crypto.createPrivateKey({
254
+ key: { kty: 'OKP', crv: 'X25519', d: b64url(privateKey), x: b64url(generateKeyPairJS_publicFrom(privateKey)) },
255
+ format: 'jwk'
256
+ });
257
+ const pubKey = crypto.createPublicKey({
258
+ key: { kty: 'OKP', crv: 'X25519', x: b64url(pub) },
259
+ format: 'jwk'
260
+ });
261
+ return crypto.diffieHellman({ privateKey: privKey, publicKey: pubKey });
262
+ }