quicksave-shared 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/LICENSE +21 -0
- package/dist/crypto.d.ts +103 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +239 -0
- package/dist/crypto.js.map +1 -0
- package/dist/crypto.test.d.ts +2 -0
- package/dist/crypto.test.d.ts.map +1 -0
- package/dist/crypto.test.js +246 -0
- package/dist/crypto.test.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +37 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +74 -0
- package/dist/protocol.js.map +1 -0
- package/dist/protocol.test.d.ts +2 -0
- package/dist/protocol.test.d.ts.map +1 -0
- package/dist/protocol.test.js +155 -0
- package/dist/protocol.test.js.map +1 -0
- package/dist/types.d.ts +242 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
- package/src/crypto.test.ts +337 -0
- package/src/crypto.ts +335 -0
- package/src/index.ts +8 -0
- package/src/protocol.test.ts +197 -0
- package/src/protocol.ts +92 -0
- package/src/types.ts +400 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +9 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Quicksave, KingYoung Technology
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { License } from './types.js';
|
|
2
|
+
declare const encodeBase64: (arr: Uint8Array) => string, decodeBase64: (s: string) => Uint8Array, encodeUTF8: (arr: Uint8Array) => string, decodeUTF8: (s: string) => Uint8Array;
|
|
3
|
+
export interface KeyPair {
|
|
4
|
+
publicKey: Uint8Array;
|
|
5
|
+
secretKey: Uint8Array;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generate a new X25519 key pair for encryption
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateKeyPair(): KeyPair;
|
|
11
|
+
/**
|
|
12
|
+
* Generate a new Ed25519 key pair for signing
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateSigningKeyPair(): KeyPair;
|
|
15
|
+
/**
|
|
16
|
+
* Encrypt a message using X25519 + XSalsa20-Poly1305
|
|
17
|
+
* @param message - The plaintext message
|
|
18
|
+
* @param theirPublicKey - Recipient's public key
|
|
19
|
+
* @param mySecretKey - Sender's secret key
|
|
20
|
+
* @returns Base64 encoded encrypted message (nonce + ciphertext)
|
|
21
|
+
*/
|
|
22
|
+
export declare function encrypt(message: string, theirPublicKey: Uint8Array, mySecretKey: Uint8Array): string;
|
|
23
|
+
/**
|
|
24
|
+
* Decrypt a message using X25519 + XSalsa20-Poly1305
|
|
25
|
+
* @param encryptedMessage - Base64 encoded encrypted message (nonce + ciphertext)
|
|
26
|
+
* @param theirPublicKey - Sender's public key
|
|
27
|
+
* @param mySecretKey - Recipient's secret key
|
|
28
|
+
* @returns Decrypted plaintext message
|
|
29
|
+
*/
|
|
30
|
+
export declare function decrypt(encryptedMessage: string, theirPublicKey: Uint8Array, mySecretKey: Uint8Array): string;
|
|
31
|
+
/**
|
|
32
|
+
* Derive a shared secret from key pairs (X25519)
|
|
33
|
+
*/
|
|
34
|
+
export declare function deriveSharedSecret(theirPublicKey: Uint8Array, mySecretKey: Uint8Array): Uint8Array;
|
|
35
|
+
/**
|
|
36
|
+
* Encrypt using a pre-computed shared secret (faster for multiple messages)
|
|
37
|
+
*/
|
|
38
|
+
export declare function encryptWithSharedSecret(message: string, sharedSecret: Uint8Array): string;
|
|
39
|
+
/**
|
|
40
|
+
* Decrypt using a pre-computed shared secret
|
|
41
|
+
*/
|
|
42
|
+
export declare function decryptWithSharedSecret(encryptedMessage: string, sharedSecret: Uint8Array): string;
|
|
43
|
+
/**
|
|
44
|
+
* Generate a random 32-byte session DEK for symmetric encryption.
|
|
45
|
+
* Used in V2 key exchange where PWA generates the DEK and sends it encrypted to Agent.
|
|
46
|
+
*/
|
|
47
|
+
export declare function generateSessionDEK(): Uint8Array;
|
|
48
|
+
/**
|
|
49
|
+
* Encrypt a DEK for a specific recipient using sealed box pattern.
|
|
50
|
+
* Uses an ephemeral keypair so the sender's identity is not revealed.
|
|
51
|
+
*
|
|
52
|
+
* Format: ephemeralPublicKey (32) + nonce (24) + ciphertext
|
|
53
|
+
*
|
|
54
|
+
* @param dek - The 32-byte DEK to encrypt
|
|
55
|
+
* @param recipientPublicKey - Recipient's X25519 public key
|
|
56
|
+
* @returns Base64 encoded encrypted DEK
|
|
57
|
+
*/
|
|
58
|
+
export declare function encryptDEK(dek: Uint8Array, recipientPublicKey: Uint8Array): string;
|
|
59
|
+
/**
|
|
60
|
+
* Decrypt a DEK that was encrypted for us.
|
|
61
|
+
*
|
|
62
|
+
* @param encryptedDEK - Base64 encoded encrypted DEK (ephemeralPubKey + nonce + ciphertext)
|
|
63
|
+
* @param mySecretKey - Our X25519 secret key
|
|
64
|
+
* @returns The decrypted 32-byte DEK
|
|
65
|
+
*/
|
|
66
|
+
export declare function decryptDEK(encryptedDEK: string, mySecretKey: Uint8Array): Uint8Array;
|
|
67
|
+
/**
|
|
68
|
+
* Sign a message using Ed25519
|
|
69
|
+
*/
|
|
70
|
+
export declare function sign(message: string, secretKey: Uint8Array): string;
|
|
71
|
+
/**
|
|
72
|
+
* Verify an Ed25519 signature
|
|
73
|
+
*/
|
|
74
|
+
export declare function verify(message: string, signature: string, publicKey: Uint8Array): boolean;
|
|
75
|
+
export declare function getQuicksavePublicKey(): Uint8Array;
|
|
76
|
+
/**
|
|
77
|
+
* Verify a license certificate
|
|
78
|
+
*/
|
|
79
|
+
export declare function verifyLicense(license: License): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Create a license certificate (server-side only)
|
|
82
|
+
*/
|
|
83
|
+
export declare function createLicense(userPublicKey: string, signingSecretKey: Uint8Array): License;
|
|
84
|
+
/**
|
|
85
|
+
* Encode a key pair to base64 strings for storage
|
|
86
|
+
*/
|
|
87
|
+
export declare function encodeKeyPair(keyPair: KeyPair): {
|
|
88
|
+
publicKey: string;
|
|
89
|
+
secretKey: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Decode base64 strings back to a key pair
|
|
93
|
+
*/
|
|
94
|
+
export declare function decodeKeyPair(encoded: {
|
|
95
|
+
publicKey: string;
|
|
96
|
+
secretKey: string;
|
|
97
|
+
}): KeyPair;
|
|
98
|
+
/**
|
|
99
|
+
* Generate a random agent ID (used for signaling)
|
|
100
|
+
*/
|
|
101
|
+
export declare function generateAgentId(): string;
|
|
102
|
+
export { encodeBase64, decodeBase64, encodeUTF8, decodeUTF8 };
|
|
103
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,QAAA,MAAQ,YAAY,+BAAE,YAAY,6BAAE,UAAU,+BAAE,UAAU,2BAAa,CAAC;AAMxE,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAMD;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,GACtB,MAAM,CAgBR;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,GACtB,MAAM,CAaR;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,GACtB,UAAU,CAEZ;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,UAAU,GACvB,MAAM,CAeR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,UAAU,GACvB,MAAM,CAaR;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,kBAAkB,EAAE,UAAU,GAC7B,MAAM,CAwBR;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,UAAU,GACtB,UAAU,CAmBZ;AAMD;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,MAAM,CAInE;AAED;;GAEG;AACH,wBAAgB,MAAM,CACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,UAAU,GACpB,OAAO,CAIT;AAWD,wBAAgB,qBAAqB,IAAI,UAAU,CAElD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAGvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,UAAU,GAC3B,OAAO,CAeT;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAKxF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAKxF;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAGD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import nacl from 'tweetnacl';
|
|
2
|
+
import naclUtil from 'tweetnacl-util';
|
|
3
|
+
const { encodeBase64, decodeBase64, encodeUTF8, decodeUTF8 } = naclUtil;
|
|
4
|
+
/**
|
|
5
|
+
* Generate a new X25519 key pair for encryption
|
|
6
|
+
*/
|
|
7
|
+
export function generateKeyPair() {
|
|
8
|
+
return nacl.box.keyPair();
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generate a new Ed25519 key pair for signing
|
|
12
|
+
*/
|
|
13
|
+
export function generateSigningKeyPair() {
|
|
14
|
+
return nacl.sign.keyPair();
|
|
15
|
+
}
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Encryption / Decryption
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Encrypt a message using X25519 + XSalsa20-Poly1305
|
|
21
|
+
* @param message - The plaintext message
|
|
22
|
+
* @param theirPublicKey - Recipient's public key
|
|
23
|
+
* @param mySecretKey - Sender's secret key
|
|
24
|
+
* @returns Base64 encoded encrypted message (nonce + ciphertext)
|
|
25
|
+
*/
|
|
26
|
+
export function encrypt(message, theirPublicKey, mySecretKey) {
|
|
27
|
+
const nonce = nacl.randomBytes(nacl.box.nonceLength);
|
|
28
|
+
const messageBytes = decodeUTF8(message);
|
|
29
|
+
const encrypted = nacl.box(messageBytes, nonce, theirPublicKey, mySecretKey);
|
|
30
|
+
if (!encrypted) {
|
|
31
|
+
throw new Error('Encryption failed');
|
|
32
|
+
}
|
|
33
|
+
// Combine nonce + ciphertext
|
|
34
|
+
const combined = new Uint8Array(nonce.length + encrypted.length);
|
|
35
|
+
combined.set(nonce);
|
|
36
|
+
combined.set(encrypted, nonce.length);
|
|
37
|
+
return encodeBase64(combined);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Decrypt a message using X25519 + XSalsa20-Poly1305
|
|
41
|
+
* @param encryptedMessage - Base64 encoded encrypted message (nonce + ciphertext)
|
|
42
|
+
* @param theirPublicKey - Sender's public key
|
|
43
|
+
* @param mySecretKey - Recipient's secret key
|
|
44
|
+
* @returns Decrypted plaintext message
|
|
45
|
+
*/
|
|
46
|
+
export function decrypt(encryptedMessage, theirPublicKey, mySecretKey) {
|
|
47
|
+
const combined = decodeBase64(encryptedMessage);
|
|
48
|
+
const nonce = combined.slice(0, nacl.box.nonceLength);
|
|
49
|
+
const ciphertext = combined.slice(nacl.box.nonceLength);
|
|
50
|
+
const decrypted = nacl.box.open(ciphertext, nonce, theirPublicKey, mySecretKey);
|
|
51
|
+
if (!decrypted) {
|
|
52
|
+
throw new Error('Decryption failed - invalid message or wrong key');
|
|
53
|
+
}
|
|
54
|
+
return encodeUTF8(decrypted);
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Shared Secret (for symmetric encryption)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Derive a shared secret from key pairs (X25519)
|
|
61
|
+
*/
|
|
62
|
+
export function deriveSharedSecret(theirPublicKey, mySecretKey) {
|
|
63
|
+
return nacl.box.before(theirPublicKey, mySecretKey);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Encrypt using a pre-computed shared secret (faster for multiple messages)
|
|
67
|
+
*/
|
|
68
|
+
export function encryptWithSharedSecret(message, sharedSecret) {
|
|
69
|
+
const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
|
|
70
|
+
const messageBytes = decodeUTF8(message);
|
|
71
|
+
const encrypted = nacl.secretbox(messageBytes, nonce, sharedSecret);
|
|
72
|
+
if (!encrypted) {
|
|
73
|
+
throw new Error('Encryption failed');
|
|
74
|
+
}
|
|
75
|
+
const combined = new Uint8Array(nonce.length + encrypted.length);
|
|
76
|
+
combined.set(nonce);
|
|
77
|
+
combined.set(encrypted, nonce.length);
|
|
78
|
+
return encodeBase64(combined);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Decrypt using a pre-computed shared secret
|
|
82
|
+
*/
|
|
83
|
+
export function decryptWithSharedSecret(encryptedMessage, sharedSecret) {
|
|
84
|
+
const combined = decodeBase64(encryptedMessage);
|
|
85
|
+
const nonce = combined.slice(0, nacl.secretbox.nonceLength);
|
|
86
|
+
const ciphertext = combined.slice(nacl.secretbox.nonceLength);
|
|
87
|
+
const decrypted = nacl.secretbox.open(ciphertext, nonce, sharedSecret);
|
|
88
|
+
if (!decrypted) {
|
|
89
|
+
throw new Error('Decryption failed - invalid message or wrong key');
|
|
90
|
+
}
|
|
91
|
+
return encodeUTF8(decrypted);
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Session DEK (Data Encryption Key) - V2 Protocol
|
|
95
|
+
// ============================================================================
|
|
96
|
+
/**
|
|
97
|
+
* Generate a random 32-byte session DEK for symmetric encryption.
|
|
98
|
+
* Used in V2 key exchange where PWA generates the DEK and sends it encrypted to Agent.
|
|
99
|
+
*/
|
|
100
|
+
export function generateSessionDEK() {
|
|
101
|
+
return nacl.randomBytes(32);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Encrypt a DEK for a specific recipient using sealed box pattern.
|
|
105
|
+
* Uses an ephemeral keypair so the sender's identity is not revealed.
|
|
106
|
+
*
|
|
107
|
+
* Format: ephemeralPublicKey (32) + nonce (24) + ciphertext
|
|
108
|
+
*
|
|
109
|
+
* @param dek - The 32-byte DEK to encrypt
|
|
110
|
+
* @param recipientPublicKey - Recipient's X25519 public key
|
|
111
|
+
* @returns Base64 encoded encrypted DEK
|
|
112
|
+
*/
|
|
113
|
+
export function encryptDEK(dek, recipientPublicKey) {
|
|
114
|
+
if (dek.length !== 32) {
|
|
115
|
+
throw new Error('DEK must be 32 bytes');
|
|
116
|
+
}
|
|
117
|
+
// Generate ephemeral keypair for this encryption
|
|
118
|
+
const ephemeral = nacl.box.keyPair();
|
|
119
|
+
const nonce = nacl.randomBytes(nacl.box.nonceLength);
|
|
120
|
+
const encrypted = nacl.box(dek, nonce, recipientPublicKey, ephemeral.secretKey);
|
|
121
|
+
if (!encrypted) {
|
|
122
|
+
throw new Error('DEK encryption failed');
|
|
123
|
+
}
|
|
124
|
+
// Combine: ephemeralPublicKey + nonce + ciphertext
|
|
125
|
+
const combined = new Uint8Array(ephemeral.publicKey.length + nonce.length + encrypted.length);
|
|
126
|
+
combined.set(ephemeral.publicKey);
|
|
127
|
+
combined.set(nonce, ephemeral.publicKey.length);
|
|
128
|
+
combined.set(encrypted, ephemeral.publicKey.length + nonce.length);
|
|
129
|
+
return encodeBase64(combined);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Decrypt a DEK that was encrypted for us.
|
|
133
|
+
*
|
|
134
|
+
* @param encryptedDEK - Base64 encoded encrypted DEK (ephemeralPubKey + nonce + ciphertext)
|
|
135
|
+
* @param mySecretKey - Our X25519 secret key
|
|
136
|
+
* @returns The decrypted 32-byte DEK
|
|
137
|
+
*/
|
|
138
|
+
export function decryptDEK(encryptedDEK, mySecretKey) {
|
|
139
|
+
const combined = decodeBase64(encryptedDEK);
|
|
140
|
+
// Extract components
|
|
141
|
+
const ephemeralPublicKey = combined.slice(0, 32);
|
|
142
|
+
const nonce = combined.slice(32, 32 + nacl.box.nonceLength);
|
|
143
|
+
const ciphertext = combined.slice(32 + nacl.box.nonceLength);
|
|
144
|
+
const decrypted = nacl.box.open(ciphertext, nonce, ephemeralPublicKey, mySecretKey);
|
|
145
|
+
if (!decrypted) {
|
|
146
|
+
throw new Error('DEK decryption failed - invalid message or wrong key');
|
|
147
|
+
}
|
|
148
|
+
if (decrypted.length !== 32) {
|
|
149
|
+
throw new Error('Decrypted DEK has invalid length');
|
|
150
|
+
}
|
|
151
|
+
return decrypted;
|
|
152
|
+
}
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Signing / Verification
|
|
155
|
+
// ============================================================================
|
|
156
|
+
/**
|
|
157
|
+
* Sign a message using Ed25519
|
|
158
|
+
*/
|
|
159
|
+
export function sign(message, secretKey) {
|
|
160
|
+
const messageBytes = decodeUTF8(message);
|
|
161
|
+
const signature = nacl.sign.detached(messageBytes, secretKey);
|
|
162
|
+
return encodeBase64(signature);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Verify an Ed25519 signature
|
|
166
|
+
*/
|
|
167
|
+
export function verify(message, signature, publicKey) {
|
|
168
|
+
const messageBytes = decodeUTF8(message);
|
|
169
|
+
const signatureBytes = decodeBase64(signature);
|
|
170
|
+
return nacl.sign.detached.verify(messageBytes, signatureBytes, publicKey);
|
|
171
|
+
}
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// License Verification
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// Quicksave's public key for license verification (Ed25519)
|
|
176
|
+
// This would be generated once and hardcoded
|
|
177
|
+
// For development, we'll generate a placeholder
|
|
178
|
+
const QUICKSAVE_PUBLIC_KEY_BASE64 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
|
|
179
|
+
export function getQuicksavePublicKey() {
|
|
180
|
+
return decodeBase64(QUICKSAVE_PUBLIC_KEY_BASE64);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Verify a license certificate
|
|
184
|
+
*/
|
|
185
|
+
export function verifyLicense(license) {
|
|
186
|
+
const message = `${license.version}:${license.publicKey}:${license.issuedAt}:${license.type}`;
|
|
187
|
+
return verify(message, license.signature, getQuicksavePublicKey());
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Create a license certificate (server-side only)
|
|
191
|
+
*/
|
|
192
|
+
export function createLicense(userPublicKey, signingSecretKey) {
|
|
193
|
+
const license = {
|
|
194
|
+
version: 1,
|
|
195
|
+
publicKey: userPublicKey,
|
|
196
|
+
issuedAt: Date.now(),
|
|
197
|
+
type: 'pro',
|
|
198
|
+
};
|
|
199
|
+
const message = `${license.version}:${license.publicKey}:${license.issuedAt}:${license.type}`;
|
|
200
|
+
const signature = sign(message, signingSecretKey);
|
|
201
|
+
return {
|
|
202
|
+
...license,
|
|
203
|
+
signature,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// ============================================================================
|
|
207
|
+
// Utility Functions
|
|
208
|
+
// ============================================================================
|
|
209
|
+
/**
|
|
210
|
+
* Encode a key pair to base64 strings for storage
|
|
211
|
+
*/
|
|
212
|
+
export function encodeKeyPair(keyPair) {
|
|
213
|
+
return {
|
|
214
|
+
publicKey: encodeBase64(keyPair.publicKey),
|
|
215
|
+
secretKey: encodeBase64(keyPair.secretKey),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Decode base64 strings back to a key pair
|
|
220
|
+
*/
|
|
221
|
+
export function decodeKeyPair(encoded) {
|
|
222
|
+
return {
|
|
223
|
+
publicKey: decodeBase64(encoded.publicKey),
|
|
224
|
+
secretKey: decodeBase64(encoded.secretKey),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Generate a random agent ID (used for signaling)
|
|
229
|
+
*/
|
|
230
|
+
export function generateAgentId() {
|
|
231
|
+
const bytes = nacl.randomBytes(16);
|
|
232
|
+
return encodeBase64(bytes)
|
|
233
|
+
.replace(/\+/g, '-')
|
|
234
|
+
.replace(/\//g, '_')
|
|
235
|
+
.replace(/=/g, '');
|
|
236
|
+
}
|
|
237
|
+
// Re-export encoding utilities
|
|
238
|
+
export { encodeBase64, decodeBase64, encodeUTF8, decodeUTF8 };
|
|
239
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.test.d.ts","sourceRoot":"","sources":["../src/crypto.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { generateKeyPair, generateSigningKeyPair, encrypt, decrypt, deriveSharedSecret, encryptWithSharedSecret, decryptWithSharedSecret, generateSessionDEK, encryptDEK, decryptDEK, sign, verify, encodeKeyPair, decodeKeyPair, generateAgentId, encodeBase64, decodeBase64, } from './crypto.js';
|
|
3
|
+
describe('Key Generation', () => {
|
|
4
|
+
it('should generate valid encryption key pair', () => {
|
|
5
|
+
const keyPair = generateKeyPair();
|
|
6
|
+
expect(keyPair.publicKey).toBeInstanceOf(Uint8Array);
|
|
7
|
+
expect(keyPair.secretKey).toBeInstanceOf(Uint8Array);
|
|
8
|
+
expect(keyPair.publicKey.length).toBe(32);
|
|
9
|
+
expect(keyPair.secretKey.length).toBe(32);
|
|
10
|
+
});
|
|
11
|
+
it('should generate unique key pairs each time', () => {
|
|
12
|
+
const keyPair1 = generateKeyPair();
|
|
13
|
+
const keyPair2 = generateKeyPair();
|
|
14
|
+
expect(encodeBase64(keyPair1.publicKey)).not.toBe(encodeBase64(keyPair2.publicKey));
|
|
15
|
+
expect(encodeBase64(keyPair1.secretKey)).not.toBe(encodeBase64(keyPair2.secretKey));
|
|
16
|
+
});
|
|
17
|
+
it('should generate valid signing key pair', () => {
|
|
18
|
+
const keyPair = generateSigningKeyPair();
|
|
19
|
+
expect(keyPair.publicKey).toBeInstanceOf(Uint8Array);
|
|
20
|
+
expect(keyPair.secretKey).toBeInstanceOf(Uint8Array);
|
|
21
|
+
expect(keyPair.publicKey.length).toBe(32);
|
|
22
|
+
expect(keyPair.secretKey.length).toBe(64);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('Encryption / Decryption', () => {
|
|
26
|
+
it('should encrypt and decrypt a message correctly', () => {
|
|
27
|
+
const alice = generateKeyPair();
|
|
28
|
+
const bob = generateKeyPair();
|
|
29
|
+
const message = 'Hello, Bob!';
|
|
30
|
+
const encrypted = encrypt(message, bob.publicKey, alice.secretKey);
|
|
31
|
+
expect(typeof encrypted).toBe('string');
|
|
32
|
+
expect(encrypted).not.toBe(message);
|
|
33
|
+
const decrypted = decrypt(encrypted, alice.publicKey, bob.secretKey);
|
|
34
|
+
expect(decrypted).toBe(message);
|
|
35
|
+
});
|
|
36
|
+
it('should produce different ciphertext for same message (due to random nonce)', () => {
|
|
37
|
+
const alice = generateKeyPair();
|
|
38
|
+
const bob = generateKeyPair();
|
|
39
|
+
const message = 'Same message';
|
|
40
|
+
const encrypted1 = encrypt(message, bob.publicKey, alice.secretKey);
|
|
41
|
+
const encrypted2 = encrypt(message, bob.publicKey, alice.secretKey);
|
|
42
|
+
expect(encrypted1).not.toBe(encrypted2);
|
|
43
|
+
});
|
|
44
|
+
it('should fail to decrypt with wrong key', () => {
|
|
45
|
+
const alice = generateKeyPair();
|
|
46
|
+
const bob = generateKeyPair();
|
|
47
|
+
const eve = generateKeyPair();
|
|
48
|
+
const message = 'Secret message';
|
|
49
|
+
const encrypted = encrypt(message, bob.publicKey, alice.secretKey);
|
|
50
|
+
expect(() => {
|
|
51
|
+
decrypt(encrypted, alice.publicKey, eve.secretKey);
|
|
52
|
+
}).toThrow('Decryption failed');
|
|
53
|
+
});
|
|
54
|
+
it('should handle unicode and special characters', () => {
|
|
55
|
+
const alice = generateKeyPair();
|
|
56
|
+
const bob = generateKeyPair();
|
|
57
|
+
const message = '你好世界 🚀 émojis & spëcial çhars!';
|
|
58
|
+
const encrypted = encrypt(message, bob.publicKey, alice.secretKey);
|
|
59
|
+
const decrypted = decrypt(encrypted, alice.publicKey, bob.secretKey);
|
|
60
|
+
expect(decrypted).toBe(message);
|
|
61
|
+
});
|
|
62
|
+
it('should handle empty string', () => {
|
|
63
|
+
const alice = generateKeyPair();
|
|
64
|
+
const bob = generateKeyPair();
|
|
65
|
+
const message = '';
|
|
66
|
+
const encrypted = encrypt(message, bob.publicKey, alice.secretKey);
|
|
67
|
+
const decrypted = decrypt(encrypted, alice.publicKey, bob.secretKey);
|
|
68
|
+
expect(decrypted).toBe(message);
|
|
69
|
+
});
|
|
70
|
+
it('should handle large messages', () => {
|
|
71
|
+
const alice = generateKeyPair();
|
|
72
|
+
const bob = generateKeyPair();
|
|
73
|
+
const message = 'x'.repeat(100000);
|
|
74
|
+
const encrypted = encrypt(message, bob.publicKey, alice.secretKey);
|
|
75
|
+
const decrypted = decrypt(encrypted, alice.publicKey, bob.secretKey);
|
|
76
|
+
expect(decrypted).toBe(message);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe('Shared Secret Encryption', () => {
|
|
80
|
+
it('should derive same shared secret from both sides', () => {
|
|
81
|
+
const alice = generateKeyPair();
|
|
82
|
+
const bob = generateKeyPair();
|
|
83
|
+
const aliceShared = deriveSharedSecret(bob.publicKey, alice.secretKey);
|
|
84
|
+
const bobShared = deriveSharedSecret(alice.publicKey, bob.secretKey);
|
|
85
|
+
expect(encodeBase64(aliceShared)).toBe(encodeBase64(bobShared));
|
|
86
|
+
});
|
|
87
|
+
it('should encrypt and decrypt with shared secret', () => {
|
|
88
|
+
const alice = generateKeyPair();
|
|
89
|
+
const bob = generateKeyPair();
|
|
90
|
+
const message = 'Shared secret message';
|
|
91
|
+
const sharedSecret = deriveSharedSecret(bob.publicKey, alice.secretKey);
|
|
92
|
+
const encrypted = encryptWithSharedSecret(message, sharedSecret);
|
|
93
|
+
const decrypted = decryptWithSharedSecret(encrypted, sharedSecret);
|
|
94
|
+
expect(decrypted).toBe(message);
|
|
95
|
+
});
|
|
96
|
+
it('should fail to decrypt with wrong shared secret', () => {
|
|
97
|
+
const alice = generateKeyPair();
|
|
98
|
+
const bob = generateKeyPair();
|
|
99
|
+
const eve = generateKeyPair();
|
|
100
|
+
const message = 'Secret';
|
|
101
|
+
const aliceShared = deriveSharedSecret(bob.publicKey, alice.secretKey);
|
|
102
|
+
const eveShared = deriveSharedSecret(eve.publicKey, eve.secretKey);
|
|
103
|
+
const encrypted = encryptWithSharedSecret(message, aliceShared);
|
|
104
|
+
expect(() => {
|
|
105
|
+
decryptWithSharedSecret(encrypted, eveShared);
|
|
106
|
+
}).toThrow('Decryption failed');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('Session DEK (V2 Protocol)', () => {
|
|
110
|
+
it('should generate 32-byte session DEK', () => {
|
|
111
|
+
const dek = generateSessionDEK();
|
|
112
|
+
expect(dek).toBeInstanceOf(Uint8Array);
|
|
113
|
+
expect(dek.length).toBe(32);
|
|
114
|
+
});
|
|
115
|
+
it('should generate unique DEKs each time', () => {
|
|
116
|
+
const dek1 = generateSessionDEK();
|
|
117
|
+
const dek2 = generateSessionDEK();
|
|
118
|
+
expect(encodeBase64(dek1)).not.toBe(encodeBase64(dek2));
|
|
119
|
+
});
|
|
120
|
+
it('should encrypt and decrypt DEK correctly', () => {
|
|
121
|
+
const agent = generateKeyPair();
|
|
122
|
+
const dek = generateSessionDEK();
|
|
123
|
+
const encryptedDEK = encryptDEK(dek, agent.publicKey);
|
|
124
|
+
expect(typeof encryptedDEK).toBe('string');
|
|
125
|
+
const decryptedDEK = decryptDEK(encryptedDEK, agent.secretKey);
|
|
126
|
+
expect(encodeBase64(decryptedDEK)).toBe(encodeBase64(dek));
|
|
127
|
+
});
|
|
128
|
+
it('should produce different ciphertext for same DEK (due to ephemeral key)', () => {
|
|
129
|
+
const agent = generateKeyPair();
|
|
130
|
+
const dek = generateSessionDEK();
|
|
131
|
+
const encrypted1 = encryptDEK(dek, agent.publicKey);
|
|
132
|
+
const encrypted2 = encryptDEK(dek, agent.publicKey);
|
|
133
|
+
expect(encrypted1).not.toBe(encrypted2);
|
|
134
|
+
});
|
|
135
|
+
it('should fail to decrypt DEK with wrong key', () => {
|
|
136
|
+
const agent = generateKeyPair();
|
|
137
|
+
const eve = generateKeyPair();
|
|
138
|
+
const dek = generateSessionDEK();
|
|
139
|
+
const encryptedDEK = encryptDEK(dek, agent.publicKey);
|
|
140
|
+
expect(() => {
|
|
141
|
+
decryptDEK(encryptedDEK, eve.secretKey);
|
|
142
|
+
}).toThrow('DEK decryption failed');
|
|
143
|
+
});
|
|
144
|
+
it('should throw if DEK is not 32 bytes', () => {
|
|
145
|
+
const agent = generateKeyPair();
|
|
146
|
+
const invalidDEK = new Uint8Array(16); // Too short
|
|
147
|
+
expect(() => {
|
|
148
|
+
encryptDEK(invalidDEK, agent.publicKey);
|
|
149
|
+
}).toThrow('DEK must be 32 bytes');
|
|
150
|
+
});
|
|
151
|
+
it('should work end-to-end: PWA generates DEK, Agent decrypts, both use for encryption', () => {
|
|
152
|
+
// Simulate V2 key exchange
|
|
153
|
+
const agentKeyPair = generateKeyPair();
|
|
154
|
+
// PWA generates session DEK and encrypts it for Agent
|
|
155
|
+
const sessionDEK = generateSessionDEK();
|
|
156
|
+
const encryptedDEK = encryptDEK(sessionDEK, agentKeyPair.publicKey);
|
|
157
|
+
// Agent decrypts the DEK
|
|
158
|
+
const agentDEK = decryptDEK(encryptedDEK, agentKeyPair.secretKey);
|
|
159
|
+
// Both should have the same DEK
|
|
160
|
+
expect(encodeBase64(agentDEK)).toBe(encodeBase64(sessionDEK));
|
|
161
|
+
// Both can now encrypt/decrypt messages using the DEK as shared secret
|
|
162
|
+
const message = 'Hello from PWA!';
|
|
163
|
+
const encrypted = encryptWithSharedSecret(message, sessionDEK);
|
|
164
|
+
const decrypted = decryptWithSharedSecret(encrypted, agentDEK);
|
|
165
|
+
expect(decrypted).toBe(message);
|
|
166
|
+
// Agent can respond
|
|
167
|
+
const response = 'Hello from Agent!';
|
|
168
|
+
const encryptedResponse = encryptWithSharedSecret(response, agentDEK);
|
|
169
|
+
const decryptedResponse = decryptWithSharedSecret(encryptedResponse, sessionDEK);
|
|
170
|
+
expect(decryptedResponse).toBe(response);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('Signing / Verification', () => {
|
|
174
|
+
it('should sign and verify a message', () => {
|
|
175
|
+
const keyPair = generateSigningKeyPair();
|
|
176
|
+
const message = 'Sign this message';
|
|
177
|
+
const signature = sign(message, keyPair.secretKey);
|
|
178
|
+
expect(typeof signature).toBe('string');
|
|
179
|
+
const isValid = verify(message, signature, keyPair.publicKey);
|
|
180
|
+
expect(isValid).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
it('should fail verification with wrong public key', () => {
|
|
183
|
+
const alice = generateSigningKeyPair();
|
|
184
|
+
const bob = generateSigningKeyPair();
|
|
185
|
+
const message = 'Signed by Alice';
|
|
186
|
+
const signature = sign(message, alice.secretKey);
|
|
187
|
+
const isValid = verify(message, signature, bob.publicKey);
|
|
188
|
+
expect(isValid).toBe(false);
|
|
189
|
+
});
|
|
190
|
+
it('should fail verification with modified message', () => {
|
|
191
|
+
const keyPair = generateSigningKeyPair();
|
|
192
|
+
const message = 'Original message';
|
|
193
|
+
const signature = sign(message, keyPair.secretKey);
|
|
194
|
+
const isValid = verify('Modified message', signature, keyPair.publicKey);
|
|
195
|
+
expect(isValid).toBe(false);
|
|
196
|
+
});
|
|
197
|
+
it('should produce different signatures for different messages', () => {
|
|
198
|
+
const keyPair = generateSigningKeyPair();
|
|
199
|
+
const sig1 = sign('Message 1', keyPair.secretKey);
|
|
200
|
+
const sig2 = sign('Message 2', keyPair.secretKey);
|
|
201
|
+
expect(sig1).not.toBe(sig2);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
describe('Key Encoding / Decoding', () => {
|
|
205
|
+
it('should encode and decode key pair correctly', () => {
|
|
206
|
+
const original = generateKeyPair();
|
|
207
|
+
const encoded = encodeKeyPair(original);
|
|
208
|
+
expect(typeof encoded.publicKey).toBe('string');
|
|
209
|
+
expect(typeof encoded.secretKey).toBe('string');
|
|
210
|
+
const decoded = decodeKeyPair(encoded);
|
|
211
|
+
expect(encodeBase64(decoded.publicKey)).toBe(encodeBase64(original.publicKey));
|
|
212
|
+
expect(encodeBase64(decoded.secretKey)).toBe(encodeBase64(original.secretKey));
|
|
213
|
+
});
|
|
214
|
+
it('should produce valid base64 strings', () => {
|
|
215
|
+
const keyPair = generateKeyPair();
|
|
216
|
+
const encoded = encodeKeyPair(keyPair);
|
|
217
|
+
// Check base64 format
|
|
218
|
+
expect(encoded.publicKey).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
219
|
+
expect(encoded.secretKey).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('Agent ID Generation', () => {
|
|
223
|
+
it('should generate valid agent ID', () => {
|
|
224
|
+
const agentId = generateAgentId();
|
|
225
|
+
expect(typeof agentId).toBe('string');
|
|
226
|
+
expect(agentId.length).toBeGreaterThan(0);
|
|
227
|
+
// URL-safe base64 (no +, /, =)
|
|
228
|
+
expect(agentId).toMatch(/^[A-Za-z0-9_-]+$/);
|
|
229
|
+
});
|
|
230
|
+
it('should generate unique agent IDs', () => {
|
|
231
|
+
const ids = new Set();
|
|
232
|
+
for (let i = 0; i < 100; i++) {
|
|
233
|
+
ids.add(generateAgentId());
|
|
234
|
+
}
|
|
235
|
+
expect(ids.size).toBe(100);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
describe('Base64 Encoding Utilities', () => {
|
|
239
|
+
it('should encode and decode bytes correctly', () => {
|
|
240
|
+
const original = new Uint8Array([1, 2, 3, 4, 5, 255, 0, 128]);
|
|
241
|
+
const encoded = encodeBase64(original);
|
|
242
|
+
const decoded = decodeBase64(encoded);
|
|
243
|
+
expect(decoded).toEqual(original);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
//# sourceMappingURL=crypto.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.test.js","sourceRoot":"","sources":["../src/crypto.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED