@rine-network/core 0.4.4 → 0.5.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/README.md +5 -5
- package/dist/index.js +1007 -21
- package/dist/src/api-types.d.ts +14 -0
- package/dist/src/crypto/hybrid.d.ts +8 -0
- package/dist/src/crypto/index.d.ts +5 -0
- package/dist/src/crypto/keys.d.ts +10 -0
- package/dist/src/crypto/message.d.ts +25 -4
- package/dist/src/crypto/mls-api.d.ts +91 -0
- package/dist/src/crypto/mls-init.d.ts +6 -0
- package/dist/src/crypto/mls-state.d.ts +29 -0
- package/dist/src/crypto/mls.d.ts +63 -0
- package/dist/src/errors.d.ts +2 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/mls-ops-join.d.ts +24 -0
- package/dist/src/mls-ops-sync.d.ts +23 -0
- package/dist/src/mls-ops.d.ts +25 -0
- package/dist/src/types.d.ts +2 -0
- package/dist/test/crypto/hybrid.test.d.ts +1 -0
- package/dist/test/crypto/message-hybrid.test.d.ts +1 -0
- package/dist/test/crypto/mls.test.d.ts +1 -0
- package/dist/test/mls-external-join.test.d.ts +1 -0
- package/dist/test/mls-ops.test.d.ts +1 -0
- package/package.json +4 -2
package/dist/src/api-types.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ export interface GroupRead {
|
|
|
9
9
|
vote_duration_hours: number;
|
|
10
10
|
member_count: number;
|
|
11
11
|
created_at: string;
|
|
12
|
+
mls_enabled?: boolean;
|
|
13
|
+
mls_group_id?: string | null;
|
|
14
|
+
mls_pending?: boolean;
|
|
15
|
+
mls_cipher_suite?: number | null;
|
|
12
16
|
}
|
|
13
17
|
export interface GroupMemberRead {
|
|
14
18
|
id: string;
|
|
@@ -86,6 +90,11 @@ export interface AgentKeysResponse {
|
|
|
86
90
|
crv: string;
|
|
87
91
|
x: string;
|
|
88
92
|
};
|
|
93
|
+
pq_encryption_public_key?: {
|
|
94
|
+
kty: string;
|
|
95
|
+
alg: string;
|
|
96
|
+
x: string;
|
|
97
|
+
};
|
|
89
98
|
}
|
|
90
99
|
export interface BatchKeysResponse {
|
|
91
100
|
keys: Record<string, {
|
|
@@ -99,6 +108,11 @@ export interface BatchKeysResponse {
|
|
|
99
108
|
crv: string;
|
|
100
109
|
x: string;
|
|
101
110
|
};
|
|
111
|
+
pq_encryption_public_key?: {
|
|
112
|
+
kty: string;
|
|
113
|
+
alg: string;
|
|
114
|
+
x: string;
|
|
115
|
+
};
|
|
102
116
|
}>;
|
|
103
117
|
}
|
|
104
118
|
export interface WebhookRead {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { KeyPair } from "./keys.js";
|
|
2
|
+
declare const VERSION_HYBRID = 3;
|
|
3
|
+
declare const MLKEM_CT_SIZE = 1088;
|
|
4
|
+
export { VERSION_HYBRID, MLKEM_CT_SIZE };
|
|
5
|
+
/** Generate an ML-KEM-768 key pair for post-quantum key encapsulation. */
|
|
6
|
+
export declare function generatePqKeyPair(): KeyPair;
|
|
7
|
+
export declare function sealHybrid(recipientX25519Pk: Uint8Array, recipientMlKemPk: Uint8Array, innerEnvelope: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
|
|
8
|
+
export declare function openHybrid(recipientX25519Sk: Uint8Array, recipientMlKemSk: Uint8Array, encryptedPayload: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from "./hpke.js";
|
|
2
|
+
export * from "./hybrid.js";
|
|
2
3
|
export * from "./sign.js";
|
|
3
4
|
export * from "./envelope.js";
|
|
4
5
|
export * from "./keys.js";
|
|
@@ -6,3 +7,7 @@ export * from "./sender-keys.js";
|
|
|
6
7
|
export * from "./sender-keys-helpers.js";
|
|
7
8
|
export * from "./message.js";
|
|
8
9
|
export * from "./ingest.js";
|
|
10
|
+
export * from "./mls.js";
|
|
11
|
+
export * from "./mls-init.js";
|
|
12
|
+
export * from "./mls-api.js";
|
|
13
|
+
export * from "./mls-state.js";
|
|
@@ -4,6 +4,12 @@ export interface JWK {
|
|
|
4
4
|
x: string;
|
|
5
5
|
d?: string;
|
|
6
6
|
}
|
|
7
|
+
/** Public-key encoding for ML-KEM-768 (post-quantum). Not a standard OKP JWK. */
|
|
8
|
+
export interface PqJWK {
|
|
9
|
+
kty: string;
|
|
10
|
+
alg: string;
|
|
11
|
+
x: string;
|
|
12
|
+
}
|
|
7
13
|
export interface KeyPair {
|
|
8
14
|
privateKey: Uint8Array;
|
|
9
15
|
publicKey: Uint8Array;
|
|
@@ -11,6 +17,7 @@ export interface KeyPair {
|
|
|
11
17
|
export interface AgentKeys {
|
|
12
18
|
signing: KeyPair;
|
|
13
19
|
encryption: KeyPair;
|
|
20
|
+
pqEncryption?: KeyPair;
|
|
14
21
|
}
|
|
15
22
|
export declare function toBase64Url(bytes: Uint8Array): string;
|
|
16
23
|
export declare function fromBase64Url(s: string): Uint8Array;
|
|
@@ -20,9 +27,12 @@ export declare function generateAgentKeys(): AgentKeys;
|
|
|
20
27
|
export declare function signingPublicKeyToJWK(publicKey: Uint8Array): JWK;
|
|
21
28
|
export declare function encryptionPublicKeyToJWK(publicKey: Uint8Array): JWK;
|
|
22
29
|
export declare function jwkToPublicKey(jwk: JWK): Uint8Array;
|
|
30
|
+
export declare function pqPublicKeyToJWK(publicKey: Uint8Array): PqJWK;
|
|
31
|
+
export declare function jwkToPqPublicKey(jwk: PqJWK): Uint8Array;
|
|
23
32
|
export declare function agentIdFromKid(kid: string): string;
|
|
24
33
|
export declare function validatePathId(id: string, label: string): void;
|
|
25
34
|
export declare function saveAgentKeys(configDir: string, agentId: string, keys: AgentKeys): void;
|
|
35
|
+
export declare function savePqEncryptionKey(configDir: string, agentId: string, pqKeyPair: KeyPair): void;
|
|
26
36
|
export declare function loadAgentKeys(configDir: string, agentId: string): AgentKeys;
|
|
27
37
|
export declare function validateSigningKey(bytes: Uint8Array): void;
|
|
28
38
|
export declare function validateEncryptionKey(bytes: Uint8Array): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from "../http.js";
|
|
2
|
-
import { type AgentKeys } from "./keys.js";
|
|
2
|
+
import { type AgentKeys, type PqJWK, signingPublicKeyToJWK } from "./keys.js";
|
|
3
3
|
import { type SenderKeyState } from "./sender-keys.js";
|
|
4
4
|
export interface EncryptResult {
|
|
5
5
|
encrypted_payload: string;
|
|
@@ -13,19 +13,40 @@ export interface DecryptResult {
|
|
|
13
13
|
verified: boolean;
|
|
14
14
|
verificationStatus: VerificationStatus;
|
|
15
15
|
}
|
|
16
|
-
export declare function encryptMessage(configDir: string, senderAgentId: string, recipientEncryptionPk: Uint8Array, payload: unknown): Promise<EncryptResult>;
|
|
17
|
-
export
|
|
16
|
+
export declare function encryptMessage(configDir: string, senderAgentId: string, recipientEncryptionPk: Uint8Array, payload: unknown, recipientPqEncryptionPk?: Uint8Array): Promise<EncryptResult>;
|
|
17
|
+
export interface RecipientKeys {
|
|
18
|
+
encryption: Uint8Array;
|
|
19
|
+
pqEncryption?: Uint8Array;
|
|
20
|
+
}
|
|
21
|
+
/** Fetch a recipient's encryption keys, including the optional PQ key for hybrid mode. */
|
|
22
|
+
export declare function fetchRecipientKeys(client: HttpClient, agentId: string): Promise<RecipientKeys>;
|
|
18
23
|
export declare function decryptMessage(configDir: string, recipientAgentId: string, encryptedPayloadB64: string, client: HttpClient): Promise<DecryptResult>;
|
|
19
24
|
export declare function encryptGroupMessage(configDir: string, senderAgentId: string, groupId: string, senderKeyState: SenderKeyState, payload: unknown): Promise<{
|
|
20
25
|
result: EncryptResult;
|
|
21
26
|
updatedState: SenderKeyState;
|
|
22
27
|
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Encrypt a payload for an MLS-active group.
|
|
30
|
+
*
|
|
31
|
+
* Mirrors {@link encryptGroupMessage} but uses MLS instead of sender keys.
|
|
32
|
+
* The signed inner envelope (kid + Ed25519 signature + plaintext) is the MLS
|
|
33
|
+
* application-message payload, so {@link decryptGroupMessage}'s 0x04 branch can
|
|
34
|
+
* run `decodeEnvelope` + `verifyEnvelopeSender` unchanged. The MLS ciphertext is
|
|
35
|
+
* prefixed with {@link VERSION_MLS} (0x04) and base64url-encoded to match the
|
|
36
|
+
* version-byte dispatch in `decryptGroupMessage`.
|
|
37
|
+
*
|
|
38
|
+
* State is keyed by the rine group UUID (`groupId`), the same identifier used by
|
|
39
|
+
* `decryptGroupMessage` and the MLS API routes — never the opaque `mls_group_id`
|
|
40
|
+
* latch or the MLS-internal group id.
|
|
41
|
+
*/
|
|
42
|
+
export declare function encryptMlsGroupMessage(configDir: string, senderAgentId: string, groupId: string, payload: unknown): Promise<EncryptResult>;
|
|
23
43
|
export declare function decryptGroupMessage(configDir: string, recipientAgentId: string, groupId: string, encryptedPayloadB64: string, client: HttpClient): Promise<DecryptResult>;
|
|
24
44
|
export declare function getAgentPublicKeys(configDir: string, agentId: string, agentKeys?: AgentKeys): {
|
|
25
|
-
signing_public_key:
|
|
45
|
+
signing_public_key: ReturnType<typeof signingPublicKeyToJWK>;
|
|
26
46
|
encryption_public_key: {
|
|
27
47
|
kty: string;
|
|
28
48
|
crv: string;
|
|
29
49
|
x: string;
|
|
30
50
|
};
|
|
51
|
+
pq_encryption_public_key?: PqJWK;
|
|
31
52
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { HttpClient } from "../http.js";
|
|
2
|
+
declare function toBase64(bytes: Uint8Array): string;
|
|
3
|
+
declare function fromBase64(s: string): Uint8Array;
|
|
4
|
+
export { toBase64 as mlsToBase64, fromBase64 as mlsFromBase64 };
|
|
5
|
+
export interface MlsInitResponse {
|
|
6
|
+
mls_pending: boolean;
|
|
7
|
+
members: {
|
|
8
|
+
agent_id: string;
|
|
9
|
+
has_key_package: boolean;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export interface MlsCommitBody {
|
|
13
|
+
commit: string;
|
|
14
|
+
welcomes?: {
|
|
15
|
+
agent_id: string;
|
|
16
|
+
welcome: string;
|
|
17
|
+
}[];
|
|
18
|
+
group_info?: string;
|
|
19
|
+
cipher_suite?: number;
|
|
20
|
+
epoch?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface MlsCommitResponse {
|
|
23
|
+
epoch: number | null;
|
|
24
|
+
delivered_to: number;
|
|
25
|
+
confirmed?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface MlsAckResponse {
|
|
28
|
+
confirmed: boolean;
|
|
29
|
+
acks: number;
|
|
30
|
+
needed: number;
|
|
31
|
+
}
|
|
32
|
+
export interface MlsNackResponse {
|
|
33
|
+
quarantined: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface MlsHandshakeEntry {
|
|
36
|
+
id: string;
|
|
37
|
+
epoch: number | null;
|
|
38
|
+
blob: string;
|
|
39
|
+
created_at: string;
|
|
40
|
+
}
|
|
41
|
+
export interface MlsWelcomeEntry {
|
|
42
|
+
id: string;
|
|
43
|
+
group_id: string | null;
|
|
44
|
+
blob: string;
|
|
45
|
+
created_at: string;
|
|
46
|
+
}
|
|
47
|
+
export interface MlsProposalResponse {
|
|
48
|
+
id: string;
|
|
49
|
+
delivered_to: number;
|
|
50
|
+
}
|
|
51
|
+
export interface MlsGroupInfoResponse {
|
|
52
|
+
group_info: string | null;
|
|
53
|
+
epoch: number | null;
|
|
54
|
+
}
|
|
55
|
+
export declare function uploadKeyPackages(client: HttpClient, agentId: string, packages: string[]): Promise<{
|
|
56
|
+
stored: number;
|
|
57
|
+
}>;
|
|
58
|
+
export declare function claimKeyPackages(client: HttpClient, agentId: string, count?: number): Promise<{
|
|
59
|
+
packages: string[];
|
|
60
|
+
agent_id: string;
|
|
61
|
+
}>;
|
|
62
|
+
export declare function mlsInit(client: HttpClient, groupId: string, extraHeaders?: Record<string, string>): Promise<MlsInitResponse>;
|
|
63
|
+
export declare function mlsCommit(client: HttpClient, groupId: string, body: MlsCommitBody, extraHeaders?: Record<string, string>): Promise<MlsCommitResponse>;
|
|
64
|
+
/**
|
|
65
|
+
* ACK a handshake the local client processed cleanly (H4). Once MLS_ACK_QUORUM
|
|
66
|
+
* distinct clean ACKs land server-side, the tentative commit + its GroupInfo are
|
|
67
|
+
* confirmed and mls_confirmed_epoch advances. extraHeaders is threaded so a
|
|
68
|
+
* multi-agent client ACKs as the right acting agent (sibling /groups bug: do not
|
|
69
|
+
* drop extraHeaders here).
|
|
70
|
+
*/
|
|
71
|
+
export declare function mlsAck(client: HttpClient, groupId: string, body: {
|
|
72
|
+
object_id: string;
|
|
73
|
+
}, extraHeaders?: Record<string, string>): Promise<MlsAckResponse>;
|
|
74
|
+
/**
|
|
75
|
+
* NACK a handshake the local client could NOT process (H4). The server marks the
|
|
76
|
+
* delivery and lazily rolls the tentative commit back. A NACK is non-destructive:
|
|
77
|
+
* it only ever un-advances unconfirmed, never-served state. extraHeaders threaded.
|
|
78
|
+
*/
|
|
79
|
+
export declare function mlsNack(client: HttpClient, groupId: string, body: {
|
|
80
|
+
object_id: string;
|
|
81
|
+
epoch: number;
|
|
82
|
+
reason?: string;
|
|
83
|
+
}, extraHeaders?: Record<string, string>): Promise<MlsNackResponse>;
|
|
84
|
+
export declare function fetchHandshakes(client: HttpClient, groupId: string, sinceEpoch?: number, extraHeaders?: Record<string, string>): Promise<{
|
|
85
|
+
handshakes: MlsHandshakeEntry[];
|
|
86
|
+
}>;
|
|
87
|
+
export declare function fetchWelcomes(client: HttpClient, agentId: string): Promise<{
|
|
88
|
+
welcomes: MlsWelcomeEntry[];
|
|
89
|
+
}>;
|
|
90
|
+
export declare function fetchGroupInfo(client: HttpClient, groupId: string, extraHeaders?: Record<string, string>): Promise<MlsGroupInfoResponse>;
|
|
91
|
+
export declare function submitProposal(client: HttpClient, groupId: string, proposal: string, extraHeaders?: Record<string, string>): Promise<MlsProposalResponse>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CiphersuiteImpl, type MlsContext } from "ts-mls";
|
|
2
|
+
/** Lazily initializes and returns the MLS cipher suite singleton. */
|
|
3
|
+
export declare function getMlsCipherSuite(): Promise<CiphersuiteImpl>;
|
|
4
|
+
/** Lazily initializes and returns the MLS context singleton. */
|
|
5
|
+
export declare function getMlsContext(): Promise<MlsContext>;
|
|
6
|
+
export declare const MLS_CIPHER_SUITE_ID = 1;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface MlsEpochMetadata {
|
|
2
|
+
groupId: string;
|
|
3
|
+
epoch: number;
|
|
4
|
+
cipherSuite: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function saveMlsState(configDir: string, agentId: string, groupId: string, stateBlob: Uint8Array, metadata: MlsEpochMetadata): void;
|
|
7
|
+
export declare function loadMlsState(configDir: string, agentId: string, groupId: string): {
|
|
8
|
+
stateBlob: Uint8Array;
|
|
9
|
+
metadata: MlsEpochMetadata;
|
|
10
|
+
} | null;
|
|
11
|
+
export declare function deleteMlsState(configDir: string, agentId: string, groupId: string): void;
|
|
12
|
+
export declare function cacheMlsSelfRead(configDir: string, agentId: string, groupId: string, encryptedPayload: string, envelope: Uint8Array): void;
|
|
13
|
+
export declare function lookupMlsSelfRead(configDir: string, agentId: string, groupId: string, encryptedPayload: string): Uint8Array | null;
|
|
14
|
+
export interface StoredKeyPackage {
|
|
15
|
+
ref: string;
|
|
16
|
+
publicBlob: Uint8Array;
|
|
17
|
+
privateBlob: Uint8Array;
|
|
18
|
+
}
|
|
19
|
+
export declare function savePrivateKeyPackages(configDir: string, agentId: string, packages: Array<{
|
|
20
|
+
ref: Uint8Array;
|
|
21
|
+
publicBlob: Uint8Array;
|
|
22
|
+
privateBlob: Uint8Array;
|
|
23
|
+
}>): void;
|
|
24
|
+
export declare function loadPrivateKeyPackage(configDir: string, agentId: string, ref: Uint8Array): {
|
|
25
|
+
publicBlob: Uint8Array;
|
|
26
|
+
privateBlob: Uint8Array;
|
|
27
|
+
} | null;
|
|
28
|
+
export declare function deletePrivateKeyPackage(configDir: string, agentId: string, ref: Uint8Array): void;
|
|
29
|
+
export declare function listPrivateKeyPackages(configDir: string, agentId: string): StoredKeyPackage[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const VERSION_MLS = 4;
|
|
2
|
+
export interface MlsGroupState {
|
|
3
|
+
groupId: string;
|
|
4
|
+
epoch: number;
|
|
5
|
+
cipherSuite: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function generateMlsKeyPackage(signingKey: Uint8Array): Promise<{
|
|
8
|
+
publicBlob: Uint8Array;
|
|
9
|
+
privateBlob: Uint8Array;
|
|
10
|
+
keyPackageRef: Uint8Array;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function createMlsGroup(signingKey: Uint8Array, _cipherSuite?: number): Promise<{
|
|
13
|
+
stateBlob: Uint8Array;
|
|
14
|
+
groupInfo: Uint8Array;
|
|
15
|
+
commitBlob: Uint8Array;
|
|
16
|
+
epoch: number;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function addMemberToMlsGroup(stateBlob: Uint8Array, keyPackageBlob: Uint8Array): Promise<{
|
|
19
|
+
commitBlob: Uint8Array;
|
|
20
|
+
welcomeBlob: Uint8Array;
|
|
21
|
+
updatedState: Uint8Array;
|
|
22
|
+
groupInfo: Uint8Array;
|
|
23
|
+
epoch: number;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function removeMemberFromMlsGroup(stateBlob: Uint8Array, leafIndex: number): Promise<{
|
|
26
|
+
commitBlob: Uint8Array;
|
|
27
|
+
updatedState: Uint8Array;
|
|
28
|
+
groupInfo: Uint8Array;
|
|
29
|
+
epoch: number;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function processMlsWelcome(welcomeBlob: Uint8Array, keyPackageBlob: Uint8Array, privateKeyBlob: Uint8Array): Promise<{
|
|
32
|
+
stateBlob: Uint8Array;
|
|
33
|
+
groupId: string;
|
|
34
|
+
epoch: number;
|
|
35
|
+
cipherSuite: number;
|
|
36
|
+
}>;
|
|
37
|
+
export declare function processMlsCommit(stateBlob: Uint8Array, commitBlob: Uint8Array): Promise<{
|
|
38
|
+
updatedState: Uint8Array;
|
|
39
|
+
epoch: number;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Self-join an MLS group via an RFC 9420 external commit (no Welcome required).
|
|
43
|
+
* The joiner mints a fresh KeyPackage with its own Ed25519 signing key, derives
|
|
44
|
+
* a fresh init_secret against the published GroupInfo's external_pub, and emits
|
|
45
|
+
* a public External Commit that existing members process to advance the epoch.
|
|
46
|
+
* Returns the public commit (to broadcast), the joiner's new state, a fresh
|
|
47
|
+
* GroupInfo (so the NEXT external joiner has a current-epoch token), and the new
|
|
48
|
+
* epoch. `resync: false` — the joiner is a brand-new member, not in the tree.
|
|
49
|
+
*/
|
|
50
|
+
export declare function externalJoinMlsGroup(signingKey: Uint8Array, groupInfoBlob: Uint8Array): Promise<{
|
|
51
|
+
commitBlob: Uint8Array;
|
|
52
|
+
stateBlob: Uint8Array;
|
|
53
|
+
groupInfo: Uint8Array;
|
|
54
|
+
epoch: number;
|
|
55
|
+
}>;
|
|
56
|
+
export declare function encryptMlsAppMessage(stateBlob: Uint8Array, plaintext: Uint8Array): Promise<{
|
|
57
|
+
ciphertext: Uint8Array;
|
|
58
|
+
updatedState: Uint8Array;
|
|
59
|
+
}>;
|
|
60
|
+
export declare function decryptMlsAppMessage(stateBlob: Uint8Array, ciphertext: Uint8Array): Promise<{
|
|
61
|
+
plaintext: Uint8Array;
|
|
62
|
+
updatedState: Uint8Array;
|
|
63
|
+
}>;
|
package/dist/src/errors.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare class RineApiError extends Error {
|
|
|
2
2
|
readonly status: number;
|
|
3
3
|
readonly detail: string;
|
|
4
4
|
readonly raw?: unknown | undefined;
|
|
5
|
-
|
|
5
|
+
readonly code?: string | undefined;
|
|
6
|
+
constructor(status: number, detail: string, raw?: unknown | undefined, code?: string | undefined);
|
|
6
7
|
}
|
|
7
8
|
export declare function formatError(err: unknown): string;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -8,4 +8,6 @@ export * from "./resolve-agent.js";
|
|
|
8
8
|
export * from "./timelock.js";
|
|
9
9
|
export * from "./sender-key-ops.js";
|
|
10
10
|
export * from "./crypto/index.js";
|
|
11
|
+
export * from "./mls-ops.js";
|
|
12
|
+
export { externalJoinMlsGroup } from "./mls-ops.js";
|
|
11
13
|
export { performRegistration, performAgentCreation, validateSlug } from "./onboard.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HttpClient } from "./http.js";
|
|
2
|
+
/**
|
|
3
|
+
* Self-join an MLS-active group via an RFC 9420 external commit (Phase 6).
|
|
4
|
+
*
|
|
5
|
+
* Used for OPEN enrollment, where the rine server adds a joiner to the group
|
|
6
|
+
* with no member in the loop — so nobody mints a Welcome and the joiner is a
|
|
7
|
+
* rine member but not yet an MLS member. The joiner fetches the group's latest
|
|
8
|
+
* published GroupInfo, derives a fresh init_secret against its external_pub,
|
|
9
|
+
* and posts a public External Commit that existing members process (via the
|
|
10
|
+
* EXISTING syncMlsGroup path) to advance the epoch.
|
|
11
|
+
*
|
|
12
|
+
* State is keyed by the RINE group UUID (groupId) — the same key
|
|
13
|
+
* encrypt/decryptGroupMessage use — so the joiner can immediately send/receive.
|
|
14
|
+
*
|
|
15
|
+
* Epoch-conflict handling (research-guided, RFC 9420 §12.4.3.2 + RFC 9750):
|
|
16
|
+
* a GroupInfo is single-use per epoch. If a competing external join lands first,
|
|
17
|
+
* our GroupInfo is stale and our commit targets a stale epoch (members reject).
|
|
18
|
+
* We do a single discard-and-rebuild retry against a freshly-fetched GroupInfo;
|
|
19
|
+
* on a second failure we surface a clear, actionable terminal error rather than
|
|
20
|
+
* looping (an unbounded retry against an advancing epoch is a self-DoS).
|
|
21
|
+
*/
|
|
22
|
+
export declare function externalJoinMlsGroup(configDir: string, agentId: string, groupId: string, client: HttpClient, extraHeaders?: Record<string, string>): Promise<{
|
|
23
|
+
epoch: number;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HttpClient } from "./http.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fetch all pending MLS welcomes for an agent and process them, establishing
|
|
4
|
+
* local group state for each group the agent has been added to.
|
|
5
|
+
*/
|
|
6
|
+
export declare function processMlsWelcomes(configDir: string, agentId: string, client: HttpClient): Promise<{
|
|
7
|
+
processed: number;
|
|
8
|
+
groupIds: string[];
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Remove a member from an MLS group by leaf index and post the remove commit.
|
|
12
|
+
*/
|
|
13
|
+
export declare function removeMlsGroupMember(configDir: string, agentId: string, groupId: string, leafIndex: number, client: HttpClient, extraHeaders?: Record<string, string>): Promise<{
|
|
14
|
+
epoch: number;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Sync local MLS group state by fetching and applying all commits posted
|
|
18
|
+
* since the current epoch.
|
|
19
|
+
*/
|
|
20
|
+
export declare function syncMlsGroup(configDir: string, agentId: string, groupId: string, client: HttpClient, extraHeaders?: Record<string, string>): Promise<{
|
|
21
|
+
epoch: number;
|
|
22
|
+
processed: number;
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HttpClient } from "./http.js";
|
|
2
|
+
export { processMlsWelcomes, removeMlsGroupMember, syncMlsGroup } from "./mls-ops-sync.js";
|
|
3
|
+
export { externalJoinMlsGroup } from "./mls-ops-join.js";
|
|
4
|
+
/**
|
|
5
|
+
* Generate and upload MLS key packages for an agent, enabling other agents
|
|
6
|
+
* to add them to MLS groups.
|
|
7
|
+
*/
|
|
8
|
+
export declare function publishMlsKeyPackages(configDir: string, agentId: string, client: HttpClient, count?: number): Promise<{
|
|
9
|
+
stored: number;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Initialize an MLS group: create the group state, add all members who have
|
|
13
|
+
* uploaded key packages, and post the initial commit + welcomes to the server.
|
|
14
|
+
*/
|
|
15
|
+
export declare function initMlsGroup(configDir: string, agentId: string, groupId: string, client: HttpClient, extraHeaders?: Record<string, string>): Promise<{
|
|
16
|
+
epoch: number;
|
|
17
|
+
membersAdded: number;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Add a single member to an existing MLS group by claiming their key package
|
|
21
|
+
* and posting an add commit + welcome.
|
|
22
|
+
*/
|
|
23
|
+
export declare function addMlsGroupMember(configDir: string, agentId: string, groupId: string, memberAgentId: string, client: HttpClient, extraHeaders?: Record<string, string>): Promise<{
|
|
24
|
+
epoch: number;
|
|
25
|
+
}>;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rine-network/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Core library for rine.network — crypto, HTTP, config, agent resolution",
|
|
5
5
|
"author": "mmmbs <mmmbs@proton.me>",
|
|
6
6
|
"license": "EUPL-1.2",
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
"@hpke/core": "^1.9.0",
|
|
28
28
|
"@hpke/dhkem-x25519": "^1.8.0",
|
|
29
29
|
"@noble/curves": "^2.0.1",
|
|
30
|
-
"@noble/hashes": "^2.0.1"
|
|
30
|
+
"@noble/hashes": "^2.0.1",
|
|
31
|
+
"@noble/post-quantum": "^0.6.1",
|
|
32
|
+
"ts-mls": "^2.0.0-rc.13"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"@biomejs/biome": "^1.9.0",
|