@tinyhumansai/tinyplace 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/a2a.d.ts +28 -0
- package/dist/api/a2a.js +21 -0
- package/dist/api/admin.d.ts +38 -0
- package/dist/api/admin.js +49 -0
- package/dist/api/broadcasts.d.ts +32 -0
- package/dist/api/broadcasts.js +51 -0
- package/dist/api/channels.d.ts +43 -0
- package/dist/api/channels.js +57 -0
- package/dist/api/directory.d.ts +15 -0
- package/dist/api/directory.js +26 -0
- package/dist/api/escrow.d.ts +47 -0
- package/dist/api/escrow.js +76 -0
- package/dist/api/events.d.ts +45 -0
- package/dist/api/events.js +77 -0
- package/dist/api/explorer.d.ts +19 -0
- package/dist/api/explorer.js +21 -0
- package/dist/api/groups.d.ts +19 -0
- package/dist/api/groups.js +32 -0
- package/dist/api/inbox.d.ts +27 -0
- package/dist/api/inbox.js +48 -0
- package/dist/api/keys.d.ts +9 -0
- package/dist/api/keys.js +14 -0
- package/dist/api/ledger.d.ts +11 -0
- package/dist/api/ledger.js +14 -0
- package/dist/api/marketplace.d.ts +53 -0
- package/dist/api/marketplace.js +81 -0
- package/dist/api/messages.d.ts +11 -0
- package/dist/api/messages.js +17 -0
- package/dist/api/moderation.d.ts +30 -0
- package/dist/api/moderation.js +32 -0
- package/dist/api/payments.d.ts +15 -0
- package/dist/api/payments.js +26 -0
- package/dist/api/pricing.d.ts +69 -0
- package/dist/api/pricing.js +60 -0
- package/dist/api/profiles.d.ts +18 -0
- package/dist/api/profiles.js +23 -0
- package/dist/api/registry.d.ts +26 -0
- package/dist/api/registry.js +87 -0
- package/dist/api/reputation.d.ts +24 -0
- package/dist/api/reputation.js +29 -0
- package/dist/api/search.d.ts +46 -0
- package/dist/api/search.js +41 -0
- package/dist/api/stats.d.ts +11 -0
- package/dist/api/stats.js +20 -0
- package/dist/auth.d.ts +16 -0
- package/dist/auth.js +36 -0
- package/dist/client.d.ts +63 -0
- package/dist/client.js +73 -0
- package/dist/crypto.d.ts +12 -0
- package/dist/crypto.js +49 -0
- package/dist/http.d.ts +30 -0
- package/dist/http.js +101 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +32 -0
- package/dist/local-signer.d.ts +15 -0
- package/dist/local-signer.js +51 -0
- package/dist/signal/crypto.d.ts +29 -0
- package/dist/signal/crypto.js +156 -0
- package/dist/signal/index.d.ts +11 -0
- package/dist/signal/index.js +6 -0
- package/dist/signal/keys.d.ts +14 -0
- package/dist/signal/keys.js +36 -0
- package/dist/signal/memory-store.d.ts +21 -0
- package/dist/signal/memory-store.js +50 -0
- package/dist/signal/ratchet.d.ts +12 -0
- package/dist/signal/ratchet.js +106 -0
- package/dist/signal/session.d.ts +17 -0
- package/dist/signal/session.js +117 -0
- package/dist/signal/store.d.ts +36 -0
- package/dist/signal/store.js +6 -0
- package/dist/signal/x3dh.d.ts +18 -0
- package/dist/signal/x3dh.js +86 -0
- package/dist/signer.d.ts +13 -0
- package/dist/signer.js +9 -0
- package/dist/types/broadcasts.d.ts +74 -0
- package/dist/types/broadcasts.js +1 -0
- package/dist/types/commerce.d.ts +183 -0
- package/dist/types/commerce.js +1 -0
- package/dist/types/directory.d.ts +88 -0
- package/dist/types/directory.js +1 -0
- package/dist/types/escrow.d.ts +129 -0
- package/dist/types/escrow.js +1 -0
- package/dist/types/events.d.ts +137 -0
- package/dist/types/events.js +1 -0
- package/dist/types/explorer.d.ts +133 -0
- package/dist/types/explorer.js +1 -0
- package/dist/types/groups.d.ts +56 -0
- package/dist/types/groups.js +1 -0
- package/dist/types/identity.d.ts +94 -0
- package/dist/types/identity.js +1 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.js +16 -0
- package/dist/types/ledger.d.ts +57 -0
- package/dist/types/ledger.js +1 -0
- package/dist/types/marketplace.d.ts +141 -0
- package/dist/types/marketplace.js +1 -0
- package/dist/types/messaging.d.ts +67 -0
- package/dist/types/messaging.js +1 -0
- package/dist/types/payments.d.ts +88 -0
- package/dist/types/payments.js +1 -0
- package/dist/types/profile.d.ts +49 -0
- package/dist/types/profile.js +1 -0
- package/dist/types/reputation.d.ts +90 -0
- package/dist/types/reputation.js +1 -0
- package/dist/types/search.d.ts +56 -0
- package/dist/types/search.js +1 -0
- package/dist/types/social.d.ts +158 -0
- package/dist/types/social.js +1 -0
- package/dist/websocket.d.ts +26 -0
- package/dist/websocket.js +83 -0
- package/package.json +30 -0
- package/src/api/a2a.ts +50 -0
- package/src/api/admin.ts +95 -0
- package/src/api/broadcasts.ts +110 -0
- package/src/api/channels.ts +110 -0
- package/src/api/directory.ts +45 -0
- package/src/api/escrow.ts +163 -0
- package/src/api/events.ts +133 -0
- package/src/api/explorer.ts +48 -0
- package/src/api/groups.ts +64 -0
- package/src/api/inbox.ts +71 -0
- package/src/api/keys.ts +18 -0
- package/src/api/ledger.ts +28 -0
- package/src/api/marketplace.ts +165 -0
- package/src/api/messages.ts +23 -0
- package/src/api/moderation.ts +71 -0
- package/src/api/payments.ts +47 -0
- package/src/api/pricing.ts +122 -0
- package/src/api/profiles.ts +43 -0
- package/src/api/registry.ts +143 -0
- package/src/api/reputation.ts +60 -0
- package/src/api/search.ts +59 -0
- package/src/api/stats.ts +32 -0
- package/src/auth.ts +75 -0
- package/src/client.ts +120 -0
- package/src/crypto.ts +74 -0
- package/src/http.ts +147 -0
- package/src/index.ts +72 -0
- package/src/local-signer.ts +78 -0
- package/src/signal/crypto.ts +229 -0
- package/src/signal/index.ts +28 -0
- package/src/signal/keys.ts +54 -0
- package/src/signal/memory-store.ts +66 -0
- package/src/signal/ratchet.ts +162 -0
- package/src/signal/session.ts +189 -0
- package/src/signal/store.ts +49 -0
- package/src/signal/x3dh.ts +130 -0
- package/src/signer.ts +21 -0
- package/src/types/broadcasts.ts +81 -0
- package/src/types/commerce.ts +206 -0
- package/src/types/directory.ts +98 -0
- package/src/types/escrow.ts +163 -0
- package/src/types/events.ts +155 -0
- package/src/types/explorer.ts +152 -0
- package/src/types/groups.ts +62 -0
- package/src/types/identity.ts +113 -0
- package/src/types/index.ts +16 -0
- package/src/types/ledger.ts +78 -0
- package/src/types/marketplace.ts +166 -0
- package/src/types/messaging.ts +77 -0
- package/src/types/payments.ts +103 -0
- package/src/types/profile.ts +55 -0
- package/src/types/reputation.ts +98 -0
- package/src/types/search.ts +61 -0
- package/src/types/social.ts +186 -0
- package/src/websocket.ts +112 -0
- package/tests/signal.test.ts +353 -0
- package/tests/staging.test.ts +650 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +7 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const SDK_VERSION = "0.1.0";
|
|
2
|
+
export { TinyVerseClient } from "./client.js";
|
|
3
|
+
export type { TinyVerseClientOptions } from "./client.js";
|
|
4
|
+
export { TinyVerseError } from "./http.js";
|
|
5
|
+
export { TinyVerseWebSocket } from "./websocket.js";
|
|
6
|
+
export type { TinyVerseWebSocketOptions, WebSocketEventHandler } from "./websocket.js";
|
|
7
|
+
export type { SigningKey, AuthHeaders, DirectoryWriteHeaders } from "./auth.js";
|
|
8
|
+
export { buildAuthHeader, signRequest, signDirectoryWrite, signCanonicalPayload } from "./auth.js";
|
|
9
|
+
export { Signer } from "./signer.js";
|
|
10
|
+
export { LocalSigner } from "./local-signer.js";
|
|
11
|
+
export type { KeyPair } from "./crypto.js";
|
|
12
|
+
export { generateKeyPair, publicKeyToHex, publicKeyToBase64, deriveCryptoId, sha256Hex, canonicalPayload, createSigningKey, } from "./crypto.js";
|
|
13
|
+
export type { RegisterRequest } from "./api/registry.js";
|
|
14
|
+
export { RegistryApi } from "./api/registry.js";
|
|
15
|
+
export { KeysApi } from "./api/keys.js";
|
|
16
|
+
export { MessagesApi } from "./api/messages.js";
|
|
17
|
+
export { DirectoryApi } from "./api/directory.js";
|
|
18
|
+
export { GroupsApi } from "./api/groups.js";
|
|
19
|
+
export { PaymentsApi } from "./api/payments.js";
|
|
20
|
+
export { LedgerApi } from "./api/ledger.js";
|
|
21
|
+
export { ReputationApi } from "./api/reputation.js";
|
|
22
|
+
export { InboxApi } from "./api/inbox.js";
|
|
23
|
+
export { ChannelsApi } from "./api/channels.js";
|
|
24
|
+
export { BroadcastsApi } from "./api/broadcasts.js";
|
|
25
|
+
export { EventsApi } from "./api/events.js";
|
|
26
|
+
export { MarketplaceApi } from "./api/marketplace.js";
|
|
27
|
+
export { EscrowApi } from "./api/escrow.js";
|
|
28
|
+
export { SearchApi } from "./api/search.js";
|
|
29
|
+
export { ProfilesApi } from "./api/profiles.js";
|
|
30
|
+
export { ExplorerApi } from "./api/explorer.js";
|
|
31
|
+
export { PricingApi } from "./api/pricing.js";
|
|
32
|
+
export { ModerationApi } from "./api/moderation.js";
|
|
33
|
+
export { StatsApi } from "./api/stats.js";
|
|
34
|
+
export { AdminApi } from "./api/admin.js";
|
|
35
|
+
export { A2AApi } from "./api/a2a.js";
|
|
36
|
+
export type { A2ATaskRequest, A2ATaskResponse } from "./api/a2a.js";
|
|
37
|
+
export * from "./types/index.js";
|
|
38
|
+
export { SignalSession, MemorySessionStore, generateSignedPreKey, generatePreKeys, serializeSignedKey, serializePreKey, generateX25519KeyPair, ed25519PubToX25519Pub, } from "./signal/index.js";
|
|
39
|
+
export type { SessionStore, SessionState, PreKeyPair, SignedPreKeyPair, X25519KeyPair, EncryptedMessage, } from "./signal/index.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const SDK_VERSION = "0.1.0";
|
|
2
|
+
export { TinyVerseClient } from "./client.js";
|
|
3
|
+
export { TinyVerseError } from "./http.js";
|
|
4
|
+
export { TinyVerseWebSocket } from "./websocket.js";
|
|
5
|
+
export { buildAuthHeader, signRequest, signDirectoryWrite, signCanonicalPayload } from "./auth.js";
|
|
6
|
+
export { Signer } from "./signer.js";
|
|
7
|
+
export { LocalSigner } from "./local-signer.js";
|
|
8
|
+
export { generateKeyPair, publicKeyToHex, publicKeyToBase64, deriveCryptoId, sha256Hex, canonicalPayload, createSigningKey, } from "./crypto.js";
|
|
9
|
+
export { RegistryApi } from "./api/registry.js";
|
|
10
|
+
export { KeysApi } from "./api/keys.js";
|
|
11
|
+
export { MessagesApi } from "./api/messages.js";
|
|
12
|
+
export { DirectoryApi } from "./api/directory.js";
|
|
13
|
+
export { GroupsApi } from "./api/groups.js";
|
|
14
|
+
export { PaymentsApi } from "./api/payments.js";
|
|
15
|
+
export { LedgerApi } from "./api/ledger.js";
|
|
16
|
+
export { ReputationApi } from "./api/reputation.js";
|
|
17
|
+
export { InboxApi } from "./api/inbox.js";
|
|
18
|
+
export { ChannelsApi } from "./api/channels.js";
|
|
19
|
+
export { BroadcastsApi } from "./api/broadcasts.js";
|
|
20
|
+
export { EventsApi } from "./api/events.js";
|
|
21
|
+
export { MarketplaceApi } from "./api/marketplace.js";
|
|
22
|
+
export { EscrowApi } from "./api/escrow.js";
|
|
23
|
+
export { SearchApi } from "./api/search.js";
|
|
24
|
+
export { ProfilesApi } from "./api/profiles.js";
|
|
25
|
+
export { ExplorerApi } from "./api/explorer.js";
|
|
26
|
+
export { PricingApi } from "./api/pricing.js";
|
|
27
|
+
export { ModerationApi } from "./api/moderation.js";
|
|
28
|
+
export { StatsApi } from "./api/stats.js";
|
|
29
|
+
export { AdminApi } from "./api/admin.js";
|
|
30
|
+
export { A2AApi } from "./api/a2a.js";
|
|
31
|
+
export * from "./types/index.js";
|
|
32
|
+
export { SignalSession, MemorySessionStore, generateSignedPreKey, generatePreKeys, serializeSignedKey, serializePreKey, generateX25519KeyPair, ed25519PubToX25519Pub, } from "./signal/index.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Signer } from "./signer.js";
|
|
2
|
+
import type { KeyPair } from "./crypto.js";
|
|
3
|
+
import type { X25519KeyPair } from "./signal/crypto.js";
|
|
4
|
+
export declare class LocalSigner extends Signer {
|
|
5
|
+
readonly agentId: string;
|
|
6
|
+
readonly publicKeyBase64: string;
|
|
7
|
+
readonly publicKey: Uint8Array;
|
|
8
|
+
private readonly privateKey;
|
|
9
|
+
private constructor();
|
|
10
|
+
static generate(): Promise<LocalSigner>;
|
|
11
|
+
static fromPrivateKey(privateKey: CryptoKey): Promise<LocalSigner>;
|
|
12
|
+
static fromKeyPair(keyPair: KeyPair): LocalSigner;
|
|
13
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
14
|
+
getX25519KeyPair(): Promise<X25519KeyPair>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Signer } from "./signer.js";
|
|
2
|
+
import { generateKeyPair, deriveCryptoId, publicKeyToBase64, } from "./crypto.js";
|
|
3
|
+
import { ed25519SeedToX25519KeyPair } from "./signal/crypto.js";
|
|
4
|
+
export class LocalSigner extends Signer {
|
|
5
|
+
constructor(keyPair) {
|
|
6
|
+
super();
|
|
7
|
+
this.publicKey = keyPair.publicKey;
|
|
8
|
+
this.privateKey = keyPair.privateKey;
|
|
9
|
+
this.agentId = deriveCryptoId(keyPair.publicKey);
|
|
10
|
+
this.publicKeyBase64 = publicKeyToBase64(keyPair.publicKey);
|
|
11
|
+
}
|
|
12
|
+
static async generate() {
|
|
13
|
+
const keyPair = await generateKeyPair();
|
|
14
|
+
return new LocalSigner(keyPair);
|
|
15
|
+
}
|
|
16
|
+
static async fromPrivateKey(privateKey) {
|
|
17
|
+
const crypto = globalThis.crypto;
|
|
18
|
+
const jwk = await crypto.subtle.exportKey("jwk", privateKey);
|
|
19
|
+
const publicOnlyJwk = { ...jwk, d: undefined, key_ops: ["verify"] };
|
|
20
|
+
const publicCryptoKey = await crypto.subtle.importKey("jwk", publicOnlyJwk, { name: "Ed25519" }, true, ["verify"]);
|
|
21
|
+
const publicKeyRaw = new Uint8Array(await crypto.subtle.exportKey("raw", publicCryptoKey));
|
|
22
|
+
return new LocalSigner({ publicKey: publicKeyRaw, privateKey });
|
|
23
|
+
}
|
|
24
|
+
static fromKeyPair(keyPair) {
|
|
25
|
+
return new LocalSigner(keyPair);
|
|
26
|
+
}
|
|
27
|
+
async sign(data) {
|
|
28
|
+
const crypto = globalThis.crypto;
|
|
29
|
+
const buffer = new ArrayBuffer(data.byteLength);
|
|
30
|
+
new Uint8Array(buffer).set(data);
|
|
31
|
+
const sig = await crypto.subtle.sign("Ed25519", this.privateKey, buffer);
|
|
32
|
+
return new Uint8Array(sig);
|
|
33
|
+
}
|
|
34
|
+
async getX25519KeyPair() {
|
|
35
|
+
const crypto = globalThis.crypto;
|
|
36
|
+
const jwk = await crypto.subtle.exportKey("jwk", this.privateKey);
|
|
37
|
+
const seed = base64urlToBytes(jwk.d);
|
|
38
|
+
return ed25519SeedToX25519KeyPair(seed);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function base64urlToBytes(b64url) {
|
|
42
|
+
const b64 = b64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
43
|
+
const pad = (4 - (b64.length % 4)) % 4;
|
|
44
|
+
const padded = b64 + "=".repeat(pad);
|
|
45
|
+
const binary = atob(padded);
|
|
46
|
+
const bytes = new Uint8Array(binary.length);
|
|
47
|
+
for (let i = 0; i < binary.length; i++) {
|
|
48
|
+
bytes[i] = binary.charCodeAt(i);
|
|
49
|
+
}
|
|
50
|
+
return bytes;
|
|
51
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface X25519KeyPair {
|
|
2
|
+
publicKey: Uint8Array;
|
|
3
|
+
privateKey: Uint8Array;
|
|
4
|
+
}
|
|
5
|
+
export declare function generateX25519KeyPair(): X25519KeyPair;
|
|
6
|
+
export declare function x25519SharedSecret(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;
|
|
7
|
+
export declare function ed25519SeedToX25519Private(seed: Uint8Array): Uint8Array;
|
|
8
|
+
export declare function ed25519SeedToX25519KeyPair(seed: Uint8Array): X25519KeyPair;
|
|
9
|
+
export declare function ed25519PubToX25519Pub(edPub: Uint8Array): Uint8Array;
|
|
10
|
+
export declare function kdfRootKey(rootKey: Uint8Array, dhOutput: Uint8Array): {
|
|
11
|
+
rootKey: Uint8Array;
|
|
12
|
+
chainKey: Uint8Array;
|
|
13
|
+
};
|
|
14
|
+
export declare function kdfChainKey(chainKey: Uint8Array): {
|
|
15
|
+
chainKey: Uint8Array;
|
|
16
|
+
messageKey: Uint8Array;
|
|
17
|
+
};
|
|
18
|
+
export declare function deriveMessageKeys(messageKey: Uint8Array): {
|
|
19
|
+
encKey: Uint8Array;
|
|
20
|
+
macKey: Uint8Array;
|
|
21
|
+
iv: Uint8Array;
|
|
22
|
+
};
|
|
23
|
+
export declare function aesEncrypt(key: Uint8Array, iv: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
|
|
24
|
+
export declare function aesDecrypt(key: Uint8Array, iv: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;
|
|
25
|
+
export declare function computeHmac(key: Uint8Array, data: Uint8Array): Uint8Array;
|
|
26
|
+
export declare function encrypt(messageKey: Uint8Array, plaintext: Uint8Array, associatedData: Uint8Array): Promise<Uint8Array>;
|
|
27
|
+
export declare function decrypt(messageKey: Uint8Array, ciphertextWithMac: Uint8Array, associatedData: Uint8Array): Promise<Uint8Array>;
|
|
28
|
+
export declare function toBase64(bytes: Uint8Array): string;
|
|
29
|
+
export declare function fromBase64(b64: string): Uint8Array;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { x25519 } from "@noble/curves/ed25519.js";
|
|
2
|
+
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
3
|
+
import { sha256, sha512 } from "@noble/hashes/sha2.js";
|
|
4
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
5
|
+
const crypto = globalThis.crypto;
|
|
6
|
+
const HKDF_INFO = new TextEncoder().encode("WhisperRatchet");
|
|
7
|
+
const MESSAGE_KEY_INFO = new TextEncoder().encode("WhisperMessageKeys");
|
|
8
|
+
const CHAIN_KEY_SEED_MESSAGE = new Uint8Array([0x01]);
|
|
9
|
+
const CHAIN_KEY_SEED_CHAIN = new Uint8Array([0x02]);
|
|
10
|
+
export function generateX25519KeyPair() {
|
|
11
|
+
const privateKey = x25519.utils.randomSecretKey();
|
|
12
|
+
const publicKey = x25519.getPublicKey(privateKey);
|
|
13
|
+
return { publicKey, privateKey };
|
|
14
|
+
}
|
|
15
|
+
export function x25519SharedSecret(privateKey, publicKey) {
|
|
16
|
+
return x25519.getSharedSecret(privateKey, publicKey);
|
|
17
|
+
}
|
|
18
|
+
export function ed25519SeedToX25519Private(seed) {
|
|
19
|
+
const hash = sha512(seed);
|
|
20
|
+
const scalar = hash.slice(0, 32);
|
|
21
|
+
scalar[0] &= 248;
|
|
22
|
+
scalar[31] &= 127;
|
|
23
|
+
scalar[31] |= 64;
|
|
24
|
+
return scalar;
|
|
25
|
+
}
|
|
26
|
+
export function ed25519SeedToX25519KeyPair(seed) {
|
|
27
|
+
const privateKey = ed25519SeedToX25519Private(seed);
|
|
28
|
+
const publicKey = x25519.getPublicKey(privateKey);
|
|
29
|
+
return { publicKey, privateKey };
|
|
30
|
+
}
|
|
31
|
+
// Edwards (Ed25519) public key → Montgomery (X25519) public key.
|
|
32
|
+
// Formula: u = (1 + y) / (1 - y) mod p, where p = 2^255 - 19.
|
|
33
|
+
const P = (1n << 255n) - 19n;
|
|
34
|
+
function modPow(base, exp, modulus) {
|
|
35
|
+
let result = 1n;
|
|
36
|
+
base = ((base % modulus) + modulus) % modulus;
|
|
37
|
+
while (exp > 0n) {
|
|
38
|
+
if (exp & 1n)
|
|
39
|
+
result = (result * base) % modulus;
|
|
40
|
+
exp >>= 1n;
|
|
41
|
+
base = (base * base) % modulus;
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
function modInverse(a, modulus) {
|
|
46
|
+
return modPow(a, modulus - 2n, modulus);
|
|
47
|
+
}
|
|
48
|
+
export function ed25519PubToX25519Pub(edPub) {
|
|
49
|
+
// Ed25519 public key encodes the y-coordinate in little-endian with
|
|
50
|
+
// the sign bit in the top bit of the last byte.
|
|
51
|
+
const bytes = new Uint8Array(edPub);
|
|
52
|
+
bytes[31] = bytes[31] & 0x7f;
|
|
53
|
+
let y = 0n;
|
|
54
|
+
for (let i = 0; i < 32; i++) {
|
|
55
|
+
y |= BigInt(bytes[i]) << BigInt(8 * i);
|
|
56
|
+
}
|
|
57
|
+
const numerator = ((1n + y) % P + P) % P;
|
|
58
|
+
const denominator = ((1n - y) % P + P) % P;
|
|
59
|
+
const u = (numerator * modInverse(denominator, P)) % P;
|
|
60
|
+
const result = new Uint8Array(32);
|
|
61
|
+
let val = u;
|
|
62
|
+
for (let i = 0; i < 32; i++) {
|
|
63
|
+
result[i] = Number(val & 0xffn);
|
|
64
|
+
val >>= 8n;
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
export function kdfRootKey(rootKey, dhOutput) {
|
|
69
|
+
const output = hkdf(sha256, dhOutput, rootKey, HKDF_INFO, 64);
|
|
70
|
+
return {
|
|
71
|
+
rootKey: output.slice(0, 32),
|
|
72
|
+
chainKey: output.slice(32, 64),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function kdfChainKey(chainKey) {
|
|
76
|
+
const newChainKey = hmac(sha256, chainKey, CHAIN_KEY_SEED_CHAIN);
|
|
77
|
+
const messageKey = hmac(sha256, chainKey, CHAIN_KEY_SEED_MESSAGE);
|
|
78
|
+
return { chainKey: newChainKey, messageKey };
|
|
79
|
+
}
|
|
80
|
+
export function deriveMessageKeys(messageKey) {
|
|
81
|
+
const output = hkdf(sha256, messageKey, new Uint8Array(32), MESSAGE_KEY_INFO, 80);
|
|
82
|
+
return {
|
|
83
|
+
encKey: output.slice(0, 32),
|
|
84
|
+
macKey: output.slice(32, 64),
|
|
85
|
+
iv: output.slice(64, 80),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function toArrayBuffer(bytes) {
|
|
89
|
+
const buffer = new ArrayBuffer(bytes.length);
|
|
90
|
+
new Uint8Array(buffer).set(bytes);
|
|
91
|
+
return buffer;
|
|
92
|
+
}
|
|
93
|
+
export async function aesEncrypt(key, iv, plaintext) {
|
|
94
|
+
const crypto = globalThis.crypto;
|
|
95
|
+
const cryptoKey = await crypto.subtle.importKey("raw", toArrayBuffer(key), { name: "AES-CBC" }, false, ["encrypt"]);
|
|
96
|
+
const ciphertext = await crypto.subtle.encrypt({ name: "AES-CBC", iv: toArrayBuffer(iv) }, cryptoKey, toArrayBuffer(plaintext));
|
|
97
|
+
return new Uint8Array(ciphertext);
|
|
98
|
+
}
|
|
99
|
+
export async function aesDecrypt(key, iv, ciphertext) {
|
|
100
|
+
const crypto = globalThis.crypto;
|
|
101
|
+
const cryptoKey = await crypto.subtle.importKey("raw", toArrayBuffer(key), { name: "AES-CBC" }, false, ["decrypt"]);
|
|
102
|
+
const plaintext = await crypto.subtle.decrypt({ name: "AES-CBC", iv: toArrayBuffer(iv) }, cryptoKey, toArrayBuffer(ciphertext));
|
|
103
|
+
return new Uint8Array(plaintext);
|
|
104
|
+
}
|
|
105
|
+
export function computeHmac(key, data) {
|
|
106
|
+
return hmac(sha256, key, data);
|
|
107
|
+
}
|
|
108
|
+
export async function encrypt(messageKey, plaintext, associatedData) {
|
|
109
|
+
const { encKey, macKey, iv } = deriveMessageKeys(messageKey);
|
|
110
|
+
const ciphertext = await aesEncrypt(encKey, iv, plaintext);
|
|
111
|
+
const macInput = new Uint8Array(associatedData.length + ciphertext.length);
|
|
112
|
+
macInput.set(associatedData);
|
|
113
|
+
macInput.set(ciphertext, associatedData.length);
|
|
114
|
+
const mac = computeHmac(macKey, macInput).slice(0, 8);
|
|
115
|
+
const result = new Uint8Array(ciphertext.length + 8);
|
|
116
|
+
result.set(ciphertext);
|
|
117
|
+
result.set(mac, ciphertext.length);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
export async function decrypt(messageKey, ciphertextWithMac, associatedData) {
|
|
121
|
+
const { encKey, macKey, iv } = deriveMessageKeys(messageKey);
|
|
122
|
+
const ciphertext = ciphertextWithMac.slice(0, -8);
|
|
123
|
+
const receivedMac = ciphertextWithMac.slice(-8);
|
|
124
|
+
const macInput = new Uint8Array(associatedData.length + ciphertext.length);
|
|
125
|
+
macInput.set(associatedData);
|
|
126
|
+
macInput.set(ciphertext, associatedData.length);
|
|
127
|
+
const computedMac = computeHmac(macKey, macInput).slice(0, 8);
|
|
128
|
+
if (!constantTimeEqual(receivedMac, computedMac)) {
|
|
129
|
+
throw new Error("MAC verification failed");
|
|
130
|
+
}
|
|
131
|
+
return aesDecrypt(encKey, iv, ciphertext);
|
|
132
|
+
}
|
|
133
|
+
function constantTimeEqual(a, b) {
|
|
134
|
+
if (a.length !== b.length)
|
|
135
|
+
return false;
|
|
136
|
+
let diff = 0;
|
|
137
|
+
for (let i = 0; i < a.length; i++) {
|
|
138
|
+
diff |= a[i] ^ b[i];
|
|
139
|
+
}
|
|
140
|
+
return diff === 0;
|
|
141
|
+
}
|
|
142
|
+
export function toBase64(bytes) {
|
|
143
|
+
let binary = "";
|
|
144
|
+
for (const byte of bytes) {
|
|
145
|
+
binary += String.fromCharCode(byte);
|
|
146
|
+
}
|
|
147
|
+
return btoa(binary);
|
|
148
|
+
}
|
|
149
|
+
export function fromBase64(b64) {
|
|
150
|
+
const binary = atob(b64);
|
|
151
|
+
const bytes = new Uint8Array(binary.length);
|
|
152
|
+
for (let i = 0; i < binary.length; i++) {
|
|
153
|
+
bytes[i] = binary.charCodeAt(i);
|
|
154
|
+
}
|
|
155
|
+
return bytes;
|
|
156
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { X25519KeyPair } from "./crypto.js";
|
|
2
|
+
export { generateX25519KeyPair, ed25519PubToX25519Pub, ed25519SeedToX25519KeyPair, toBase64, fromBase64, } from "./crypto.js";
|
|
3
|
+
export type { SessionState, PreKeyPair, SignedPreKeyPair, SessionStore } from "./store.js";
|
|
4
|
+
export { MemorySessionStore } from "./memory-store.js";
|
|
5
|
+
export type { X3DHBundle, X3DHInitResult } from "./x3dh.js";
|
|
6
|
+
export { x3dhInitiate, x3dhRespond, buildAssociatedData } from "./x3dh.js";
|
|
7
|
+
export type { RatchetHeader, RatchetMessage } from "./ratchet.js";
|
|
8
|
+
export { ratchetEncrypt, ratchetDecrypt } from "./ratchet.js";
|
|
9
|
+
export { generateSignedPreKey, generatePreKeys, serializeSignedKey, serializePreKey, } from "./keys.js";
|
|
10
|
+
export type { EncryptedMessage } from "./session.js";
|
|
11
|
+
export { SignalSession } from "./session.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { generateX25519KeyPair, ed25519PubToX25519Pub, ed25519SeedToX25519KeyPair, toBase64, fromBase64, } from "./crypto.js";
|
|
2
|
+
export { MemorySessionStore } from "./memory-store.js";
|
|
3
|
+
export { x3dhInitiate, x3dhRespond, buildAssociatedData } from "./x3dh.js";
|
|
4
|
+
export { ratchetEncrypt, ratchetDecrypt } from "./ratchet.js";
|
|
5
|
+
export { generateSignedPreKey, generatePreKeys, serializeSignedKey, serializePreKey, } from "./keys.js";
|
|
6
|
+
export { SignalSession } from "./session.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Signer } from "../signer.js";
|
|
2
|
+
import type { PreKeyPair, SignedPreKeyPair } from "./store.js";
|
|
3
|
+
export declare function generateSignedPreKey(signer: Signer, keyId: string): Promise<SignedPreKeyPair>;
|
|
4
|
+
export declare function generatePreKeys(signer: Signer, startId: number, count: number): Promise<Array<PreKeyPair>>;
|
|
5
|
+
export declare function serializeSignedKey(preKey: SignedPreKeyPair): {
|
|
6
|
+
keyId: string;
|
|
7
|
+
publicKey: string;
|
|
8
|
+
signature: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function serializePreKey(preKey: PreKeyPair): {
|
|
11
|
+
keyId: string;
|
|
12
|
+
publicKey: string;
|
|
13
|
+
signature: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { generateX25519KeyPair, toBase64 } from "./crypto.js";
|
|
2
|
+
// Backend verifies: ed25519.Verify(identityPubKey, []byte(preKey.PublicKey), signature)
|
|
3
|
+
// So we sign the base64 string representation of the X25519 public key.
|
|
4
|
+
async function signPublicKey(signer, publicKey) {
|
|
5
|
+
const publicKeyB64 = toBase64(publicKey);
|
|
6
|
+
return signer.sign(new TextEncoder().encode(publicKeyB64));
|
|
7
|
+
}
|
|
8
|
+
export async function generateSignedPreKey(signer, keyId) {
|
|
9
|
+
const keyPair = generateX25519KeyPair();
|
|
10
|
+
const signature = await signPublicKey(signer, keyPair.publicKey);
|
|
11
|
+
return { keyId, keyPair, signature };
|
|
12
|
+
}
|
|
13
|
+
export async function generatePreKeys(signer, startId, count) {
|
|
14
|
+
const preKeys = [];
|
|
15
|
+
for (let i = 0; i < count; i++) {
|
|
16
|
+
const keyId = `pk_${startId + i}`;
|
|
17
|
+
const keyPair = generateX25519KeyPair();
|
|
18
|
+
const signature = await signPublicKey(signer, keyPair.publicKey);
|
|
19
|
+
preKeys.push({ keyId, keyPair, signature });
|
|
20
|
+
}
|
|
21
|
+
return preKeys;
|
|
22
|
+
}
|
|
23
|
+
export function serializeSignedKey(preKey) {
|
|
24
|
+
return {
|
|
25
|
+
keyId: preKey.keyId,
|
|
26
|
+
publicKey: toBase64(preKey.keyPair.publicKey),
|
|
27
|
+
signature: toBase64(preKey.signature),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function serializePreKey(preKey) {
|
|
31
|
+
return {
|
|
32
|
+
keyId: preKey.keyId,
|
|
33
|
+
publicKey: toBase64(preKey.keyPair.publicKey),
|
|
34
|
+
signature: toBase64(preKey.signature),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { X25519KeyPair } from "./crypto.js";
|
|
2
|
+
import type { SessionStore, SessionState, PreKeyPair, SignedPreKeyPair } from "./store.js";
|
|
3
|
+
export declare class MemorySessionStore implements SessionStore {
|
|
4
|
+
private readonly identityKeyPair;
|
|
5
|
+
private readonly signedPreKeys;
|
|
6
|
+
private readonly preKeys;
|
|
7
|
+
private readonly sessions;
|
|
8
|
+
private activeSignedPreKeyId;
|
|
9
|
+
constructor(identityKeyPair: X25519KeyPair);
|
|
10
|
+
getIdentityX25519KeyPair(): Promise<X25519KeyPair>;
|
|
11
|
+
getSignedPreKey(keyId: string): Promise<SignedPreKeyPair | null>;
|
|
12
|
+
getActiveSignedPreKey(): Promise<SignedPreKeyPair>;
|
|
13
|
+
storeSignedPreKey(preKey: SignedPreKeyPair): Promise<void>;
|
|
14
|
+
getPreKey(keyId: string): Promise<PreKeyPair | null>;
|
|
15
|
+
removePreKey(keyId: string): Promise<void>;
|
|
16
|
+
storePreKey(preKey: PreKeyPair): Promise<void>;
|
|
17
|
+
getAllPreKeys(): Promise<Array<PreKeyPair>>;
|
|
18
|
+
getSession(address: string): Promise<SessionState | null>;
|
|
19
|
+
storeSession(address: string, session: SessionState): Promise<void>;
|
|
20
|
+
removeSession(address: string): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export class MemorySessionStore {
|
|
2
|
+
constructor(identityKeyPair) {
|
|
3
|
+
this.signedPreKeys = new Map();
|
|
4
|
+
this.preKeys = new Map();
|
|
5
|
+
this.sessions = new Map();
|
|
6
|
+
this.activeSignedPreKeyId = null;
|
|
7
|
+
this.identityKeyPair = identityKeyPair;
|
|
8
|
+
}
|
|
9
|
+
async getIdentityX25519KeyPair() {
|
|
10
|
+
return this.identityKeyPair;
|
|
11
|
+
}
|
|
12
|
+
async getSignedPreKey(keyId) {
|
|
13
|
+
return this.signedPreKeys.get(keyId) ?? null;
|
|
14
|
+
}
|
|
15
|
+
async getActiveSignedPreKey() {
|
|
16
|
+
if (!this.activeSignedPreKeyId) {
|
|
17
|
+
throw new Error("No active signed pre-key");
|
|
18
|
+
}
|
|
19
|
+
const key = this.signedPreKeys.get(this.activeSignedPreKeyId);
|
|
20
|
+
if (!key) {
|
|
21
|
+
throw new Error("Active signed pre-key not found");
|
|
22
|
+
}
|
|
23
|
+
return key;
|
|
24
|
+
}
|
|
25
|
+
async storeSignedPreKey(preKey) {
|
|
26
|
+
this.signedPreKeys.set(preKey.keyId, preKey);
|
|
27
|
+
this.activeSignedPreKeyId = preKey.keyId;
|
|
28
|
+
}
|
|
29
|
+
async getPreKey(keyId) {
|
|
30
|
+
return this.preKeys.get(keyId) ?? null;
|
|
31
|
+
}
|
|
32
|
+
async removePreKey(keyId) {
|
|
33
|
+
this.preKeys.delete(keyId);
|
|
34
|
+
}
|
|
35
|
+
async storePreKey(preKey) {
|
|
36
|
+
this.preKeys.set(preKey.keyId, preKey);
|
|
37
|
+
}
|
|
38
|
+
async getAllPreKeys() {
|
|
39
|
+
return Array.from(this.preKeys.values());
|
|
40
|
+
}
|
|
41
|
+
async getSession(address) {
|
|
42
|
+
return this.sessions.get(address) ?? null;
|
|
43
|
+
}
|
|
44
|
+
async storeSession(address, session) {
|
|
45
|
+
this.sessions.set(address, session);
|
|
46
|
+
}
|
|
47
|
+
async removeSession(address) {
|
|
48
|
+
this.sessions.delete(address);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SessionState } from "./store.js";
|
|
2
|
+
export interface RatchetHeader {
|
|
3
|
+
publicKey: Uint8Array;
|
|
4
|
+
previousChainLength: number;
|
|
5
|
+
messageNumber: number;
|
|
6
|
+
}
|
|
7
|
+
export interface RatchetMessage {
|
|
8
|
+
header: RatchetHeader;
|
|
9
|
+
ciphertext: Uint8Array;
|
|
10
|
+
}
|
|
11
|
+
export declare function ratchetEncrypt(state: SessionState, plaintext: Uint8Array, associatedData: Uint8Array): Promise<RatchetMessage>;
|
|
12
|
+
export declare function ratchetDecrypt(state: SessionState, message: RatchetMessage, associatedData: Uint8Array): Promise<Uint8Array>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { generateX25519KeyPair, x25519SharedSecret, kdfRootKey, kdfChainKey, encrypt, decrypt, } from "./crypto.js";
|
|
2
|
+
import { skippedKeyId } from "./store.js";
|
|
3
|
+
const MAX_SKIP = 1000;
|
|
4
|
+
export async function ratchetEncrypt(state, plaintext, associatedData) {
|
|
5
|
+
if (!state.sendChainKey) {
|
|
6
|
+
dhRatchetStep(state);
|
|
7
|
+
}
|
|
8
|
+
const { chainKey, messageKey } = kdfChainKey(state.sendChainKey);
|
|
9
|
+
state.sendChainKey = chainKey;
|
|
10
|
+
const header = {
|
|
11
|
+
publicKey: state.dhSendKeyPair.publicKey,
|
|
12
|
+
previousChainLength: state.previousChainLength,
|
|
13
|
+
messageNumber: state.sendMessageNumber,
|
|
14
|
+
};
|
|
15
|
+
state.sendMessageNumber++;
|
|
16
|
+
const headerBytes = encodeHeader(header);
|
|
17
|
+
const ad = concat(associatedData, headerBytes);
|
|
18
|
+
const ciphertext = await encrypt(messageKey, plaintext, ad);
|
|
19
|
+
return { header, ciphertext };
|
|
20
|
+
}
|
|
21
|
+
export async function ratchetDecrypt(state, message, associatedData) {
|
|
22
|
+
const skId = skippedKeyId(message.header.publicKey, message.header.messageNumber);
|
|
23
|
+
const skippedMk = state.skippedKeys.get(skId);
|
|
24
|
+
if (skippedMk) {
|
|
25
|
+
state.skippedKeys.delete(skId);
|
|
26
|
+
const headerBytes = encodeHeader(message.header);
|
|
27
|
+
const ad = concat(associatedData, headerBytes);
|
|
28
|
+
return decrypt(skippedMk, message.ciphertext, ad);
|
|
29
|
+
}
|
|
30
|
+
const headerKeyChanged = !state.dhRecvPublicKey ||
|
|
31
|
+
!uint8ArrayEqual(state.dhRecvPublicKey, message.header.publicKey);
|
|
32
|
+
if (headerKeyChanged) {
|
|
33
|
+
if (state.recvChainKey) {
|
|
34
|
+
skipMessageKeys(state, message.header.previousChainLength);
|
|
35
|
+
}
|
|
36
|
+
dhRatchetStepWithRecv(state, message.header.publicKey);
|
|
37
|
+
}
|
|
38
|
+
skipMessageKeys(state, message.header.messageNumber);
|
|
39
|
+
const { chainKey, messageKey } = kdfChainKey(state.recvChainKey);
|
|
40
|
+
state.recvChainKey = chainKey;
|
|
41
|
+
state.recvMessageNumber++;
|
|
42
|
+
const headerBytes = encodeHeader(message.header);
|
|
43
|
+
const ad = concat(associatedData, headerBytes);
|
|
44
|
+
return decrypt(messageKey, message.ciphertext, ad);
|
|
45
|
+
}
|
|
46
|
+
function dhRatchetStep(state) {
|
|
47
|
+
if (!state.dhRecvPublicKey) {
|
|
48
|
+
throw new Error("Cannot perform DH ratchet without recipient public key");
|
|
49
|
+
}
|
|
50
|
+
const dhOutput = x25519SharedSecret(state.dhSendKeyPair.privateKey, state.dhRecvPublicKey);
|
|
51
|
+
const { rootKey, chainKey } = kdfRootKey(state.rootKey, dhOutput);
|
|
52
|
+
state.rootKey = rootKey;
|
|
53
|
+
state.sendChainKey = chainKey;
|
|
54
|
+
}
|
|
55
|
+
function dhRatchetStepWithRecv(state, newRecvPublicKey) {
|
|
56
|
+
state.previousChainLength = state.sendMessageNumber;
|
|
57
|
+
state.sendMessageNumber = 0;
|
|
58
|
+
state.recvMessageNumber = 0;
|
|
59
|
+
state.dhRecvPublicKey = newRecvPublicKey;
|
|
60
|
+
const dhRecv = x25519SharedSecret(state.dhSendKeyPair.privateKey, state.dhRecvPublicKey);
|
|
61
|
+
const recvResult = kdfRootKey(state.rootKey, dhRecv);
|
|
62
|
+
state.rootKey = recvResult.rootKey;
|
|
63
|
+
state.recvChainKey = recvResult.chainKey;
|
|
64
|
+
state.dhSendKeyPair = generateX25519KeyPair();
|
|
65
|
+
const dhSend = x25519SharedSecret(state.dhSendKeyPair.privateKey, state.dhRecvPublicKey);
|
|
66
|
+
const sendResult = kdfRootKey(state.rootKey, dhSend);
|
|
67
|
+
state.rootKey = sendResult.rootKey;
|
|
68
|
+
state.sendChainKey = sendResult.chainKey;
|
|
69
|
+
}
|
|
70
|
+
function skipMessageKeys(state, until) {
|
|
71
|
+
if (!state.recvChainKey)
|
|
72
|
+
return;
|
|
73
|
+
if (until - state.recvMessageNumber > MAX_SKIP) {
|
|
74
|
+
throw new Error("Too many skipped messages");
|
|
75
|
+
}
|
|
76
|
+
while (state.recvMessageNumber < until) {
|
|
77
|
+
const { chainKey, messageKey } = kdfChainKey(state.recvChainKey);
|
|
78
|
+
state.recvChainKey = chainKey;
|
|
79
|
+
const skId = skippedKeyId(state.dhRecvPublicKey, state.recvMessageNumber);
|
|
80
|
+
state.skippedKeys.set(skId, messageKey);
|
|
81
|
+
state.recvMessageNumber++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function encodeHeader(header) {
|
|
85
|
+
const result = new Uint8Array(32 + 4 + 4);
|
|
86
|
+
result.set(header.publicKey);
|
|
87
|
+
const view = new DataView(result.buffer);
|
|
88
|
+
view.setUint32(32, header.previousChainLength, false);
|
|
89
|
+
view.setUint32(36, header.messageNumber, false);
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
function concat(a, b) {
|
|
93
|
+
const result = new Uint8Array(a.length + b.length);
|
|
94
|
+
result.set(a);
|
|
95
|
+
result.set(b, a.length);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
function uint8ArrayEqual(a, b) {
|
|
99
|
+
if (a.length !== b.length)
|
|
100
|
+
return false;
|
|
101
|
+
for (let i = 0; i < a.length; i++) {
|
|
102
|
+
if (a[i] !== b[i])
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SessionStore } from "./store.js";
|
|
2
|
+
import type { KeyBundle, MessageEnvelope, SignalMetadata } from "../types/index.js";
|
|
3
|
+
export interface EncryptedMessage {
|
|
4
|
+
body: string;
|
|
5
|
+
type: "CIPHERTEXT" | "PREKEY_BUNDLE";
|
|
6
|
+
signal?: SignalMetadata;
|
|
7
|
+
}
|
|
8
|
+
export declare class SignalSession {
|
|
9
|
+
private readonly store;
|
|
10
|
+
private readonly ourIdentityPublicKey;
|
|
11
|
+
constructor(store: SessionStore, ourIdentityPublicKey: Uint8Array);
|
|
12
|
+
encrypt(recipientAddress: string, recipientIdentityKey: Uint8Array, plaintext: Uint8Array, recipientBundle?: KeyBundle): Promise<EncryptedMessage>;
|
|
13
|
+
decrypt(senderAddress: string, senderIdentityKey: Uint8Array, envelope: MessageEnvelope): Promise<Uint8Array>;
|
|
14
|
+
private processPreKeyMessage;
|
|
15
|
+
hasSession(address: string): Promise<boolean>;
|
|
16
|
+
removeSession(address: string): Promise<void>;
|
|
17
|
+
}
|