@sixcore/baileys 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +606 -0
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +4357 -0
  5. package/WAProto/index.d.ts +50383 -0
  6. package/WAProto/index.js +155693 -0
  7. package/WASignalGroup/GroupProtocol.js +1697 -0
  8. package/WASignalGroup/ciphertext_message.js +16 -0
  9. package/WASignalGroup/generate-proto.sh +1 -0
  10. package/WASignalGroup/group.proto +42 -0
  11. package/WASignalGroup/group_cipher.js +120 -0
  12. package/WASignalGroup/group_session_builder.js +46 -0
  13. package/WASignalGroup/index.js +5 -0
  14. package/WASignalGroup/keyhelper.js +21 -0
  15. package/WASignalGroup/protobufs.js +3 -0
  16. package/WASignalGroup/queue_job.js +69 -0
  17. package/WASignalGroup/sender_chain_key.js +50 -0
  18. package/WASignalGroup/sender_key_distribution_message.js +78 -0
  19. package/WASignalGroup/sender_key_message.js +92 -0
  20. package/WASignalGroup/sender_key_name.js +70 -0
  21. package/WASignalGroup/sender_key_record.js +56 -0
  22. package/WASignalGroup/sender_key_state.js +129 -0
  23. package/WASignalGroup/sender_message_key.js +39 -0
  24. package/lib/Defaults/baileys-version.json +3 -0
  25. package/lib/Defaults/index.d.ts +53 -0
  26. package/lib/Defaults/index.js +108 -0
  27. package/lib/Signal/libsignal.d.ts +3 -0
  28. package/lib/Signal/libsignal.js +152 -0
  29. package/lib/Socket/Client/abstract-socket-client.d.ts +17 -0
  30. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  31. package/lib/Socket/Client/index.d.ts +3 -0
  32. package/lib/Socket/Client/index.js +19 -0
  33. package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
  34. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  35. package/lib/Socket/Client/web-socket-client.d.ts +12 -0
  36. package/lib/Socket/Client/web-socket-client.js +62 -0
  37. package/lib/Socket/business.d.ts +170 -0
  38. package/lib/Socket/business.js +260 -0
  39. package/lib/Socket/chats.d.ts +81 -0
  40. package/lib/Socket/chats.js +950 -0
  41. package/lib/Socket/groups.d.ts +115 -0
  42. package/lib/Socket/groups.js +315 -0
  43. package/lib/Socket/index.d.ts +172 -0
  44. package/lib/Socket/index.js +10 -0
  45. package/lib/Socket/messages-recv.d.ts +158 -0
  46. package/lib/Socket/messages-recv.js +972 -0
  47. package/lib/Socket/messages-send.d.ts +155 -0
  48. package/lib/Socket/messages-send.js +1087 -0
  49. package/lib/Socket/newsletter.d.ts +132 -0
  50. package/lib/Socket/newsletter.js +236 -0
  51. package/lib/Socket/registration.d.ts +264 -0
  52. package/lib/Socket/registration.js +166 -0
  53. package/lib/Socket/socket.d.ts +44 -0
  54. package/lib/Socket/socket.js +643 -0
  55. package/lib/Socket/usync.d.ts +37 -0
  56. package/lib/Socket/usync.js +70 -0
  57. package/lib/Store/index.d.ts +3 -0
  58. package/lib/Store/index.js +10 -0
  59. package/lib/Store/make-cache-manager-store.d.ts +14 -0
  60. package/lib/Store/make-cache-manager-store.js +83 -0
  61. package/lib/Store/make-in-memory-store.d.ts +118 -0
  62. package/lib/Store/make-in-memory-store.js +431 -0
  63. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  64. package/lib/Store/make-ordered-dictionary.js +81 -0
  65. package/lib/Store/object-repository.d.ts +10 -0
  66. package/lib/Store/object-repository.js +27 -0
  67. package/lib/Types/Auth.d.ts +109 -0
  68. package/lib/Types/Auth.js +2 -0
  69. package/lib/Types/Call.d.ts +13 -0
  70. package/lib/Types/Call.js +2 -0
  71. package/lib/Types/Chat.d.ts +107 -0
  72. package/lib/Types/Chat.js +4 -0
  73. package/lib/Types/Contact.d.ts +19 -0
  74. package/lib/Types/Contact.js +2 -0
  75. package/lib/Types/Events.d.ts +172 -0
  76. package/lib/Types/Events.js +2 -0
  77. package/lib/Types/GroupMetadata.d.ts +56 -0
  78. package/lib/Types/GroupMetadata.js +2 -0
  79. package/lib/Types/Label.d.ts +46 -0
  80. package/lib/Types/Label.js +27 -0
  81. package/lib/Types/LabelAssociation.d.ts +29 -0
  82. package/lib/Types/LabelAssociation.js +9 -0
  83. package/lib/Types/Message.d.ts +433 -0
  84. package/lib/Types/Message.js +9 -0
  85. package/lib/Types/Newsletter.d.ts +92 -0
  86. package/lib/Types/Newsletter.js +32 -0
  87. package/lib/Types/Product.d.ts +78 -0
  88. package/lib/Types/Product.js +2 -0
  89. package/lib/Types/Signal.d.ts +57 -0
  90. package/lib/Types/Signal.js +2 -0
  91. package/lib/Types/Socket.d.ts +116 -0
  92. package/lib/Types/Socket.js +2 -0
  93. package/lib/Types/State.d.ts +27 -0
  94. package/lib/Types/State.js +2 -0
  95. package/lib/Types/USync.d.ts +25 -0
  96. package/lib/Types/USync.js +2 -0
  97. package/lib/Types/index.d.ts +66 -0
  98. package/lib/Types/index.js +42 -0
  99. package/lib/Utils/auth-utils.d.ts +18 -0
  100. package/lib/Utils/auth-utils.js +227 -0
  101. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  102. package/lib/Utils/baileys-event-stream.js +63 -0
  103. package/lib/Utils/business.d.ts +22 -0
  104. package/lib/Utils/business.js +234 -0
  105. package/lib/Utils/chat-utils.d.ts +70 -0
  106. package/lib/Utils/chat-utils.js +745 -0
  107. package/lib/Utils/crypto.d.ts +40 -0
  108. package/lib/Utils/crypto.js +199 -0
  109. package/lib/Utils/decode-wa-message.d.ts +36 -0
  110. package/lib/Utils/decode-wa-message.js +234 -0
  111. package/lib/Utils/event-buffer.d.ts +35 -0
  112. package/lib/Utils/event-buffer.js +517 -0
  113. package/lib/Utils/generics.d.ts +88 -0
  114. package/lib/Utils/generics.js +402 -0
  115. package/lib/Utils/history.d.ts +19 -0
  116. package/lib/Utils/history.js +94 -0
  117. package/lib/Utils/index.d.ts +17 -0
  118. package/lib/Utils/index.js +33 -0
  119. package/lib/Utils/link-preview.d.ts +21 -0
  120. package/lib/Utils/link-preview.js +93 -0
  121. package/lib/Utils/logger.d.ts +2 -0
  122. package/lib/Utils/logger.js +7 -0
  123. package/lib/Utils/lt-hash.d.ts +12 -0
  124. package/lib/Utils/lt-hash.js +51 -0
  125. package/lib/Utils/make-mutex.d.ts +7 -0
  126. package/lib/Utils/make-mutex.js +43 -0
  127. package/lib/Utils/messages-media.d.ts +113 -0
  128. package/lib/Utils/messages-media.js +643 -0
  129. package/lib/Utils/messages.d.ts +77 -0
  130. package/lib/Utils/messages.js +1221 -0
  131. package/lib/Utils/noise-handler.d.ts +20 -0
  132. package/lib/Utils/noise-handler.js +160 -0
  133. package/lib/Utils/process-message.d.ts +41 -0
  134. package/lib/Utils/process-message.js +373 -0
  135. package/lib/Utils/signal.d.ts +33 -0
  136. package/lib/Utils/signal.js +159 -0
  137. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  138. package/lib/Utils/use-multi-file-auth-state.js +295 -0
  139. package/lib/Utils/use-single-file-auth-state.d.ts +12 -0
  140. package/lib/Utils/use-single-file-auth-state.js +75 -0
  141. package/lib/Utils/validate-connection.d.ts +11 -0
  142. package/lib/Utils/validate-connection.js +205 -0
  143. package/lib/WABinary/constants.d.ts +27 -0
  144. package/lib/WABinary/constants.js +40 -0
  145. package/lib/WABinary/decode.d.ts +6 -0
  146. package/lib/WABinary/decode.js +264 -0
  147. package/lib/WABinary/encode.d.ts +2 -0
  148. package/lib/WABinary/encode.js +252 -0
  149. package/lib/WABinary/generic-utils.d.ts +14 -0
  150. package/lib/WABinary/generic-utils.js +110 -0
  151. package/lib/WABinary/index.d.ts +5 -0
  152. package/lib/WABinary/index.js +21 -0
  153. package/lib/WABinary/jid-utils.d.ts +31 -0
  154. package/lib/WABinary/jid-utils.js +62 -0
  155. package/lib/WABinary/types.d.ts +18 -0
  156. package/lib/WABinary/types.js +2 -0
  157. package/lib/WAM/BinaryInfo.d.ts +8 -0
  158. package/lib/WAM/BinaryInfo.js +13 -0
  159. package/lib/WAM/constants.d.ts +38 -0
  160. package/lib/WAM/constants.js +15350 -0
  161. package/lib/WAM/encode.d.ts +2 -0
  162. package/lib/WAM/encode.js +155 -0
  163. package/lib/WAM/index.d.ts +3 -0
  164. package/lib/WAM/index.js +19 -0
  165. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  166. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  167. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  168. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  169. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  170. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  171. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  172. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  173. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +25 -0
  174. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
  175. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +8 -0
  176. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  177. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  178. package/lib/WAUSync/Protocols/index.js +20 -0
  179. package/lib/WAUSync/USyncQuery.d.ts +28 -0
  180. package/lib/WAUSync/USyncQuery.js +89 -0
  181. package/lib/WAUSync/USyncUser.d.ts +10 -0
  182. package/lib/WAUSync/USyncUser.js +26 -0
  183. package/lib/WAUSync/index.d.ts +3 -0
  184. package/lib/WAUSync/index.js +19 -0
  185. package/lib/index.js +31 -0
  186. package/package.json +51 -0
  187. package/src/Defaults/baileys-version.json +3 -0
  188. package/src/Defaults/index.ts +133 -0
  189. package/src/Signal/Group/ciphertext-message.ts +9 -0
  190. package/src/Signal/Group/group-session-builder.ts +56 -0
  191. package/src/Signal/Group/group_cipher.ts +117 -0
  192. package/src/Signal/Group/index.ts +11 -0
  193. package/src/Signal/Group/keyhelper.ts +28 -0
  194. package/src/Signal/Group/sender-chain-key.ts +34 -0
  195. package/src/Signal/Group/sender-key-distribution-message.ts +95 -0
  196. package/src/Signal/Group/sender-key-message.ts +96 -0
  197. package/src/Signal/Group/sender-key-name.ts +66 -0
  198. package/src/Signal/Group/sender-key-record.ts +69 -0
  199. package/src/Signal/Group/sender-key-state.ts +134 -0
  200. package/src/Signal/Group/sender-message-key.ts +36 -0
  201. package/src/Signal/libsignal.ts +447 -0
  202. package/src/Signal/lid-mapping.ts +209 -0
  203. package/src/Socket/Client/index.ts +2 -0
  204. package/src/Socket/Client/types.ts +22 -0
  205. package/src/Socket/Client/websocket.ts +56 -0
  206. package/src/Socket/business.ts +421 -0
  207. package/src/Socket/chats.ts +1223 -0
  208. package/src/Socket/communities.ts +477 -0
  209. package/src/Socket/groups.ts +361 -0
  210. package/src/Socket/index.ts +22 -0
  211. package/src/Socket/messages-recv.ts +1563 -0
  212. package/src/Socket/messages-send.ts +1210 -0
  213. package/src/Socket/mex.ts +58 -0
  214. package/src/Socket/newsletter.ts +229 -0
  215. package/src/Socket/socket.ts +1072 -0
  216. package/src/Types/Auth.ts +115 -0
  217. package/src/Types/Bussines.ts +20 -0
  218. package/src/Types/Call.ts +14 -0
  219. package/src/Types/Chat.ts +138 -0
  220. package/src/Types/Contact.ts +24 -0
  221. package/src/Types/Events.ts +132 -0
  222. package/src/Types/GroupMetadata.ts +70 -0
  223. package/src/Types/Label.ts +48 -0
  224. package/src/Types/LabelAssociation.ts +35 -0
  225. package/src/Types/Message.ts +424 -0
  226. package/src/Types/Newsletter.ts +98 -0
  227. package/src/Types/Product.ts +85 -0
  228. package/src/Types/Signal.ts +76 -0
  229. package/src/Types/Socket.ts +150 -0
  230. package/src/Types/State.ts +43 -0
  231. package/src/Types/USync.ts +27 -0
  232. package/src/Types/globals.d.ts +8 -0
  233. package/src/Types/index.ts +67 -0
  234. package/src/Utils/auth-utils.ts +331 -0
  235. package/src/Utils/browser-utils.ts +31 -0
  236. package/src/Utils/business.ts +286 -0
  237. package/src/Utils/chat-utils.ts +933 -0
  238. package/src/Utils/crypto.ts +184 -0
  239. package/src/Utils/decode-wa-message.ts +355 -0
  240. package/src/Utils/event-buffer.ts +662 -0
  241. package/src/Utils/generics.ts +470 -0
  242. package/src/Utils/history.ts +114 -0
  243. package/src/Utils/index.ts +18 -0
  244. package/src/Utils/link-preview.ts +111 -0
  245. package/src/Utils/logger.ts +13 -0
  246. package/src/Utils/lt-hash.ts +65 -0
  247. package/src/Utils/make-mutex.ts +45 -0
  248. package/src/Utils/message-retry-manager.ts +229 -0
  249. package/src/Utils/messages-media.ts +820 -0
  250. package/src/Utils/messages.ts +1137 -0
  251. package/src/Utils/noise-handler.ts +192 -0
  252. package/src/Utils/pre-key-manager.ts +126 -0
  253. package/src/Utils/process-message.ts +622 -0
  254. package/src/Utils/signal.ts +214 -0
  255. package/src/Utils/use-multi-file-auth-state.ts +136 -0
  256. package/src/Utils/validate-connection.ts +253 -0
  257. package/src/WABinary/constants.ts +1305 -0
  258. package/src/WABinary/decode.ts +281 -0
  259. package/src/WABinary/encode.ts +253 -0
  260. package/src/WABinary/generic-utils.ts +127 -0
  261. package/src/WABinary/index.ts +5 -0
  262. package/src/WABinary/jid-utils.ts +128 -0
  263. package/src/WABinary/types.ts +17 -0
  264. package/src/WAM/BinaryInfo.ts +12 -0
  265. package/src/WAM/constants.ts +22889 -0
  266. package/src/WAM/encode.ts +169 -0
  267. package/src/WAM/index.ts +3 -0
  268. package/src/WAUSync/Protocols/USyncContactProtocol.ts +32 -0
  269. package/src/WAUSync/Protocols/USyncDeviceProtocol.ts +78 -0
  270. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.ts +35 -0
  271. package/src/WAUSync/Protocols/USyncStatusProtocol.ts +44 -0
  272. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.ts +76 -0
  273. package/src/WAUSync/Protocols/UsyncLIDProtocol.ts +33 -0
  274. package/src/WAUSync/Protocols/index.ts +4 -0
  275. package/src/WAUSync/USyncQuery.ts +133 -0
  276. package/src/WAUSync/USyncUser.ts +32 -0
  277. package/src/WAUSync/index.ts +3 -0
  278. package/src/index.ts +13 -0
