jfrery-zama commited on
Commit
aa387a3
Β·
unverified Β·
1 Parent(s): 8a699bc

save load keys

Browse files
Files changed (2) hide show
  1. index.html +3 -2
  2. wasm-demo.js +85 -24
index.html CHANGED
@@ -403,8 +403,9 @@ sequenceDiagram
403
  <p id="keygenStatus" class="status" aria-live="polite">Ready to generate keys</p>
404
  <span id="keygenSpin" class="loader" hidden aria-label="Generating keys"></span>
405
  </div>
406
- <div style="margin-top: auto;">
407
- <button id="btnKeygen" class="btn" aria-describedby="keygenStatus">πŸ”‘ Generate keys</button>
 
408
  </div>
409
  </div>
410
  </section>
 
403
  <p id="keygenStatus" class="status" aria-live="polite">Ready to generate keys</p>
404
  <span id="keygenSpin" class="loader" hidden aria-label="Generating keys"></span>
405
  </div>
406
+ <div style="display:flex; gap:var(--spacing-unit); margin-top:auto">
407
+ <button id="btnKeygen" class="btn" aria-describedby="keygenStatus">πŸ”‘ Generate keys</button>
408
+ <button id="btnLoadSaved" class="btn" aria-describedby="keygenStatus">πŸ—οΈ Load keys</button>
409
  </div>
410
  </div>
411
  </section>
wasm-demo.js CHANGED
@@ -26,6 +26,22 @@ function uint8ToBase64(uint8) {
26
  });
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  const $ = id => document.getElementById(id);
30
  const enable = (id, ok=true) => $(id).disabled = !ok;
31
  const show = (id, visible=true) => $(id).hidden = !visible;
@@ -55,29 +71,7 @@ show('tokenizerSpin', false);
55
 
56
  try {
57
  // Initialize encryption worker
58
- encryptWorker = new Worker(new URL('./encrypt-worker.js', import.meta.url), { type: 'module' });
59
- encryptWorker.onmessage = function(e) {
60
- if (e.data.type === 'ready') {
61
- console.log('[Main] Encryption worker ready');
62
- } else if (e.data.type === 'success') {
63
- encTokens = e.data.result;
64
- console.log(`[Main] Encryption completed: ${encTokens.length} bytes`);
65
- show('encryptSpin', false);
66
- show('encIcon', true);
67
- enable('btnEncrypt', true);
68
- enable('btnSend');
69
- $('encStatus').textContent = 'Your text is encrypted πŸ”’';
70
- } else if (e.data.type === 'error') {
71
- console.error('[Main] Encryption error:', e.data.error);
72
- show('encryptSpin', false);
73
- enable('btnEncrypt', true);
74
- $('encStatus').textContent = `Encryption failed: ${e.data.error}`;
75
- alert(`Encryption failed: ${e.data.error}`);
76
- }
77
- };
78
-
79
- // Initialize the worker with the client key
80
- encryptWorker.postMessage({ type: 'init', clientKey });
81
 
82
  console.log('[Main] Sending server key to server...');
83
  $('keygenStatus').textContent = 'Keys generated, sending server key...';
@@ -104,6 +98,14 @@ show('tokenizerSpin', false);
104
  console.log('[Main] Server key sent and UID received:', sessionUid);
105
  $('keygenStatus').textContent = 'Keys generated & UID received βœ“';
106
  enable('btnEncrypt');
 
 
 
 
 
 
 
 
107
  } catch (error) {
108
  console.error('[Main] Server key submission error:', error);
109
  $('keygenStatus').textContent = `Server key submission failed: ${error.message}`;
@@ -140,6 +142,39 @@ $('btnKeygen').onclick = async () => {
140
  }
141
  };
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  // Add token counter functionality
144
  $('tokenInput').addEventListener('input', () => {
145
  const text = $('tokenInput').value.trim();
@@ -361,4 +396,30 @@ $('btnDecrypt').onclick = () => {
361
  console.error('[Main] Decryption error:', e);
362
  $('decResult').textContent = `Decryption failed: ${e.message}`;
363
  }
364
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  });
27
  }
28
 
