wowok 2.1.41 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/cjs/w/call/guard.d.ts +2 -0
  2. package/dist/cjs/w/call/guard.js +1 -1
  3. package/dist/cjs/w/call/repository.js +1 -1
  4. package/dist/cjs/w/call/util.js +1 -1
  5. package/dist/cjs/w/messenger/messenger-manager.js +1 -1
  6. package/dist/cjs/w/messenger/messenger.js +1 -1
  7. package/dist/cjs/w/messenger/pq/crypto.d.ts +39 -0
  8. package/dist/cjs/w/messenger/pq/crypto.js +1 -0
  9. package/dist/cjs/w/messenger/pq/erasure.d.ts +17 -0
  10. package/dist/cjs/w/messenger/pq/erasure.js +1 -0
  11. package/dist/cjs/w/messenger/pq/index.d.ts +9 -0
  12. package/dist/cjs/w/messenger/pq/index.js +1 -0
  13. package/dist/cjs/w/messenger/pq/keycombiner.d.ts +1 -0
  14. package/dist/cjs/w/messenger/pq/keycombiner.js +1 -0
  15. package/dist/cjs/w/messenger/pq/pqxdh.d.ts +41 -0
  16. package/dist/cjs/w/messenger/pq/pqxdh.js +1 -0
  17. package/dist/cjs/w/messenger/pq/ratchet.d.ts +12 -0
  18. package/dist/cjs/w/messenger/pq/ratchet.js +1 -0
  19. package/dist/cjs/w/messenger/pq/session.d.ts +39 -0
  20. package/dist/cjs/w/messenger/pq/session.js +1 -0
  21. package/dist/cjs/w/messenger/pq/spqr.d.ts +23 -0
  22. package/dist/cjs/w/messenger/pq/spqr.js +1 -0
  23. package/dist/cjs/w/messenger/pq/store-adapter.d.ts +33 -0
  24. package/dist/cjs/w/messenger/pq/store-adapter.js +1 -0
  25. package/dist/cjs/w/messenger/pq/types.d.ts +181 -0
  26. package/dist/cjs/w/messenger/pq/types.js +1 -0
  27. package/dist/cjs/w/messenger/session.d.ts +15 -16
  28. package/dist/cjs/w/messenger/session.js +1 -1
  29. package/dist/cjs/w/messenger/storage.d.ts +2 -0
  30. package/dist/cjs/w/messenger/storage.js +1 -1
  31. package/dist/cjs/w/messenger/types.d.ts +15 -1
  32. package/dist/cjs/w/messenger/types.js +1 -1
  33. package/dist/cjs/w/messenger/utils.js +1 -1
  34. package/dist/cjs/w/query/object.js +1 -1
  35. package/dist/esm/w/call/guard.d.ts +2 -0
  36. package/dist/esm/w/call/guard.js +1 -1
  37. package/dist/esm/w/call/repository.js +1 -1
  38. package/dist/esm/w/call/util.js +1 -1
  39. package/dist/esm/w/messenger/messenger-manager.js +1 -1
  40. package/dist/esm/w/messenger/messenger.js +1 -1
  41. package/dist/esm/w/messenger/pq/crypto.d.ts +39 -0
  42. package/dist/esm/w/messenger/pq/crypto.js +1 -0
  43. package/dist/esm/w/messenger/pq/erasure.d.ts +17 -0
  44. package/dist/esm/w/messenger/pq/erasure.js +1 -0
  45. package/dist/esm/w/messenger/pq/index.d.ts +9 -0
  46. package/dist/esm/w/messenger/pq/index.js +1 -0
  47. package/dist/esm/w/messenger/pq/keycombiner.d.ts +1 -0
  48. package/dist/esm/w/messenger/pq/keycombiner.js +1 -0
  49. package/dist/esm/w/messenger/pq/pqxdh.d.ts +41 -0
  50. package/dist/esm/w/messenger/pq/pqxdh.js +1 -0
  51. package/dist/esm/w/messenger/pq/ratchet.d.ts +12 -0
  52. package/dist/esm/w/messenger/pq/ratchet.js +1 -0
  53. package/dist/esm/w/messenger/pq/session.d.ts +39 -0
  54. package/dist/esm/w/messenger/pq/session.js +1 -0
  55. package/dist/esm/w/messenger/pq/spqr.d.ts +23 -0
  56. package/dist/esm/w/messenger/pq/spqr.js +1 -0
  57. package/dist/esm/w/messenger/pq/store-adapter.d.ts +33 -0
  58. package/dist/esm/w/messenger/pq/store-adapter.js +1 -0
  59. package/dist/esm/w/messenger/pq/types.d.ts +181 -0
  60. package/dist/esm/w/messenger/pq/types.js +1 -0
  61. package/dist/esm/w/messenger/session.d.ts +15 -16
  62. package/dist/esm/w/messenger/session.js +1 -1
  63. package/dist/esm/w/messenger/storage.d.ts +2 -0
  64. package/dist/esm/w/messenger/storage.js +1 -1
  65. package/dist/esm/w/messenger/types.d.ts +15 -1
  66. package/dist/esm/w/messenger/types.js +1 -1
  67. package/dist/esm/w/messenger/utils.js +1 -1
  68. package/dist/esm/w/query/object.js +1 -1
  69. package/package.json +43 -3