@@ -0,0 +1,96 @@
1
+ import { calculateSignature, verifySignature } from 'libsignal/src/curve'
2
+ import { proto } from '../../../WAProto/index.js'
3
+ import { CiphertextMessage } from './ciphertext-message'
4
+
5
+ interface SenderKeyMessageStructure {
6
+ id: number
7
+ iteration: number
8
+ ciphertext: string | Buffer
9
+ }
10
+
11
+ export class SenderKeyMessage extends CiphertextMessage {
12
+ private readonly SIGNATURE_LENGTH = 64
13
+ private readonly messageVersion: number
14
+ private readonly keyId: number
15
+ private readonly iteration: number
16
+ private readonly ciphertext: Uint8Array
17
+ private readonly signature: Uint8Array
18
+ private readonly serialized: Uint8Array
19
+
20
+ constructor(
21
+ keyId?: number | null,
22
+ iteration?: number | null,
23
+ ciphertext?: Uint8Array | null,
24
+ signatureKey?: Uint8Array | null,
25
+ serialized?: Uint8Array | null
26
+ ) {
27
+ super()
28
+
29
+ if (serialized) {
30
+ const version = serialized[0]!
31
+ const message = serialized.slice(1, serialized.length - this.SIGNATURE_LENGTH)
32
+ const signature = serialized.slice(-1 * this.SIGNATURE_LENGTH)
33
+ const senderKeyMessage = proto.SenderKeyMessage.decode(message).toJSON() as SenderKeyMessageStructure
34
+
35
+ this.serialized = serialized
36
+ this.messageVersion = (version & 0xff) >> 4
37
+ this.keyId = senderKeyMessage.id
38
+ this.iteration = senderKeyMessage.iteration
39
+ this.ciphertext =
40
+ typeof senderKeyMessage.ciphertext === 'string'
41
+ ? Buffer.from(senderKeyMessage.ciphertext, 'base64')
42
+ : senderKeyMessage.ciphertext
43
+ this.signature = signature
44
+ } else {
45
+ const version = (((this.CURRENT_VERSION << 4) | this.CURRENT_VERSION) & 0xff) % 256
46
+ const ciphertextBuffer = Buffer.from(ciphertext!)
47
+ const message = proto.SenderKeyMessage.encode(
48
+ proto.SenderKeyMessage.create({
49
+ id: keyId!,
50
+ iteration: iteration!,
51
+ ciphertext: ciphertextBuffer
52
+ })
53
+ ).finish()
54
+
55
+ const signature = this.getSignature(signatureKey!, Buffer.concat([Buffer.from([version]), message]))
56
+
57
+ this.serialized = Buffer.concat([Buffer.from([version]), message, Buffer.from(signature)])
58
+ this.messageVersion = this.CURRENT_VERSION
59
+ this.keyId = keyId!
60
+ this.iteration = iteration!
61
+ this.ciphertext = ciphertextBuffer
62
+ this.signature = signature
63
+ }
64
+ }
65
+
66
+ public getKeyId(): number {
67
+ return this.keyId
68
+ }
69
+
70
+ public getIteration(): number {
71
+ return this.iteration
72
+ }
73
+
74
+ public getCipherText(): Uint8Array {
75
+ return this.ciphertext
76
+ }
77
+
78
+ public verifySignature(signatureKey: Uint8Array): void {
79
+ const part1 = this.serialized.slice(0, this.serialized.length - this.SIGNATURE_LENGTH)
80
+ const part2 = this.serialized.slice(-1 * this.SIGNATURE_LENGTH)
81
+ const res = verifySignature(signatureKey, part1, part2)
82
+ if (!res) throw new Error('Invalid signature!')
83
+ }
84
+
85
+ private getSignature(signatureKey: Uint8Array, serialized: Uint8Array): Uint8Array {
86
+ return Buffer.from(calculateSignature(signatureKey, serialized))
87
+ }
88
+
89
+ public serialize(): Uint8Array {
90
+ return this.serialized
91
+ }
92
+
93
+ public getType(): number {
94
+ return 4
95
+ }
96
+ }
@@ -0,0 +1,66 @@
1
+ interface Sender {
2
+ id: string
3
+ deviceId: number
4
+ toString(): string
5
+ }
6
+
7
+ function isNull(str: string | null): boolean {
8
+ return str === null || str === ''
9
+ }
10
+
11
+ function intValue(num: number): number {
12
+ const MAX_VALUE = 0x7fffffff
13
+ const MIN_VALUE = -0x80000000
14
+ if (num > MAX_VALUE || num < MIN_VALUE) {
15
+ return num & 0xffffffff
16
+ }
17
+
18
+ return num
19
+ }
20
+
21
+ function hashCode(strKey: string): number {
22
+ let hash = 0
23
+ if (!isNull(strKey)) {
24
+ for (let i = 0; i < strKey.length; i++) {
25
+ hash = hash * 31 + strKey.charCodeAt(i)
26
+ hash = intValue(hash)
27
+ }
28
+ }
29
+
30
+ return hash
31
+ }
32
+
33
+ export class SenderKeyName {
34
+ private readonly groupId: string
35
+ private readonly sender: Sender
36
+
37
+ constructor(groupId: string, sender: Sender) {
38
+ this.groupId = groupId
39
+ this.sender = sender
40
+ }
41
+
42
+ public getGroupId(): string {
43
+ return this.groupId
44
+ }
45
+
46
+ public getSender(): Sender {
47
+ return this.sender
48
+ }
49
+
50
+ public serialize(): string {
51
+ return `${this.groupId}::${this.sender.id}::${this.sender.deviceId}`
52
+ }
53
+
54
+ public toString(): string {
55
+ return this.serialize()
56
+ }
57
+
58
+ public equals(other: SenderKeyName | null): boolean {
59
+ if (other === null) return false
60
+ return this.groupId === other.groupId && this.sender.toString() === other.sender.toString()
61
+ }
62
+
63
+ public hashCode(): number {
64
+ return hashCode(this.groupId) ^ hashCode(this.sender.toString())
65
+ }
66
+ }
@@ -0,0 +1,69 @@
1
+ import { BufferJSON } from '../../Utils/generics'
2
+ import { SenderKeyState } from './sender-key-state'
3
+
4
+ export interface SenderKeyStateStructure {
5
+ senderKeyId: number
6
+ senderChainKey: {
7
+ iteration: number
8
+ seed: Uint8Array
9
+ }
10
+ senderSigningKey: {
11
+ public: Uint8Array
12
+ private?: Uint8Array
13
+ }
14
+ senderMessageKeys: Array<{
15
+ iteration: number
16
+ seed: Uint8Array
17
+ }>
18
+ }
19
+
20
+ export class SenderKeyRecord {
21
+ private readonly MAX_STATES = 5
22
+ private readonly senderKeyStates: SenderKeyState[] = []
23
+
24
+ constructor(serialized?: SenderKeyStateStructure[]) {
25
+ if (serialized) {
26
+ for (const structure of serialized) {
27
+ this.senderKeyStates.push(new SenderKeyState(null, null, null, null, null, null, structure))
28
+ }
29
+ }
30
+ }
31
+
32
+ public isEmpty(): boolean {
33
+ return this.senderKeyStates.length === 0
34
+ }
35
+
36
+ public getSenderKeyState(keyId?: number): SenderKeyState | undefined {
37
+ if (keyId === undefined && this.senderKeyStates.length) {
38
+ return this.senderKeyStates[this.senderKeyStates.length - 1]
39
+ }
40
+
41
+ return this.senderKeyStates.find(state => state.getKeyId() === keyId)
42
+ }
43
+
44
+ public addSenderKeyState(id: number, iteration: number, chainKey: Uint8Array, signatureKey: Uint8Array): void {
45
+ this.senderKeyStates.push(new SenderKeyState(id, iteration, chainKey, null, signatureKey))
46
+ if (this.senderKeyStates.length > this.MAX_STATES) {
47
+ this.senderKeyStates.shift()
48
+ }
49
+ }
50
+
51
+ public setSenderKeyState(
52
+ id: number,
53
+ iteration: number,
54
+ chainKey: Uint8Array,
55
+ keyPair: { public: Uint8Array; private: Uint8Array }
56
+ ): void {
57
+ this.senderKeyStates.length = 0
58
+ this.senderKeyStates.push(new SenderKeyState(id, iteration, chainKey, keyPair))
59
+ }
60
+
61
+ public serialize(): SenderKeyStateStructure[] {
62
+ return this.senderKeyStates.map(state => state.getStructure())
63
+ }
64
+ static deserialize(data: Uint8Array): SenderKeyRecord {
65
+ const str = Buffer.from(data).toString('utf-8')
66
+ const parsed = JSON.parse(str, BufferJSON.reviver)
67
+ return new SenderKeyRecord(parsed)
68
+ }
69
+ }
@@ -0,0 +1,134 @@
1
+ import { SenderChainKey } from './sender-chain-key'
2
+ import { SenderMessageKey } from './sender-message-key'
3
+
4
+ interface SenderChainKeyStructure {
5
+ iteration: number
6
+ seed: Uint8Array
7
+ }
8
+
9
+ interface SenderSigningKeyStructure {
10
+ public: Uint8Array
11
+ private?: Uint8Array
12
+ }
13
+
14
+ interface SenderMessageKeyStructure {
15
+ iteration: number
16
+ seed: Uint8Array
17
+ }
18
+
19
+ interface SenderKeyStateStructure {
20
+ senderKeyId: number
21
+ senderChainKey: SenderChainKeyStructure
22
+ senderSigningKey: SenderSigningKeyStructure
23
+ senderMessageKeys: SenderMessageKeyStructure[]
24
+ }
25
+
26
+ export class SenderKeyState {
27
+ private readonly MAX_MESSAGE_KEYS = 2000
28
+ private readonly senderKeyStateStructure: SenderKeyStateStructure
29
+
30
+ constructor(
31
+ id?: number | null,
32
+ iteration?: number | null,
33
+ chainKey?: Uint8Array | null | string,
34
+ signatureKeyPair?: { public: Uint8Array | string; private: Uint8Array | string } | null,
35
+ signatureKeyPublic?: Uint8Array | string | null,
36
+ signatureKeyPrivate?: Uint8Array | string | null,
37
+ senderKeyStateStructure?: SenderKeyStateStructure | null
38
+ ) {
39
+ if (senderKeyStateStructure) {
40
+ this.senderKeyStateStructure = {
41
+ ...senderKeyStateStructure,
42
+ senderMessageKeys: Array.isArray(senderKeyStateStructure.senderMessageKeys)
43
+ ? senderKeyStateStructure.senderMessageKeys
44
+ : []
45
+ }
46
+ } else {
47
+ if (signatureKeyPair) {
48
+ signatureKeyPublic = signatureKeyPair.public
49
+ signatureKeyPrivate = signatureKeyPair.private
50
+ }
51
+
52
+ this.senderKeyStateStructure = {
53
+ senderKeyId: id || 0,
54
+ senderChainKey: {
55
+ iteration: iteration || 0,
56
+ seed: Buffer.from(chainKey || [])
57
+ },
58
+ senderSigningKey: {
59
+ public: Buffer.from(signatureKeyPublic || []),
60
+ private: Buffer.from(signatureKeyPrivate || [])
61
+ },
62
+ senderMessageKeys: []
63
+ }
64
+ }
65
+ }
66
+
67
+ public getKeyId(): number {
68
+ return this.senderKeyStateStructure.senderKeyId
69
+ }
70
+
71
+ public getSenderChainKey(): SenderChainKey {
72
+ return new SenderChainKey(
73
+ this.senderKeyStateStructure.senderChainKey.iteration,
74
+ this.senderKeyStateStructure.senderChainKey.seed
75
+ )
76
+ }
77
+
78
+ public setSenderChainKey(chainKey: SenderChainKey): void {
79
+ this.senderKeyStateStructure.senderChainKey = {
80
+ iteration: chainKey.getIteration(),
81
+ seed: chainKey.getSeed()
82
+ }
83
+ }
84
+
85
+ public getSigningKeyPublic(): Buffer {
86
+ const publicKey = Buffer.from(this.senderKeyStateStructure.senderSigningKey.public)
87
+
88
+ if (publicKey.length === 32) {
89
+ const fixed = Buffer.alloc(33)
90
+ fixed[0] = 0x05
91
+ publicKey.copy(fixed, 1)
92
+ return fixed
93
+ }
94
+
95
+ return publicKey
96
+ }
97
+
98
+ public getSigningKeyPrivate(): Buffer | undefined {
99
+ const privateKey = this.senderKeyStateStructure.senderSigningKey.private
100
+
101
+ return Buffer.from(privateKey || [])
102
+ }
103
+
104
+ public hasSenderMessageKey(iteration: number): boolean {
105
+ return this.senderKeyStateStructure.senderMessageKeys.some(key => key.iteration === iteration)
106
+ }
107
+
108
+ public addSenderMessageKey(senderMessageKey: SenderMessageKey): void {
109
+ this.senderKeyStateStructure.senderMessageKeys.push({
110
+ iteration: senderMessageKey.getIteration(),
111
+ seed: senderMessageKey.getSeed()
112
+ })
113
+
114
+ if (this.senderKeyStateStructure.senderMessageKeys.length > this.MAX_MESSAGE_KEYS) {
115
+ this.senderKeyStateStructure.senderMessageKeys.shift()
116
+ }
117
+ }
118
+
119
+ public removeSenderMessageKey(iteration: number): SenderMessageKey | null {
120
+ const index = this.senderKeyStateStructure.senderMessageKeys.findIndex(key => key.iteration === iteration)
121
+
122
+ if (index !== -1) {
123
+ const messageKey = this.senderKeyStateStructure.senderMessageKeys[index]!
124
+ this.senderKeyStateStructure.senderMessageKeys.splice(index, 1)
125
+ return new SenderMessageKey(messageKey.iteration, messageKey.seed)
126
+ }
127
+
128
+ return null
129
+ }
130
+
131
+ public getStructure(): SenderKeyStateStructure {
132
+ return this.senderKeyStateStructure
133
+ }
134
+ }
@@ -0,0 +1,36 @@
1
+ import { deriveSecrets } from 'libsignal/src/crypto'
2
+
3
+ export class SenderMessageKey {
4
+ private readonly iteration: number
5
+ private readonly iv: Uint8Array
6
+ private readonly cipherKey: Uint8Array
7
+ private readonly seed: Uint8Array
8
+
9
+ constructor(iteration: number, seed: Uint8Array) {
10
+ const derivative = deriveSecrets(seed, Buffer.alloc(32), Buffer.from('WhisperGroup'))
11
+ const keys = new Uint8Array(32)
12
+ keys.set(new Uint8Array(derivative[0].slice(16)))
13
+ keys.set(new Uint8Array(derivative[1].slice(0, 16)), 16)
14
+
15
+ this.iv = Buffer.from(derivative[0].slice(0, 16))
16
+ this.cipherKey = Buffer.from(keys.buffer)
17
+ this.iteration = iteration
18
+ this.seed = seed
19
+ }
20
+
21
+ public getIteration(): number {
22
+ return this.iteration
23
+ }
24
+
25
+ public getIv(): Uint8Array {
26
+ return this.iv
27
+ }
28
+
29
+ public getCipherKey(): Uint8Array {
30
+ return this.cipherKey
31
+ }
32
+
33
+ public getSeed(): Uint8Array {
34
+ return this.seed
35
+ }
36
+ }