29
+ // β€”β€”β€” local key cache helpers β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
30
+ const KEYS_STORAGE_KEY = 'synthid_keys_v1';
31
+
32
+ /** base64 β†’ Uint8Array (works in all browsers, avoids atob size limits) */
33
+ function base64ToUint8(base64) {
34
+ const binStr = atob(base64);
35
+ const len = binStr.length;
36
+ const bytes = new Uint8Array(len);
37
+ for (let i = 0; i < len; i++) bytes[i] = binStr.charCodeAt(i);
38
+ return bytes;
39
+ }
40
+
41
+ function getSavedKeys() { return JSON.parse(localStorage.getItem(KEYS_STORAGE_KEY) || '{}'); }
42
+ function saveKeys(map) { localStorage.setItem(KEYS_STORAGE_KEY, JSON.stringify(map)); }
43
+ function saveKeyset(uid, b64){ const m = getSavedKeys(); m[uid] = b64; saveKeys(m); }
44
+
45
  const $ = id => document.getElementById(id);
46
  const enable = (id, ok=true) => $(id).disabled = !ok;
47
  const show = (id, visible=true) => $(id).hidden = !visible;
 
71
 
72
  try {
73
  // Initialize encryption worker
74
+ initEncryptWorkerWithKey(clientKey);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  console.log('[Main] Sending server key to server...');
77
  $('keygenStatus').textContent = 'Keys generated, sending server key...';
 
98
  console.log('[Main] Server key sent and UID received:', sessionUid);
99
  $('keygenStatus').textContent = 'Keys generated & UID received βœ“';
100
  enable('btnEncrypt');
101
+
102
+ // Persist clientKey ⟷ uid for reuse
103
+ uint8ToBase64(clientKey)
104
+ .then(b64 => {
105
+ saveKeyset(sessionUid, b64);
106
+ console.log(`[Main] Saved clientKey for uid ${sessionUid} to localStorage`);
107
+ })
108
+ .catch(err => console.warn('[Main] Failed to save key:', err));
109
  } catch (error) {
110
  console.error('[Main] Server key submission error:', error);
111
  $('keygenStatus').textContent = `Server key submission failed: ${error.message}`;
 
142
  }
143
  };
144
 
145
+ $('btnLoadSaved').onclick = async () => {
146
+ const saved = getSavedKeys();
147
+ const ids = Object.keys(saved);
148
+ if (!ids.length) {
149
+ alert('No saved keys found on this machine.');
150
+ return;
151
+ }
152
+
153
+ // Very lightweight UI: ask which uid to use
154
+ const uid = prompt(
155
+ `Saved key sets:\n${ids.join('\n')}\n\nEnter the uid you want to use:`,
156
+ ids[0]
157
+ );
158
+ if (!uid || !saved[uid]) {
159
+ alert('Invalid or unknown uid.');
160
+ return;
161
+ }
162
+
163
+ try {
164
+ sessionUid = uid;
165
+ clientKey = base64ToUint8(saved[uid]);
166
+
167
+ // Make sure we have an encryption worker ready
168
+ initEncryptWorkerWithKey(clientKey);
169
+
170
+ $('keygenStatus').textContent = `Loaded saved keys for ${uid} βœ“`;
171
+ enable('btnEncrypt');
172
+ } catch (err) {
173
+ console.error('[Main] Failed to load key:', err);
174
+ alert(`Failed to load saved key: ${err.message}`);
175
+ }
176
+ };
177
+
178
  // Add token counter functionality
179
  $('tokenInput').addEventListener('input', () => {
180
  const text = $('tokenInput').value.trim();
 
396
  console.error('[Main] Decryption error:', e);
397
  $('decResult').textContent = `Decryption failed: ${e.message}`;
398
  }
399
+ };
400
+
401
+ function encryptWorker_onmessage(e) {
402
+ if (e.data.type === 'ready') {
403
+ console.log('[Main] Encryption worker ready');
404
+ } else if (e.data.type === 'success') {
405
+ encTokens = e.data.result;
406
+ console.log(`[Main] Encryption completed: ${encTokens.length} bytes`);
407
+ show('encryptSpin', false);
408
+ show('encIcon', true);
409
+ enable('btnEncrypt', true);
410
+ enable('btnSend');
411
+ $('encStatus').textContent = 'Your text is encrypted πŸ”’';
412
+ } else if (e.data.type === 'error') {
413
+ console.error('[Main] Encryption error:', e.data.error);
414
+ show('encryptSpin', false);
415
+ enable('btnEncrypt', true);
416
+ $('encStatus').textContent = `Encryption failed: ${e.data.error}`;
417
+ alert(`Encryption failed: ${e.data.error}`);
418
+ }
419
+ }
420
+
421
+ function initEncryptWorkerWithKey(keyUint8) {
422
+ encryptWorker = new Worker(new URL('./encrypt-worker.js', import.meta.url), { type: 'module' });
423
+ encryptWorker.onmessage = encryptWorker_onmessage;
424
+ encryptWorker.postMessage({ type: 'init', clientKey: keyUint8 });
425
+ }