@@ -0,0 +1,17 @@
1
+ declare const DATA_SHARDS = 28;
2
+ declare const PARITY_SHARDS = 28;
3
+ declare const TOTAL_SHARDS = 56;
4
+ declare const SHARD_DATA_SIZE = 44;
5
+ declare const SHARD_HEADER_SIZE = 8;
6
+ declare const SHARD_SIZE: number;
7
+ export declare function encodeShards(data: Uint8Array): Uint8Array[];
8
+ export declare function decodeShards(availableShards: Map<number, Uint8Array>, totalShards: number): Uint8Array;
9
+ export interface SPQRChunkData {
10
+ cycleId: number;
11
+ chunkIndex: number;
12
+ totalChunks: number;
13
+ data: Uint8Array;
14
+ }
15
+ export declare function packChunk(chunk: SPQRChunkData): Uint8Array;
16
+ export declare function unpackChunk(packed: Uint8Array): SPQRChunkData;
17
+ export { DATA_SHARDS, PARITY_SHARDS, TOTAL_SHARDS, SHARD_DATA_SIZE, SHARD_HEADER_SIZE, SHARD_SIZE, };
@@ -0,0 +1 @@
1
+ import{PQError,PQErrorCode}from'./types.js';const DATA_SHARDS=0x1c,PARITY_SHARDS=0x1c,TOTAL_SHARDS=0x38,SHARD_DATA_SIZE=0x2c,SHARD_HEADER_SIZE=0x8,SHARD_SIZE=SHARD_DATA_SIZE+SHARD_HEADER_SIZE,EXP_TABLE=new Array(0x200),LOG_TABLE=new Array(0x100);function initGFTables(){if(EXP_TABLE[0x0]!==undefined)return;let a=0x1;for(let b=0x0;b<0xff;b++){EXP_TABLE[b]=a,EXP_TABLE[b+0xff]=a,LOG_TABLE[a]=b,a<<=0x1,a&0x100&&(a^=0x11d);}LOG_TABLE[0x0]=0x0;}function gfMul(c,d){if(c===0x0||d===0x0)return 0x0;return initGFTables(),EXP_TABLE[(LOG_TABLE[c]+LOG_TABLE[d])%0xff];}function gfDiv(c,d){if(c===0x0)return 0x0;if(d===0x0)throw new PQError(PQErrorCode['ERASURE_ERROR'],'Division\x20by\x20zero');initGFTables();const e=(LOG_TABLE[c]-LOG_TABLE[d]+0xff)%0xff;return EXP_TABLE[e];}function buildVandermondeMatrix(a,b,c=0x0){const d=[];for(let e=0x0;e<a;e++){d[e]=[];for(let f=0x0;f<b;f++){d[e][f]=gfPow(c+e,f);}}return d;}function buildEncodingMatrix(a,b){const c=[];for(let f=0x0;f<b;f++){c[f]=new Array(b)['fill'](0x0),c[f][f]=0x1;}const d=a-b,e=buildVandermondeMatrix(d,b,b);for(let g=0x0;g<d;g++){c[b+g]=e[g];}return c;}function gfPow(a,b){if(b===0x0)return 0x1;if(a===0x0)return 0x0;let c=0x1;for(let d=0x0;d<b;d++){c=gfMul(c,a);}return c;}function matrixInvert(a){const b=a['length'],c=[];for(let e=0x0;e<b;e++){c[e]=[...a[e]];for(let f=0x0;f<b;f++){c[e]['push'](e===f?0x1:0x0);}}for(let g=0x0;g<b;g++){let h=g;while(h<b&&c[h][g]===0x0){h++;}if(h===b)throw new PQError(PQErrorCode['ERASURE_ERROR'],'Matrix\x20is\x20singular');h!==g&&([c[g],c[h]]=[c[h],c[g]]);const k=gfDiv(0x1,c[g][g]);for(let l=0x0;l<0x2*b;l++){c[g][l]=gfMul(c[g][l],k);}for(let m=0x0;m<b;m++){if(m!==g){const o=c[m][g];if(o!==0x0)for(let p=0x0;p<0x2*b;p++){c[m][p]^=gfMul(o,c[g][p]);}}}}const d=[];for(let q=0x0;q<b;q++){d[q]=c[q]['slice'](b);}return d;}export function encodeShards(a){const b=DATA_SHARDS*SHARD_DATA_SIZE;if(a['length']>b)throw new PQError(PQErrorCode['ERASURE_ERROR'],'Data\x20too\x20large:\x20'+a['length']+'\x20>\x20'+b);const c=new Uint8Array(b);c['set'](a);const d=[];for(let f=0x0;f<DATA_SHARDS;f++){d[f]=c['slice'](f*SHARD_DATA_SIZE,(f+0x1)*SHARD_DATA_SIZE);}const e=buildVandermondeMatrix(PARITY_SHARDS,DATA_SHARDS,DATA_SHARDS);for(let g=0x0;g<PARITY_SHARDS;g++){const h=new Uint8Array(SHARD_DATA_SIZE);for(let l=0x0;l<SHARD_DATA_SIZE;l++){let m=0x0;for(let n=0x0;n<DATA_SHARDS;n++){m^=gfMul(e[g][n],d[n][l]);}h[l]=m;}d[DATA_SHARDS+g]=h;}return d;}export function decodeShards(a,b){const c=Array['from'](a['keys']())['sort']((l,m)=>l-m);if(c['length']<DATA_SHARDS)throw new PQError(PQErrorCode['ERASURE_ERROR'],'Need\x20at\x20least\x20'+DATA_SHARDS+'\x20shards,\x20got\x20'+c['length']);const d=c['slice'](0x0,DATA_SHARDS),e=buildEncodingMatrix(b,DATA_SHARDS),f=[];for(const l of d){f['push'](e[l]);}const g=matrixInvert(f),h=new Uint8Array(DATA_SHARDS*SHARD_DATA_SIZE);for(let m=0x0;m<DATA_SHARDS;m++){for(let n=0x0;n<SHARD_DATA_SIZE;n++){let o=0x0;for(let p=0x0;p<DATA_SHARDS;p++){const q=a['get'](d[p]);o^=gfMul(g[m][p],q[n]);}h[m*SHARD_DATA_SIZE+n]=o;}}return h;}export function packChunk(a){const b=new Uint8Array(SHARD_SIZE),c=new DataView(b['buffer']);return c['setUint32'](0x0,a['cycleId'],![]),c['setUint16'](0x4,a['chunkIndex'],![]),c['setUint16'](0x6,a['totalChunks'],![]),b['set'](a['data']['slice'](0x0,SHARD_DATA_SIZE),SHARD_HEADER_SIZE),b;}export function unpackChunk(a){if(a['length']<SHARD_SIZE)throw new PQError(PQErrorCode['ERASURE_ERROR'],'Chunk\x20too\x20small:\x20'+a['length']+'\x20<\x20'+SHARD_SIZE);const b=new DataView(a['buffer'],a['byteOffset'],a['byteLength']),c=b['getUint32'](0x0,![]),d=b['getUint16'](0x4,![]),e=b['getUint16'](0x6,![]),f=a['slice'](SHARD_HEADER_SIZE,SHARD_HEADER_SIZE+SHARD_DATA_SIZE);return{'cycleId':c,'chunkIndex':d,'totalChunks':e,'data':f};}export{DATA_SHARDS,PARITY_SHARDS,TOTAL_SHARDS,SHARD_DATA_SIZE,SHARD_HEADER_SIZE,SHARD_SIZE};
@@ -0,0 +1,9 @@
1
+ export * from "./types.js";
2
+ export * from "./crypto.js";
3
+ export * from "./pqxdh.js";
4
+ export * from "./ratchet.js";
5
+ export * from "./erasure.js";
6
+ export * from "./spqr.js";
7
+ export * from "./keycombiner.js";
8
+ export * from "./session.js";
9
+ export * from "./store-adapter.js";
@@ -0,0 +1 @@
1
+ export*from'./types.js';export*from'./crypto.js';export*from'./pqxdh.js';export*from'./ratchet.js';export*from'./erasure.js';export*from'./spqr.js';export*from'./keycombiner.js';export*from'./session.js';export*from'./store-adapter.js';
@@ -0,0 +1 @@
1
+ export declare function combineKeys(dhMessageKey: Uint8Array, spqrKey: Uint8Array): Uint8Array;
@@ -0,0 +1 @@
1
+ import{hkdfDerive,concatBytes}from'./crypto.js';import{MESSAGE_KEY_SIZE}from'./types.js';export function combineKeys(a,b){return hkdfDerive(concatBytes(a,b),new TextEncoder()['encode']('WowokPQCombinedKey'),MESSAGE_KEY_SIZE);}
@@ -0,0 +1,41 @@
1
+ import type { X25519KeyPair, MLKEMKeyPair, PQPreKeyBundle, PQXDHResult } from "./types.js";
2
+ export interface PQXDHInitiateResult {
3
+ result: PQXDHResult;
4
+ initialMessage: {
5
+ ephemeralPublicKey: Uint8Array;
6
+ mlkemCiphertext: Uint8Array;
7
+ identityKey: Uint8Array;
8
+ };
9
+ }
10
+ export declare function pqxdhInitiate(ourIdentityKeyPair: X25519KeyPair, ourEd25519KeyPair: {
11
+ publicKey: Uint8Array;
12
+ privateKey: Uint8Array;
13
+ }, peerBundle: PQPreKeyBundle): PQXDHInitiateResult;
14
+ export declare function pqxdhReceive(ourIdentityKeyPair: X25519KeyPair, ourSignedPreKeyPair: X25519KeyPair, ourOneTimePreKeyPair: X25519KeyPair | null, ourPQPreKeyPair: MLKEMKeyPair, peerEphemeralPublicKey: Uint8Array, peerIdentityKey: Uint8Array, mlkemCiphertext: Uint8Array): PQXDHResult;
15
+ export interface GeneratedPreKeyBundle {
16
+ identityKeyPair: X25519KeyPair;
17
+ ed25519KeyPair: {
18
+ publicKey: Uint8Array;
19
+ privateKey: Uint8Array;
20
+ };
21
+ registrationId: number;
22
+ signedPreKey: {
23
+ keyId: number;
24
+ keyPair: X25519KeyPair;
25
+ signature: Uint8Array;
26
+ };
27
+ oneTimePreKeys: Array<{
28
+ keyId: number;
29
+ keyPair: X25519KeyPair;
30
+ }>;
31
+ pqPreKey: {
32
+ keyId: number;
33
+ keyPair: MLKEMKeyPair;
34
+ signature: Uint8Array;
35
+ };
36
+ }
37
+ export declare function generatePreKeyBundle(identityKeyPair: X25519KeyPair, ed25519KeyPair: {
38
+ publicKey: Uint8Array;
39
+ privateKey: Uint8Array;
40
+ }, signedPreKeyId: number, pqPreKeyId: number, oneTimePreKeyCount: number): GeneratedPreKeyBundle;
41
+ export declare function verifyPreKeyBundle(bundle: PQPreKeyBundle): boolean;
@@ -0,0 +1 @@
1
+ import{generateX25519KeyPair,x25519DH,ed25519Sign,ed25519Verify,generateMLKEMKeyPair,mlkemEncapsulate,mlkemDecapsulate,hkdfDerive,concatBytes,deriveRegistrationId}from'./crypto.js';import{ROOT_KEY_SIZE,CHAIN_KEY_SIZE}from'./types.js';export function pqxdhInitiate(a,b,c){const d=generateX25519KeyPair(),e=x25519DH(d['privateKey'],c['identityKey']),f=x25519DH(a['privateKey'],c['signedPreKey']['publicKey']),g=x25519DH(d['privateKey'],c['signedPreKey']['publicKey']),{ciphertext:h,sharedSecret:i}=mlkemEncapsulate(c['pqPreKey']['publicKey']);let j;if(c['oneTimePreKey']){const n=x25519DH(d['privateKey'],c['oneTimePreKey']['publicKey']);j=concatBytes(e,f,g,n,i);}else j=concatBytes(e,f,g,i);const k=concatBytes(new TextEncoder()['encode']('WowokPQXDH'),a['publicKey'],c['identityKey']),l=hkdfDerive(j,k,ROOT_KEY_SIZE+CHAIN_KEY_SIZE),m={'rootKey':l['slice'](0x0,ROOT_KEY_SIZE),'chainKey':l['slice'](ROOT_KEY_SIZE,ROOT_KEY_SIZE+CHAIN_KEY_SIZE),'ourDHKeyPair':d,'peerDHPublicKey':c['signedPreKey']['publicKey'],'peerIdentityKey':c['identityKey'],'pqSharedSecret':i};return{'result':m,'initialMessage':{'ephemeralPublicKey':d['publicKey'],'mlkemCiphertext':h,'identityKey':a['publicKey']}};}export function pqxdhReceive(a,b,c,d,e,f,g){const h=x25519DH(a['privateKey'],e),i=x25519DH(b['privateKey'],f),j=x25519DH(b['privateKey'],e),k=mlkemDecapsulate(g,d['secretKey']);let l;if(c){const o=x25519DH(c['privateKey'],e);l=concatBytes(h,i,j,o,k);}else l=concatBytes(h,i,j,k);const m=concatBytes(new TextEncoder()['encode']('WowokPQXDH'),f,a['publicKey']),n=hkdfDerive(l,m,ROOT_KEY_SIZE+CHAIN_KEY_SIZE);return{'rootKey':n['slice'](0x0,ROOT_KEY_SIZE),'chainKey':n['slice'](ROOT_KEY_SIZE,ROOT_KEY_SIZE+CHAIN_KEY_SIZE),'ourDHKeyPair':b,'peerDHPublicKey':e,'peerIdentityKey':f,'pqSharedSecret':k};}export function generatePreKeyBundle(a,b,c,d,e){const f=deriveRegistrationId(a['publicKey']),g=generateX25519KeyPair(),h=ed25519Sign(b['privateKey'],g['publicKey']),j=[];for(let m=0x0;m<e;m++){j['push']({'keyId':m+0x1,'keyPair':generateX25519KeyPair()});}const k=generateMLKEMKeyPair(),l=ed25519Sign(b['privateKey'],k['publicKey']);return{'identityKeyPair':a,'ed25519KeyPair':b,'registrationId':f,'signedPreKey':{'keyId':c,'keyPair':g,'signature':h},'oneTimePreKeys':j,'pqPreKey':{'keyId':d,'keyPair':k,'signature':l}};}export function verifyPreKeyBundle(a){if(!a['ed25519PublicKey']||a['ed25519PublicKey']['length']!==0x20)return![];if(!a['signedPreKey'])return![];const b=ed25519Verify(a['ed25519PublicKey'],a['signedPreKey']['publicKey'],a['signedPreKey']['signature']);if(!b)return![];if(!a['pqPreKey'])return![];const c=ed25519Verify(a['ed25519PublicKey'],a['pqPreKey']['publicKey'],a['pqPreKey']['signature']);if(!c)return![];return!![];}
@@ -0,0 +1,12 @@
1
+ import type { RatchetState, X25519KeyPair, EncryptedMessage, SerializedRatchetState } from "./types.js";
2
+ export declare function initRatchet(rootKey: Uint8Array, sendingChainKey: Uint8Array, receivingChainKey: Uint8Array, ourDHKeyPair: X25519KeyPair, peerDHPublicKey: Uint8Array): RatchetState;
3
+ export declare function ratchetEncrypt(state: RatchetState, plaintext: Uint8Array): {
4
+ message: EncryptedMessage;
5
+ newState: RatchetState;
6
+ };
7
+ export declare function ratchetDecrypt(state: RatchetState, messageBody: Uint8Array): {
8
+ plaintext: Uint8Array;
9
+ newState: RatchetState;
10
+ };
11
+ export declare function serializeRatchetState(state: RatchetState): SerializedRatchetState;
12
+ export declare function deserializeRatchetState(serialized: SerializedRatchetState): RatchetState;
@@ -0,0 +1 @@
1
+ import{generateX25519KeyPair,x25519DH,hkdfChainKey,hkdfMessageKey,aesGcmEncrypt,aesGcmDecrypt,concatBytes}from'./crypto.js';import{MessageType,PQError,PQErrorCode}from'./types.js';function encodeHeader(a){const b=new Uint8Array(0x20+0x4+0x4);b['set'](a['dhPublicKey'],0x0);const c=new DataView(b['buffer']);return c['setUint32'](0x20,a['previousSendingCount'],![]),c['setUint32'](0x24,a['messageCount'],![]),b;}function decodeHeader(a){const b=a['slice'](0x0,0x20),c=new DataView(a['buffer'],a['byteOffset'],a['byteLength']),d=c['getUint32'](0x20,![]),e=c['getUint32'](0x24,![]);return{'dhPublicKey':b,'previousSendingCount':d,'messageCount':e};}function makeSkipKey(a,b){const c=new Uint8Array(a['length']+0x4);return c['set'](a,0x0),new DataView(c['buffer'])['setUint32'](a['length'],b,![]),Buffer['from'](c)['toString']('base64');}export function initRatchet(a,b,c,d,e){return{'rootKey':a,'sendingChainKey':b,'sendingMessageCount':0x0,'receivingChainKey':c,'receivingMessageCount':0x0,'ourDHKeyPair':d,'peerDHPublicKey':e,'previousSendingCount':0x0,'skipMessageKeys':new Map()};}export function ratchetEncrypt(a,b){const c=cloneRatchetState(a),{messageKey:d,nextChainKey:e}=hkdfMessageKey(c['sendingChainKey']);c['sendingChainKey']=e;const f={'dhPublicKey':c['ourDHKeyPair']['publicKey'],'previousSendingCount':c['previousSendingCount'],'messageCount':c['sendingMessageCount']},g=encodeHeader(f),{ciphertext:h,iv:i,tag:j}=aesGcmEncrypt(d,b,g),k=concatBytes(g,i,j,h);return c['sendingMessageCount']+=0x1,{'message':{'type':MessageType['NORMAL_MESSAGE'],'body':k},'newState':c};}export function ratchetDecrypt(a,b){const c=0x20+0x4+0x4;if(b['length']<c+0xc+0x10)throw new PQError(PQErrorCode['DECRYPTION_FAILED'],'Message\x20body\x20too\x20short');const d=b['slice'](0x0,c),e=decodeHeader(d),f=b['slice'](c,c+0xc),g=b['slice'](c+0xc,c+0xc+0x10),h=b['slice'](c+0xc+0x10),i=cloneRatchetState(a);let j;if(i['peerDHPublicKey']&&Buffer['from'](e['dhPublicKey'])['equals'](Buffer['from'](i['peerDHPublicKey']))){if(e['messageCount']<i['receivingMessageCount']){j=trySkippedMessageKeys(i,e);if(!j)throw new PQError(PQErrorCode['DECRYPTION_FAILED'],'Message\x20key\x20not\x20found\x20for\x20old\x20message');}else{while(i['receivingMessageCount']<e['messageCount']){const {messageKey:n,nextChainKey:o}=hkdfMessageKey(i['receivingChainKey']),p=makeSkipKey(e['dhPublicKey'],i['receivingMessageCount']);i['skipMessageKeys']['set'](p,n),i['receivingChainKey']=o,i['receivingMessageCount']+=0x1;}const {messageKey:l,nextChainKey:m}=hkdfMessageKey(i['receivingChainKey']);j=l,i['receivingChainKey']=m,i['receivingMessageCount']+=0x1;}}else{j=trySkippedMessageKeys(i,e);if(!j){const q=dhRatchetStep(i,e);Object['assign'](i,q['newState']),j=q['messageKey'];}}const k=aesGcmDecrypt(j,h,f,g,d);return{'plaintext':k,'newState':i};}function dhRatchetStep(a,b){a['previousSendingCount']=a['sendingMessageCount'];const c=x25519DH(a['ourDHKeyPair']['privateKey'],b['dhPublicKey']),{rootKey:d,chainKey:e}=hkdfChainKey(a['rootKey'],c),f=generateX25519KeyPair(),g=x25519DH(f['privateKey'],b['dhPublicKey']),{rootKey:h,chainKey:i}=hkdfChainKey(d,g),{messageKey:j}=hkdfMessageKey(e);return{'messageKey':j,'newState':{'rootKey':h,'sendingChainKey':e,'sendingMessageCount':0x0,'receivingChainKey':i,'receivingMessageCount':0x1,'ourDHKeyPair':f,'peerDHPublicKey':b['dhPublicKey'],'previousSendingCount':b['previousSendingCount']}};}function trySkippedMessageKeys(a,b){const c=makeSkipKey(b['dhPublicKey'],b['messageCount']),d=a['skipMessageKeys']['get'](c);if(d)return a['skipMessageKeys']['delete'](c),d;return null;}function cloneRatchetState(a){return{'rootKey':new Uint8Array(a['rootKey']),'sendingChainKey':new Uint8Array(a['sendingChainKey']),'sendingMessageCount':a['sendingMessageCount'],'receivingChainKey':new Uint8Array(a['receivingChainKey']),'receivingMessageCount':a['receivingMessageCount'],'ourDHKeyPair':{'publicKey':new Uint8Array(a['ourDHKeyPair']['publicKey']),'privateKey':new Uint8Array(a['ourDHKeyPair']['privateKey'])},'peerDHPublicKey':a['peerDHPublicKey']?new Uint8Array(a['peerDHPublicKey']):null,'previousSendingCount':a['previousSendingCount'],'skipMessageKeys':new Map(a['skipMessageKeys'])};}export function serializeRatchetState(a){const b={};for(const [c,d]of a['skipMessageKeys']){b[c]=Buffer['from'](d)['toString']('base64');}return{'rootKey':Buffer['from'](a['rootKey'])['toString']('base64'),'sendingChainKey':Buffer['from'](a['sendingChainKey'])['toString']('base64'),'sendingMessageCount':a['sendingMessageCount'],'receivingChainKey':Buffer['from'](a['receivingChainKey'])['toString']('base64'),'receivingMessageCount':a['receivingMessageCount'],'ourDHPrivateKey':Buffer['from'](a['ourDHKeyPair']['privateKey'])['toString']('base64'),'ourDHPublicKey':Buffer['from'](a['ourDHKeyPair']['publicKey'])['toString']('base64'),'peerDHPublicKey':a['peerDHPublicKey']?Buffer['from'](a['peerDHPublicKey'])['toString']('base64'):null,'previousSendingCount':a['previousSendingCount'],'skipMessageKeys':b};}export function deserializeRatchetState(a){const b=new Map();for(const [c,d]of Object['entries'](a['skipMessageKeys'])){b['set'](c,new Uint8Array(Buffer['from'](d,'base64')));}return{'rootKey':new Uint8Array(Buffer['from'](a['rootKey'],'base64')),'sendingChainKey':new Uint8Array(Buffer['from'](a['sendingChainKey'],'base64')),'sendingMessageCount':a['sendingMessageCount'],'receivingChainKey':new Uint8Array(Buffer['from'](a['receivingChainKey'],'base64')),'receivingMessageCount':a['receivingMessageCount'],'ourDHKeyPair':{'publicKey':new Uint8Array(Buffer['from'](a['ourDHPublicKey'],'base64')),'privateKey':new Uint8Array(Buffer['from'](a['ourDHPrivateKey'],'base64'))},'peerDHPublicKey':a['peerDHPublicKey']?new Uint8Array(Buffer['from'](a['peerDHPublicKey'],'base64')):null,'previousSendingCount':a['previousSendingCount'],'skipMessageKeys':b};}
@@ -0,0 +1,39 @@
1
+ import type { X25519KeyPair, Ed25519KeyPair, MLKEMKeyPair, PQPreKeyBundle, PQIdentity, EncryptedMessage, SerializedPQSessionState } from "./types.js";
2
+ export interface PQSessionStore {
3
+ getIdentityKeyPair(): Promise<X25519KeyPair | null>;
4
+ setIdentityKeyPair(keyPair: X25519KeyPair): Promise<void>;
5
+ getEd25519KeyPair(): Promise<Ed25519KeyPair | null>;
6
+ setEd25519KeyPair(keyPair: Ed25519KeyPair): Promise<void>;
7
+ getRegistrationId(): Promise<number | null>;
8
+ setRegistrationId(id: number): Promise<void>;
9
+ getSignedPreKey(keyId: number): Promise<X25519KeyPair | null>;
10
+ setSignedPreKey(keyId: number, keyPair: X25519KeyPair): Promise<void>;
11
+ getSignedPreKeySignature(keyId: number): Promise<Uint8Array | null>;
12
+ setSignedPreKeySignature(keyId: number, sig: Uint8Array): Promise<void>;
13
+ getOneTimePreKey(keyId: number): Promise<X25519KeyPair | null>;
14
+ setOneTimePreKey(keyId: number, keyPair: X25519KeyPair): Promise<void>;
15
+ removeOneTimePreKey(keyId: number): Promise<void>;
16
+ getPQPreKey(keyId: number): Promise<MLKEMKeyPair | null>;
17
+ setPQPreKey(keyId: number, keyPair: MLKEMKeyPair): Promise<void>;
18
+ getPQPreKeySignature(keyId: number): Promise<Uint8Array | null>;
19
+ setPQPreKeySignature(keyId: number, sig: Uint8Array): Promise<void>;
20
+ getSession(peerAddress: string, peerDeviceId: number): Promise<SerializedPQSessionState | null>;
21
+ setSession(peerAddress: string, peerDeviceId: number, state: SerializedPQSessionState): Promise<void>;
22
+ removeSession(peerAddress: string, peerDeviceId: number): Promise<void>;
23
+ getPeerIdentity(peerAddress: string): Promise<Uint8Array | null>;
24
+ setPeerIdentity(peerAddress: string, identityKey: Uint8Array): Promise<void>;
25
+ }
26
+ export declare class PQSessionCipher {
27
+ private store;
28
+ private identity;
29
+ constructor(store: PQSessionStore);
30
+ ensureIdentity(): Promise<PQIdentity>;
31
+ generatePreKeyBundle(signedPreKeyId: number, pqPreKeyId: number, oneTimePreKeyCount: number): Promise<import("./pqxdh.js").GeneratedPreKeyBundle>;
32
+ processPreKeyBundle(peerAddress: string, peerDeviceId: number, bundle: PQPreKeyBundle): Promise<void>;
33
+ processInitialMessage(peerAddress: string, peerDeviceId: number, ephemeralPublicKey: Uint8Array, mlkemCiphertext: Uint8Array, peerIdentityKey: Uint8Array, signedPreKeyId: number, oneTimePreKeyId: number | null, pqPreKeyId: number): Promise<void>;
34
+ encryptMessage(peerAddress: string, plaintext: Uint8Array, peerDeviceId?: number): Promise<EncryptedMessage>;
35
+ decryptMessage(peerAddress: string, messageBody: Uint8Array, peerDeviceId?: number): Promise<Uint8Array>;
36
+ hasSession(peerAddress: string, peerDeviceId?: number): Promise<boolean>;
37
+ private loadSession;
38
+ private saveSession;
39
+ }
@@ -0,0 +1 @@
1
+ import{generateX25519KeyPair,generateEd25519KeyPair,concatBytes,deriveRegistrationId,bytesToBase64,base64ToBytes}from'./crypto.js';import{pqxdhInitiate,pqxdhReceive,generatePreKeyBundle,verifyPreKeyBundle}from'./pqxdh.js';import{initRatchet,ratchetEncrypt,ratchetDecrypt,serializeRatchetState,deserializeRatchetState}from'./ratchet.js';import{initSPQR,spqrGetNextChunk,spqrReceiveChunk,spqrOnPeerPQPKReceived,serializeSPQRState,deserializeSPQRState}from'./spqr.js';import{packChunk,SHARD_SIZE}from'./erasure.js';import{MessageType,DEFAULT_DEVICE_ID,CHAIN_KEY_SIZE,PQError,PQErrorCode}from'./types.js';export class PQSessionCipher{['store'];['identity']=null;constructor(a){this['store']=a;}async['ensureIdentity'](){if(this['identity'])return this['identity'];let a=await this['store']['getIdentityKeyPair'](),b=await this['store']['getEd25519KeyPair'](),c=await this['store']['getRegistrationId']();return(!a||!b||!c)&&(a=generateX25519KeyPair(),b=generateEd25519KeyPair(),c=deriveRegistrationId(a['publicKey']),await this['store']['setIdentityKeyPair'](a),await this['store']['setEd25519KeyPair'](b),await this['store']['setRegistrationId'](c)),this['identity']={'x25519KeyPair':a,'ed25519KeyPair':b,'registrationId':c},this['identity'];}async['generatePreKeyBundle'](a,b,c){const d=await this['ensureIdentity'](),e=generatePreKeyBundle(d['x25519KeyPair'],d['ed25519KeyPair'],a,b,c);await this['store']['setSignedPreKey'](a,e['signedPreKey']['keyPair']),await this['store']['setSignedPreKeySignature'](a,e['signedPreKey']['signature']);for(const f of e['oneTimePreKeys']){await this['store']['setOneTimePreKey'](f['keyId'],f['keyPair']);}return await this['store']['setPQPreKey'](b,e['pqPreKey']['keyPair']),await this['store']['setPQPreKeySignature'](b,e['pqPreKey']['signature']),e;}async['processPreKeyBundle'](a,b,c){const d=await this['ensureIdentity']();if(!verifyPreKeyBundle(c))throw new PQError(PQErrorCode['HANDSHAKE_FAILED'],'PreKey\x20bundle\x20signature\x20verification\x20failed');const e=pqxdhInitiate(d['x25519KeyPair'],d['ed25519KeyPair'],c),f=initRatchet(e['result']['rootKey'],e['result']['chainKey'],new Uint8Array(CHAIN_KEY_SIZE),e['result']['ourDHKeyPair'],e['result']['peerDHPublicKey']),g=initSPQR(),h={'pqxdhComplete':!![],'ratchetState':f,'spqrState':g,'peerIdentityKey':c['identityKey'],'peerRegistrationId':c['registrationId'],'peerDeviceId':b,'pendingInitialMessage':{'ephemeralPublicKey':e['initialMessage']['ephemeralPublicKey'],'mlkemCiphertext':e['initialMessage']['mlkemCiphertext'],'identityKey':e['initialMessage']['identityKey'],'signedPreKeyId':c['signedPreKey']['keyId'],'oneTimePreKeyId':c['oneTimePreKey']?.['keyId']??null,'pqPreKeyId':c['pqPreKey']['keyId']}};await this['store']['setPeerIdentity'](a,c['identityKey']),await this['saveSession'](a,b,h);}async['processInitialMessage'](a,b,c,d,e,f,g,h){const i=await this['ensureIdentity'](),j=await this['store']['getSignedPreKey'](f);if(!j)throw new PQError(PQErrorCode['HANDSHAKE_FAILED'],'Signed\x20pre-key\x20not\x20found');let k=null;g!==null&&(k=await this['store']['getOneTimePreKey'](g),k&&await this['store']['removeOneTimePreKey'](g));const l=await this['store']['getPQPreKey'](h);if(!l)throw new PQError(PQErrorCode['HANDSHAKE_FAILED'],'PQ\x20pre-key\x20not\x20found');const m=pqxdhReceive(i['x25519KeyPair'],j,k,l,c,e,d),n=initRatchet(m['rootKey'],new Uint8Array(CHAIN_KEY_SIZE),m['chainKey'],m['ourDHKeyPair'],m['peerDHPublicKey']),o=initSPQR(),p={'pqxdhComplete':!![],'ratchetState':n,'spqrState':o,'peerIdentityKey':e,'peerRegistrationId':0x0,'peerDeviceId':b};await this['store']['setPeerIdentity'](a,e),await this['saveSession'](a,b,p);}async['encryptMessage'](a,b,c=DEFAULT_DEVICE_ID){const d=await this['loadSession'](a,c);if(!d)throw new PQError(PQErrorCode['SESSION_NOT_FOUND'],'No\x20session\x20established');const {message:e,newState:f}=ratchetEncrypt(d['ratchetState'],b),g=f['sendingMessageCount']+f['previousSendingCount'],{chunk:h,newState:i}=spqrGetNextChunk(d['spqrState'],g);let j;if(h){const l=packChunk(h);j=concatBytes(new Uint8Array([0x1]),e['body'],l);}else j=concatBytes(new Uint8Array([0x0]),e['body']);const k=d['pendingInitialMessage']!==undefined;if(d['pendingInitialMessage']){const m=d['pendingInitialMessage'],n=m['oneTimePreKeyId']??0xffffffff,o=new Uint8Array(0x20+0x440+0x20+0x4+0x4+0x4),p=new DataView(o['buffer']);o['set'](m['ephemeralPublicKey'],0x0),o['set'](m['mlkemCiphertext'],0x20),o['set'](m['identityKey'],0x20+0x440),p['setUint32'](0x20+0x440+0x20,m['signedPreKeyId'],![]),p['setUint32'](0x20+0x440+0x20+0x4,n,![]),p['setUint32'](0x20+0x440+0x20+0x8,m['pqPreKeyId'],![]),j=concatBytes(o,j),d['pendingInitialMessage']=undefined;}return d['ratchetState']=f,d['spqrState']=i,await this['saveSession'](a,c,d),{'type':k?MessageType['PREKEY_MESSAGE']:MessageType['NORMAL_MESSAGE'],'body':j};}async['decryptMessage'](a,b,c=DEFAULT_DEVICE_ID){const d=0x20+0x440+0x20+0x4+0x4+0x4;let e=await this['loadSession'](a,c);if(!e&&b['length']>=d){const m=new DataView(b['buffer'],b['byteOffset'],b['byteLength']),n=b['slice'](0x0,0x20),o=b['slice'](0x20,0x20+0x440),p=b['slice'](0x20+0x440,0x20+0x440+0x20),q=m['getUint32'](0x20+0x440+0x20,![]),r=m['getUint32'](0x20+0x440+0x20+0x4,![]),s=m['getUint32'](0x20+0x440+0x20+0x8,![]),t=r===0xffffffff?null:r;await this['processInitialMessage'](a,c,n,o,p,q,t,s),b=b['slice'](d),e=await this['loadSession'](a,c);}if(!e)throw new PQError(PQErrorCode['SESSION_NOT_FOUND'],'No\x20session\x20established');if(b['length']<0x1)throw new PQError(PQErrorCode['DECRYPTION_FAILED'],'Message\x20body\x20too\x20short');const f=b[0x0]===0x1,g=b['slice'](0x1);let h=null;if(f){if(g['length']<SHARD_SIZE)throw new PQError(PQErrorCode['DECRYPTION_FAILED'],'SPQR\x20chunk\x20missing');h=g['slice'](g['length']-SHARD_SIZE);}const i=f?g['slice'](0x0,g['length']-SHARD_SIZE):g,{plaintext:j,newState:k}=ratchetDecrypt(e['ratchetState'],i);let l=e['spqrState'];if(h){const u=spqrReceiveChunk(l,h);l=u['newState'];if(u['shouldSendCT']&&u['peerPQPK']){const v=spqrOnPeerPQPKReceived(l,u['peerPQPK']);l=v['newState'];}}return e['ratchetState']=k,e['spqrState']=l,await this['saveSession'](a,c,e),j;}async['hasSession'](a,b=DEFAULT_DEVICE_ID){const c=await this['loadSession'](a,b);return c!==null&&c['pqxdhComplete'];}async['loadSession'](a,b){const c=await this['store']['getSession'](a,b);if(!c)return null;const d={'pqxdhComplete':c['pqxdhComplete'],'ratchetState':deserializeRatchetState(c['ratchetState']),'spqrState':deserializeSPQRState(c['spqrState']),'peerIdentityKey':base64ToBytes(c['peerIdentityKey']),'peerRegistrationId':c['peerRegistrationId'],'peerDeviceId':c['peerDeviceId']};return c['pendingInitialMessage']&&(d['pendingInitialMessage']={'ephemeralPublicKey':base64ToBytes(c['pendingInitialMessage']['ephemeralPublicKey']),'mlkemCiphertext':base64ToBytes(c['pendingInitialMessage']['mlkemCiphertext']),'identityKey':base64ToBytes(c['pendingInitialMessage']['identityKey']),'signedPreKeyId':c['pendingInitialMessage']['signedPreKeyId'],'oneTimePreKeyId':c['pendingInitialMessage']['oneTimePreKeyId'],'pqPreKeyId':c['pendingInitialMessage']['pqPreKeyId']}),d;}async['saveSession'](a,b,c){const d={'pqxdhComplete':c['pqxdhComplete'],'ratchetState':serializeRatchetState(c['ratchetState']),'spqrState':serializeSPQRState(c['spqrState']),'peerIdentityKey':bytesToBase64(c['peerIdentityKey']),'peerRegistrationId':c['peerRegistrationId'],'peerDeviceId':c['peerDeviceId']};c['pendingInitialMessage']&&(d['pendingInitialMessage']={'ephemeralPublicKey':bytesToBase64(c['pendingInitialMessage']['ephemeralPublicKey']),'mlkemCiphertext':bytesToBase64(c['pendingInitialMessage']['mlkemCiphertext']),'identityKey':bytesToBase64(c['pendingInitialMessage']['identityKey']),'signedPreKeyId':c['pendingInitialMessage']['signedPreKeyId'],'oneTimePreKeyId':c['pendingInitialMessage']['oneTimePreKeyId'],'pqPreKeyId':c['pendingInitialMessage']['pqPreKeyId']}),await this['store']['setSession'](a,b,d);}}
@@ -0,0 +1,23 @@
1
+ import type { SPQRState, SPQRChunk, SerializedSPQRState } from "./types.js";
2
+ export declare function initSPQR(): SPQRState;
3
+ export declare function spqrGetNextChunk(state: SPQRState, messageCount: number): {
4
+ chunk: SPQRChunk | null;
5
+ newState: SPQRState;
6
+ };
7
+ export declare function spqrProcessReceivedChunks(state: SPQRState, chunks: SPQRChunk[]): {
8
+ newState: SPQRState;
9
+ completed: boolean;
10
+ };
11
+ export declare function spqrOnPeerPQPKReceived(state: SPQRState, peerPQPK: Uint8Array): {
12
+ newState: SPQRState;
13
+ ctChunks: Uint8Array[];
14
+ };
15
+ export declare function spqrReceiveChunk(state: SPQRState, packedChunk: Uint8Array): {
16
+ newState: SPQRState;
17
+ peerPQPKReady: boolean;
18
+ peerPQPK: Uint8Array | null;
19
+ shouldSendCT: boolean;
20
+ };
21
+ export declare function spqrGetCurrentKey(state: SPQRState): Uint8Array;
22
+ export declare function serializeSPQRState(state: SPQRState): SerializedSPQRState;
23
+ export declare function deserializeSPQRState(serialized: SerializedSPQRState): SPQRState;
@@ -0,0 +1 @@
1
+ import{generateMLKEMKeyPair,mlkemEncapsulate,mlkemDecapsulate,hkdfDerive,concatBytes}from'./crypto.js';import{encodeShards,decodeShards,unpackChunk,DATA_SHARDS}from'./erasure.js';import{CHAIN_KEY_SIZE,MESSAGE_KEY_SIZE,MLKEM_PUBLIC_KEY_SIZE,MLKEM_CIPHERTEXT_SIZE}from'./types.js';const SPQR_CYCLE_INTERVAL=0x32;export function initSPQR(){return{'cycleId':0x0,'sendingPQKeys':null,'sendingChunks':[],'sendingChunkIndex':0x0,'sendingPhase':'idle','receivedChunks':new Map(),'receivingPhase':'idle','expectedTotalChunks':0x0,'receivedSharedSecret':null,'currentSPQRKey':new Uint8Array(MESSAGE_KEY_SIZE),'spqrChainKey':new Uint8Array(CHAIN_KEY_SIZE),'spqrMessageCount':0x0};}export function spqrGetNextChunk(a,b){const c=cloneSPQRState(a);if(c['sendingPhase']==='idle'&&b>0x0&&b%SPQR_CYCLE_INTERVAL===0x0){c['cycleId']+=0x1,c['sendingPQKeys']=generateMLKEMKeyPair(),c['sendingPhase']='sending_pk';const f=encodeShards(c['sendingPQKeys']['publicKey']);c['sendingChunks']=f,c['sendingChunkIndex']=0x0;}if(c['sendingPhase']==='idle')return{'chunk':null,'newState':c};if(c['sendingChunkIndex']>=c['sendingChunks']['length']){if(c['sendingPhase']==='sending_pk')c['sendingPhase']='sending_ct_no_pk',c['sendingChunkIndex']=0x0,c['sendingChunks']=[];else{if(c['sendingPhase']==='sending_ct_no_pk'||c['sendingPhase']==='sending_ct_pk')return c['sendingPhase']='idle',c['sendingPQKeys']=null,c['sendingChunks']=[],c['sendingChunkIndex']=0x0,{'chunk':null,'newState':c};}}if((c['sendingPhase']==='sending_ct_no_pk'||c['sendingPhase']==='sending_ct_pk')&&c['sendingChunks']['length']===0x0)return{'chunk':null,'newState':c};const d=c['sendingChunks'][c['sendingChunkIndex']],e={'cycleId':c['cycleId'],'chunkIndex':c['sendingChunkIndex'],'totalChunks':c['sendingChunks']['length'],'data':d};return c['sendingChunkIndex']+=0x1,{'chunk':e,'newState':c};}export function spqrProcessReceivedChunks(a,b){const c=cloneSPQRState(a);for(const d of b){c['receivingPhase']==='idle'&&(c['receivingPhase']='receiving_ct',c['expectedTotalChunks']=d['totalChunks'],c['receivedChunks']=new Map());if(d['cycleId']!==c['cycleId'])continue;c['receivedChunks']['set'](d['chunkIndex'],d['data']);}if(c['receivingPhase']==='receiving_ct'&&c['receivedChunks']['size']>=DATA_SHARDS){const e=decodeShards(c['receivedChunks'],c['expectedTotalChunks']),f=e['slice'](0x0,MLKEM_CIPHERTEXT_SIZE);if(c['sendingPQKeys']){const g=mlkemDecapsulate(f,c['sendingPQKeys']['secretKey']);return c['receivedSharedSecret']=g,c['currentSPQRKey']=hkdfDerive(concatBytes(c['currentSPQRKey'],g),new TextEncoder()['encode']('WowokSPQRUpdate'),MESSAGE_KEY_SIZE),c['receivingPhase']='done',c['receivedChunks']=new Map(),{'newState':c,'completed':!![]};}}return{'newState':c,'completed':![]};}export function spqrOnPeerPQPKReceived(a,b){const c=cloneSPQRState(a),{ciphertext:d,sharedSecret:e}=mlkemEncapsulate(b);c['currentSPQRKey']=hkdfDerive(concatBytes(c['currentSPQRKey'],e),new TextEncoder()['encode']('WowokSPQRUpdate'),MESSAGE_KEY_SIZE);const f=encodeShards(d);return c['sendingChunks']=f,c['sendingChunkIndex']=0x0,c['sendingPhase']='sending_ct_pk',{'newState':c,'ctChunks':f};}export function spqrReceiveChunk(a,b){const c=cloneSPQRState(a),d=unpackChunk(b);c['receivingPhase']==='idle'&&(c['receivingPhase']='receiving_pk',c['expectedTotalChunks']=d['totalChunks'],c['receivedChunks']=new Map(),c['cycleId']=d['cycleId']);if(d['cycleId']!==c['cycleId'])return{'newState':c,'peerPQPKReady':![],'peerPQPK':null,'shouldSendCT':![]};c['receivedChunks']['set'](d['chunkIndex'],d['data']);if(c['receivingPhase']==='receiving_pk'&&c['receivedChunks']['size']>=DATA_SHARDS){const e=decodeShards(c['receivedChunks'],c['expectedTotalChunks']),f=e['slice'](0x0,MLKEM_PUBLIC_KEY_SIZE);return c['receivingPhase']='receiving_ct',c['receivedChunks']=new Map(),{'newState':c,'peerPQPKReady':!![],'peerPQPK':f,'shouldSendCT':!![]};}if(c['receivingPhase']==='receiving_ct'&&c['receivedChunks']['size']>=DATA_SHARDS){const g=decodeShards(c['receivedChunks'],c['expectedTotalChunks']),h=g['slice'](0x0,MLKEM_CIPHERTEXT_SIZE);if(c['sendingPQKeys']){const i=mlkemDecapsulate(h,c['sendingPQKeys']['secretKey']);c['currentSPQRKey']=hkdfDerive(concatBytes(c['currentSPQRKey'],i),new TextEncoder()['encode']('WowokSPQRUpdate'),MESSAGE_KEY_SIZE),c['receivingPhase']='done',c['receivedChunks']=new Map(),c['sendingPQKeys']=null;}return{'newState':c,'peerPQPKReady':![],'peerPQPK':null,'shouldSendCT':![]};}return{'newState':c,'peerPQPKReady':![],'peerPQPK':null,'shouldSendCT':![]};}export function spqrGetCurrentKey(a){return a['currentSPQRKey'];}function cloneSPQRState(a){return{'cycleId':a['cycleId'],'sendingPQKeys':a['sendingPQKeys']?{'publicKey':new Uint8Array(a['sendingPQKeys']['publicKey']),'secretKey':new Uint8Array(a['sendingPQKeys']['secretKey'])}:null,'sendingChunks':a['sendingChunks']['map'](b=>new Uint8Array(b)),'sendingChunkIndex':a['sendingChunkIndex'],'sendingPhase':a['sendingPhase'],'receivedChunks':new Map(a['receivedChunks']),'receivingPhase':a['receivingPhase'],'expectedTotalChunks':a['expectedTotalChunks'],'receivedSharedSecret':a['receivedSharedSecret']?new Uint8Array(a['receivedSharedSecret']):null,'currentSPQRKey':new Uint8Array(a['currentSPQRKey']),'spqrChainKey':new Uint8Array(a['spqrChainKey']),'spqrMessageCount':a['spqrMessageCount']};}export function serializeSPQRState(a){const b={};for(const [c,d]of a['receivedChunks']){b[c['toString']()]=Buffer['from'](d)['toString']('base64');}return{'cycleId':a['cycleId'],'sendingPQPublicKey':a['sendingPQKeys']?Buffer['from'](a['sendingPQKeys']['publicKey'])['toString']('base64'):null,'sendingPQSecretKey':a['sendingPQKeys']?Buffer['from'](a['sendingPQKeys']['secretKey'])['toString']('base64'):null,'sendingChunks':a['sendingChunks']['map'](e=>Buffer['from'](e)['toString']('base64')),'sendingChunkIndex':a['sendingChunkIndex'],'sendingPhase':a['sendingPhase'],'receivedChunks':b,'receivingPhase':a['receivingPhase'],'expectedTotalChunks':a['expectedTotalChunks'],'receivedSharedSecret':a['receivedSharedSecret']?Buffer['from'](a['receivedSharedSecret'])['toString']('base64'):null,'currentSPQRKey':Buffer['from'](a['currentSPQRKey'])['toString']('base64'),'spqrChainKey':Buffer['from'](a['spqrChainKey'])['toString']('base64'),'spqrMessageCount':a['spqrMessageCount']};}export function deserializeSPQRState(a){const b=new Map();for(const [c,d]of Object['entries'](a['receivedChunks'])){b['set'](parseInt(c),new Uint8Array(Buffer['from'](d,'base64')));}return{'cycleId':a['cycleId'],'sendingPQKeys':a['sendingPQPublicKey']&&a['sendingPQSecretKey']?{'publicKey':new Uint8Array(Buffer['from'](a['sendingPQPublicKey'],'base64')),'secretKey':new Uint8Array(Buffer['from'](a['sendingPQSecretKey'],'base64'))}:null,'sendingChunks':a['sendingChunks']['map'](e=>new Uint8Array(Buffer['from'](e,'base64'))),'sendingChunkIndex':a['sendingChunkIndex'],'sendingPhase':a['sendingPhase'],'receivedChunks':b,'receivingPhase':a['receivingPhase'],'expectedTotalChunks':a['expectedTotalChunks'],'receivedSharedSecret':a['receivedSharedSecret']?new Uint8Array(Buffer['from'](a['receivedSharedSecret'],'base64')):null,'currentSPQRKey':new Uint8Array(Buffer['from'](a['currentSPQRKey'],'base64')),'spqrChainKey':new Uint8Array(Buffer['from'](a['spqrChainKey'],'base64')),'spqrMessageCount':a['spqrMessageCount']};}
@@ -0,0 +1,33 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { X25519KeyPair, Ed25519KeyPair, MLKEMKeyPair, SerializedPQSessionState } from "./types.js";
3
+ import type { PQSessionStore } from "./session.js";
4
+ export declare class PQSessionStoreAdapter implements PQSessionStore {
5
+ private db;
6
+ private userAddress;
7
+ constructor(db: Database.Database, userAddress: string);
8
+ private getValue;
9
+ private putValue;
10
+ private delValue;
11
+ getIdentityKeyPair(): Promise<X25519KeyPair | null>;
12
+ setIdentityKeyPair(keyPair: X25519KeyPair): Promise<void>;
13
+ getEd25519KeyPair(): Promise<Ed25519KeyPair | null>;
14
+ setEd25519KeyPair(keyPair: Ed25519KeyPair): Promise<void>;
15
+ getRegistrationId(): Promise<number | null>;
16
+ setRegistrationId(id: number): Promise<void>;
17
+ getSignedPreKey(keyId: number): Promise<X25519KeyPair | null>;
18
+ setSignedPreKey(keyId: number, keyPair: X25519KeyPair): Promise<void>;
19
+ getSignedPreKeySignature(keyId: number): Promise<Uint8Array | null>;
20
+ setSignedPreKeySignature(keyId: number, sig: Uint8Array): Promise<void>;
21
+ getOneTimePreKey(keyId: number): Promise<X25519KeyPair | null>;
22
+ setOneTimePreKey(keyId: number, keyPair: X25519KeyPair): Promise<void>;
23
+ removeOneTimePreKey(keyId: number): Promise<void>;
24
+ getPQPreKey(keyId: number): Promise<MLKEMKeyPair | null>;
25
+ setPQPreKey(keyId: number, keyPair: MLKEMKeyPair): Promise<void>;
26
+ getPQPreKeySignature(keyId: number): Promise<Uint8Array | null>;
27
+ setPQPreKeySignature(keyId: number, sig: Uint8Array): Promise<void>;
28
+ getSession(peerAddress: string, peerDeviceId: number): Promise<SerializedPQSessionState | null>;
29
+ setSession(peerAddress: string, peerDeviceId: number, state: SerializedPQSessionState): Promise<void>;
30
+ removeSession(peerAddress: string, peerDeviceId: number): Promise<void>;
31
+ getPeerIdentity(peerAddress: string): Promise<Uint8Array | null>;
32
+ setPeerIdentity(peerAddress: string, identityKey: Uint8Array): Promise<void>;
33
+ }
@@ -0,0 +1 @@
1
+ const PQ_STORE_PREFIX='pq';function arrayBufferToBase64(a){return Buffer['from'](a)['toString']('base64');}function base64ToUint8Array(a){return new Uint8Array(Buffer['from'](a,'base64'));}export class PQSessionStoreAdapter{['db'];['userAddress'];constructor(a,b){this['db']=a,this['userAddress']=b;}['getValue'](a){const b=this['db']['prepare']('SELECT\x20value\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['get'](PQ_STORE_PREFIX,a);return b?.['value'];}['putValue'](a,b){this['db']['prepare']('INSERT\x20INTO\x20signal_store\x20(store_type,\x20key,\x20value,\x20updated_at)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20(?,\x20?,\x20?,\x20strftime(\x27%s\x27,\x20\x27now\x27))\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT(store_type,\x20key)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20value\x20=\x20excluded.value,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at\x20=\x20excluded.updated_at')['run'](PQ_STORE_PREFIX,a,b);}['delValue'](a){this['db']['prepare']('DELETE\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['run'](PQ_STORE_PREFIX,a);}async['getIdentityKeyPair'](){const a=this['getValue']('identity_x25519');if(!a)return null;const b=JSON['parse'](a);return{'publicKey':base64ToUint8Array(b['pubKey']),'privateKey':base64ToUint8Array(b['privKey'])};}async['setIdentityKeyPair'](a){const b={'pubKey':arrayBufferToBase64(a['publicKey']),'privKey':arrayBufferToBase64(a['privateKey'])};this['putValue']('identity_x25519',JSON['stringify'](b));}async['getEd25519KeyPair'](){const a=this['getValue']('identity_ed25519');if(!a)return null;const b=JSON['parse'](a);return{'publicKey':base64ToUint8Array(b['pubKey']),'privateKey':base64ToUint8Array(b['privKey'])};}async['setEd25519KeyPair'](a){const b={'pubKey':arrayBufferToBase64(a['publicKey']),'privKey':arrayBufferToBase64(a['privateKey'])};this['putValue']('identity_ed25519',JSON['stringify'](b));}async['getRegistrationId'](){const a=this['getValue']('registration_id');return a?parseInt(a,0xa):null;}async['setRegistrationId'](a){this['putValue']('registration_id',a['toString']());}async['getSignedPreKey'](a){const b=this['getValue']('signed_prekey:'+a);if(!b)return null;const c=JSON['parse'](b);return{'publicKey':base64ToUint8Array(c['pubKey']),'privateKey':base64ToUint8Array(c['privKey'])};}async['setSignedPreKey'](a,b){const c={'pubKey':arrayBufferToBase64(b['publicKey']),'privKey':arrayBufferToBase64(b['privateKey'])};this['putValue']('signed_prekey:'+a,JSON['stringify'](c));}async['getSignedPreKeySignature'](a){const b=this['getValue']('signed_prekey_sig:'+a);return b?base64ToUint8Array(b):null;}async['setSignedPreKeySignature'](a,b){this['putValue']('signed_prekey_sig:'+a,arrayBufferToBase64(b));}async['getOneTimePreKey'](a){const b=this['getValue']('onetime_prekey:'+a);if(!b)return null;const c=JSON['parse'](b);return{'publicKey':base64ToUint8Array(c['pubKey']),'privateKey':base64ToUint8Array(c['privKey'])};}async['setOneTimePreKey'](a,b){const c={'pubKey':arrayBufferToBase64(b['publicKey']),'privKey':arrayBufferToBase64(b['privateKey'])};this['putValue']('onetime_prekey:'+a,JSON['stringify'](c));}async['removeOneTimePreKey'](a){this['delValue']('onetime_prekey:'+a);}async['getPQPreKey'](a){const b=this['getValue']('pq_prekey:'+a);if(!b)return null;const c=JSON['parse'](b);return{'publicKey':base64ToUint8Array(c['pubKey']),'secretKey':base64ToUint8Array(c['secKey'])};}async['setPQPreKey'](a,b){const c={'pubKey':arrayBufferToBase64(b['publicKey']),'secKey':arrayBufferToBase64(b['secretKey'])};this['putValue']('pq_prekey:'+a,JSON['stringify'](c));}async['getPQPreKeySignature'](a){const b=this['getValue']('pq_prekey_sig:'+a);return b?base64ToUint8Array(b):null;}async['setPQPreKeySignature'](a,b){this['putValue']('pq_prekey_sig:'+a,arrayBufferToBase64(b));}async['getSession'](a,b){const c='session:'+a+'.'+b,d=this['getValue'](c);if(!d)return null;return JSON['parse'](d);}async['setSession'](a,b,c){const d='session:'+a+'.'+b;this['putValue'](d,JSON['stringify'](c));}async['removeSession'](a,b){const c='session:'+a+'.'+b;this['delValue'](c);}async['getPeerIdentity'](a){const b=this['getValue']('peer_identity:'+a);return b?base64ToUint8Array(b):null;}async['setPeerIdentity'](a,b){this['putValue']('peer_identity:'+a,arrayBufferToBase64(b));}}
@@ -0,0 +1,181 @@
1
+ export interface KeyPair {
2
+ publicKey: Uint8Array;
3
+ secretKey: Uint8Array;
4
+ }
5
+ export interface X25519KeyPair {
6
+ publicKey: Uint8Array;
7
+ privateKey: Uint8Array;
8
+ }
9
+ export interface Ed25519KeyPair {
10
+ publicKey: Uint8Array;
11
+ privateKey: Uint8Array;
12
+ }
13
+ export interface MLKEMKeyPair {
14
+ publicKey: Uint8Array;
15
+ secretKey: Uint8Array;
16
+ }
17
+ export interface PQPreKeyBundle {
18
+ registrationId: number;
19
+ deviceId: number;
20
+ identityKey: Uint8Array;
21
+ ed25519PublicKey: Uint8Array;
22
+ signedPreKey: {
23
+ keyId: number;
24
+ publicKey: Uint8Array;
25
+ signature: Uint8Array;
26
+ };
27
+ oneTimePreKey?: {
28
+ keyId: number;
29
+ publicKey: Uint8Array;
30
+ };
31
+ pqPreKey: {
32
+ keyId: number;
33
+ publicKey: Uint8Array;
34
+ signature: Uint8Array;
35
+ };
36
+ }
37
+ export interface PQXDHResult {
38
+ rootKey: Uint8Array;
39
+ chainKey: Uint8Array;
40
+ ourDHKeyPair: X25519KeyPair;
41
+ peerDHPublicKey: Uint8Array;
42
+ peerIdentityKey: Uint8Array;
43
+ pqSharedSecret: Uint8Array;
44
+ }
45
+ export interface RatchetState {
46
+ rootKey: Uint8Array;
47
+ sendingChainKey: Uint8Array;
48
+ sendingMessageCount: number;
49
+ receivingChainKey: Uint8Array;
50
+ receivingMessageCount: number;
51
+ ourDHKeyPair: X25519KeyPair;
52
+ peerDHPublicKey: Uint8Array | null;
53
+ previousSendingCount: number;
54
+ skipMessageKeys: Map<string, Uint8Array>;
55
+ }
56
+ export interface EncryptedMessage {
57
+ type: MessageType;
58
+ body: Uint8Array;
59
+ registrationId?: number;
60
+ }
61
+ export declare enum MessageType {
62
+ PREKEY_MESSAGE = 3,
63
+ NORMAL_MESSAGE = 1
64
+ }
65
+ export type SPQRPhase = "idle" | "sending_pk" | "sending_ct_no_pk" | "sending_ct_pk" | "done";
66
+ export type SPQRReceivePhase = "idle" | "receiving_pk" | "receiving_ct" | "done";
67
+ export interface SPQRState {
68
+ cycleId: number;
69
+ sendingPQKeys: MLKEMKeyPair | null;
70
+ sendingChunks: Uint8Array[];
71
+ sendingChunkIndex: number;
72
+ sendingPhase: SPQRPhase;
73
+ receivedChunks: Map<number, Uint8Array>;
74
+ receivingPhase: SPQRReceivePhase;
75
+ expectedTotalChunks: number;
76
+ receivedSharedSecret: Uint8Array | null;
77
+ currentSPQRKey: Uint8Array;
78
+ spqrChainKey: Uint8Array;
79
+ spqrMessageCount: number;
80
+ }
81
+ export interface SPQRChunk {
82
+ cycleId: number;
83
+ chunkIndex: number;
84
+ totalChunks: number;
85
+ data: Uint8Array;
86
+ }
87
+ export interface PQSessionState {
88
+ pqxdhComplete: boolean;
89
+ ratchetState: RatchetState;
90
+ spqrState: SPQRState;
91
+ peerIdentityKey: Uint8Array;
92
+ peerRegistrationId: number;
93
+ peerDeviceId: number;
94
+ pendingInitialMessage?: {
95
+ ephemeralPublicKey: Uint8Array;
96
+ mlkemCiphertext: Uint8Array;
97
+ identityKey: Uint8Array;
98
+ signedPreKeyId: number;
99
+ oneTimePreKeyId: number | null;
100
+ pqPreKeyId: number;
101
+ };
102
+ }
103
+ export interface PQIdentity {
104
+ x25519KeyPair: X25519KeyPair;
105
+ ed25519KeyPair: Ed25519KeyPair;
106
+ registrationId: number;
107
+ }
108
+ export interface SerializedRatchetState {
109
+ rootKey: string;
110
+ sendingChainKey: string;
111
+ sendingMessageCount: number;
112
+ receivingChainKey: string;
113
+ receivingMessageCount: number;
114
+ ourDHPrivateKey: string;
115
+ ourDHPublicKey: string;
116
+ peerDHPublicKey: string | null;
117
+ previousSendingCount: number;
118
+ skipMessageKeys: Record<string, string>;
119
+ }
120
+ export interface SerializedSPQRState {
121
+ cycleId: number;
122
+ sendingPQPublicKey: string | null;
123
+ sendingPQSecretKey: string | null;
124
+ sendingChunks: string[];
125
+ sendingChunkIndex: number;
126
+ sendingPhase: string;
127
+ receivedChunks: Record<string, string>;
128
+ receivingPhase: string;
129
+ expectedTotalChunks: number;
130
+ receivedSharedSecret: string | null;
131
+ currentSPQRKey: string;
132
+ spqrChainKey: string;
133
+ spqrMessageCount: number;
134
+ }
135
+ export interface SerializedPQSessionState {
136
+ pqxdhComplete: boolean;
137
+ ratchetState: SerializedRatchetState;
138
+ spqrState: SerializedSPQRState;
139
+ peerIdentityKey: string;
140
+ peerRegistrationId: number;
141
+ peerDeviceId: number;
142
+ pendingInitialMessage?: {
143
+ ephemeralPublicKey: string;
144
+ mlkemCiphertext: string;
145
+ identityKey: string;
146
+ signedPreKeyId: number;
147
+ oneTimePreKeyId: number | null;
148
+ pqPreKeyId: number;
149
+ };
150
+ }
151
+ export declare enum PQErrorCode {
152
+ INVALID_KEY = "INVALID_KEY",
153
+ HANDSHAKE_FAILED = "HANDSHAKE_FAILED",
154
+ ENCRYPTION_FAILED = "ENCRYPTION_FAILED",
155
+ DECRYPTION_FAILED = "DECRYPTION_FAILED",
156
+ SESSION_NOT_FOUND = "SESSION_NOT_FOUND",
157
+ SPQR_ERROR = "SPQR_ERROR",
158
+ ERASURE_ERROR = "ERASURE_ERROR",
159
+ SERIALIZATION_ERROR = "SERIALIZATION_ERROR"
160
+ }
161
+ export declare class PQError extends Error {
162
+ code: PQErrorCode;
163
+ constructor(code: PQErrorCode, message: string);
164
+ }
165
+ export declare const DEFAULT_DEVICE_ID = 1;
166
+ export declare const ROOT_KEY_SIZE = 32;
167
+ export declare const CHAIN_KEY_SIZE = 32;
168
+ export declare const MESSAGE_KEY_SIZE = 32;
169
+ export declare const DH_KEY_SIZE = 32;
170
+ export declare const SIGNATURE_SIZE = 64;
171
+ export declare const MLKEM_PUBLIC_KEY_SIZE = 1184;
172
+ export declare const MLKEM_SECRET_KEY_SIZE = 2400;
173
+ export declare const MLKEM_CIPHERTEXT_SIZE = 1088;
174
+ export declare const MLKEM_SHARED_SECRET_SIZE = 32;
175
+ export declare const AES_GCM_IV_SIZE = 12;
176
+ export declare const AES_GCM_TAG_SIZE = 16;
177
+ export declare const SPQR_CHUNK_DATA_SIZE = 34;
178
+ export declare const SPQR_CHUNK_HEADER_SIZE = 8;
179
+ export declare const SPQR_CHUNK_SIZE: number;
180
+ export declare const SPQR_DATA_CHUNKS = 28;
181
+ export declare const SPQR_TOTAL_CHUNKS = 56;
@@ -0,0 +1 @@
1
+ export var MessageType;(function(a){a[a['PREKEY_MESSAGE']=0x3]='PREKEY_MESSAGE',a[a['NORMAL_MESSAGE']=0x1]='NORMAL_MESSAGE';}(MessageType||(MessageType={})));export var PQErrorCode;(function(a){a['INVALID_KEY']='INVALID_KEY',a['HANDSHAKE_FAILED']='HANDSHAKE_FAILED',a['ENCRYPTION_FAILED']='ENCRYPTION_FAILED',a['DECRYPTION_FAILED']='DECRYPTION_FAILED',a['SESSION_NOT_FOUND']='SESSION_NOT_FOUND',a['SPQR_ERROR']='SPQR_ERROR',a['ERASURE_ERROR']='ERASURE_ERROR',a['SERIALIZATION_ERROR']='SERIALIZATION_ERROR';}(PQErrorCode||(PQErrorCode={})));export class PQError extends Error{['code'];constructor(a,b){super(b),this['code']=a,this['name']='PQError';}}export const DEFAULT_DEVICE_ID=0x1;export const ROOT_KEY_SIZE=0x20;export const CHAIN_KEY_SIZE=0x20;export const MESSAGE_KEY_SIZE=0x20;export const DH_KEY_SIZE=0x20;export const SIGNATURE_SIZE=0x40;export const MLKEM_PUBLIC_KEY_SIZE=0x4a0;export const MLKEM_SECRET_KEY_SIZE=0x960;export const MLKEM_CIPHERTEXT_SIZE=0x440;export const MLKEM_SHARED_SECRET_SIZE=0x20;export const AES_GCM_IV_SIZE=0xc;export const AES_GCM_TAG_SIZE=0x10;export const SPQR_CHUNK_DATA_SIZE=0x22;export const SPQR_CHUNK_HEADER_SIZE=0x8;export const SPQR_CHUNK_SIZE=SPQR_CHUNK_DATA_SIZE+SPQR_CHUNK_HEADER_SIZE;export const SPQR_DATA_CHUNKS=0x1c;export const SPQR_TOTAL_CHUNKS=0x38;
@@ -1,12 +1,11 @@
1
- import { SignalProtocolStorage } from "./storage.js";
1
+ import { PQSessionCipher } from "./pq/index.js";
2
+ import type { PQSessionStore } from "./pq/session.js";
2
3
  import type { Xed25519KeyPair, MessengerConfig, RemoteBundle } from "./types.js";
3
- type KeyPairType = {
4
- pubKey: ArrayBuffer;
5
- privKey: ArrayBuffer;
6
- };
4
+ import type { X25519KeyPair, Ed25519KeyPair } from "./pq/types.js";
7
5
  export interface LocalIdentity {
8
6
  xed25519: Xed25519KeyPair;
9
- signalIdentity: KeyPairType;
7
+ x25519KeyPair: X25519KeyPair;
8
+ ed25519KeyPair: Ed25519KeyPair;
10
9
  registrationId: number;
11
10
  }
12
11
  export interface EncryptedMessage {
@@ -15,11 +14,14 @@ export interface EncryptedMessage {
15
14
  registrationId?: number;
16
15
  }
17
16
  export declare class MessengerSession {
18
- private store;
17
+ private pqStore;
18
+ private pqCipher;
19
19
  private serverClient;
20
20
  private config;
21
21
  private identity;
22
22
  constructor(userAddress: string, config?: Partial<MessengerConfig>);
23
+ get store(): PQSessionStore;
24
+ get cipher(): PQSessionCipher;
23
25
  ensureIdentity(userAddress?: string): Promise<LocalIdentity>;
24
26
  private deriveRegistrationId;
25
27
  registerDevice(userAddress: string): Promise<void>;
@@ -40,10 +42,10 @@ export interface SessionSnapshot {
40
42
  }
41
43
  export declare class SessionStateManager {
42
44
  private store;
43
- constructor(store: SignalProtocolStorage);
44
- snapshotSession(sessionKey: string): Promise<SessionSnapshot>;
45
- rollbackSession(sessionKey: string, snapshot: SessionSnapshot): Promise<void>;
46
- commitSession(_sessionKey: string): Promise<void>;
45
+ constructor(store: PQSessionStore);
46
+ snapshotSession(peerAddress: string, peerDeviceId: number): Promise<SessionSnapshot>;
47
+ rollbackSession(peerAddress: string, peerDeviceId: number, snapshot: SessionSnapshot): Promise<void>;
48
+ commitSession(_peerAddress: string, _peerDeviceId: number): Promise<void>;
47
49
  }
48
50
  export interface DecryptResult {
49
51
  success: boolean;
@@ -56,12 +58,9 @@ export interface DecryptResult {
56
58
  export declare class DecryptionEngine {
57
59
  private sessionManager;
58
60
  private store;
59
- constructor(store: SignalProtocolStorage);
60
- private getRecvSessionKey;
61
- private getSendSessionKey;
61
+ private cipher;
62
+ constructor(store: PQSessionStore);
62
63
  decryptMessage(myAddress: string, peerAddress: string, ciphertext: ArrayBuffer, msgType: number, peerDeviceId?: number): Promise<DecryptResult>;
63
64
  private handlePreKeyMessage;
64
65
  private handleWhisperMessage;
65
- private arrayBufferToBinary;
66
66
  }
67
- export {};