jfrery-zama commited on
Commit
80fbc0a
Β·
unverified Β·
1 Parent(s): c7c27a1

more update to ux / ui

Browse files
Files changed (3) hide show
  1. index.html +26 -65
  2. wasm-demo.js +26 -8
  3. zama_logo.webp +0 -0
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Private SynthID - Check if your text is AI Generated</title>
7
  <link rel="icon" type="image/x-icon" href="favicon.ico">
8
 
9
  <style>
@@ -56,9 +56,7 @@
56
  margin-inline: auto;
57
  }
58
  .logo {
59
- font-size: 2rem;
60
- font-weight: 700;
61
- letter-spacing: -0.02em;
62
  }
63
  .contact-btn {
64
  border: 2px solid var(--black);
@@ -88,7 +86,7 @@
88
  max-width: var(--container-max);
89
  margin: calc(var(--spacing-unit) * 4) auto calc(var(--spacing-unit) * 10);
90
  padding-inline: calc(var(--spacing-unit) * 4);
91
- grid-template-columns: 1fr 1fr;
92
  }
93
  .hero h1 {
94
  font-size: clamp(3rem, 6vw, 4.5rem);
@@ -301,6 +299,19 @@
301
  opacity: 0.8;
302
  }
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  /* Responsive adjustments */
305
  @media (max-width: 968px) {
306
  .hero {
@@ -340,71 +351,22 @@
340
 
341
  <!-- external scripts -->
342
  <script type="module" src="https://belladoreai.github.io/llama3-tokenizer-js/bundle/llama3-tokenizer-with-baked-data.js"></script>
343
- <script type="module">
344
- import mermaid from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
345
- mermaid.initialize({
346
- startOnLoad: true,
347
- theme: 'base',
348
- themeVariables: {
349
- primaryColor: '#ffd200',
350
- primaryTextColor: '#000',
351
- lineColor: '#000',
352
- tertiaryColor: '#fff',
353
- fontFamily: 'Telegraf',
354
- fontSize: '1.4rem'
355
- },
356
- flowchart: {
357
- nodeSpacing: 50,
358
- rankSpacing: 50,
359
- curve: 'basis',
360
- fontSize: '1.4rem'
361
- },
362
- sequence: {
363
- actorFontSize: '1.4rem',
364
- noteFontSize: '1.4rem',
365
- messageFontSize: '1.4rem'
366
- }
367
- });
368
- </script>
369
  </head>
370
  <body>
371
  <!-- Navbar -->
372
  <nav class="navbar">
373
- <div class="logo">ZAMA</div>
374
  <a href="https://www.zama.ai/contact" class="contact-btn" target="_blank" rel="noopener noreferrer">Contact us</a>
375
  </nav>
376
 
377
  <!-- Hero -->
378
  <header class="hero" role="banner">
379
  <div class="hero-copy">
380
- <h1>Private Watermark Detection</h1>
381
  <div class="explanation-text">
382
- Private SynthID uses Google's SynthID technology to detect watermarks in AI-generated text while preserving privacy through Fully Homomorphic Encryption (FHE). This means you can check if text contains AI watermarks without revealing the content to anyone. Learn more about <a href="https://deepmind.google/science/synthid/" target="_blank">SynthID</a> and <a href="https://www.zama.ai/" target="_blank">FHE applications</a>.
383
  </div>
384
  </div>
385
-
386
- <div class="hero-diagram">
387
- <pre class="mermaid">
388
- sequenceDiagram
389
- participant UserπŸ§‘β€πŸ’»
390
- participant BrowserπŸ”
391
- participant RustServerπŸ¦€
392
-
393
- UserπŸ§‘β€πŸ’»->>BrowserπŸ”: 1️⃣ Generate keys
394
- BrowserπŸ”->>BrowserπŸ”: TFHE keygen (WASM)
395
- BrowserπŸ”->>RustServerπŸ¦€: 2️⃣ /handshake (server_key_b64)
396
- RustServerπŸ¦€->>BrowserπŸ”: UID (uuid-v4)
397
-
398
- UserπŸ§‘β€πŸ’»->>BrowserπŸ”: 3️⃣ Enter text
399
- BrowserπŸ”->>BrowserπŸ”: Tokenise ◁ HF tokenizer
400
- BrowserπŸ”->>BrowserπŸ”: Encrypt tokens (WASM)
401
- BrowserπŸ”->>RustServerπŸ¦€: 4️⃣ /detect (uid, ciphertext_b64)
402
- RustServerπŸ¦€->>RustServerπŸ¦€: FHE SynthID detect
403
- RustServerπŸ¦€->>BrowserπŸ”: Encrypted result_b64
404
- BrowserπŸ”->>BrowserπŸ”: Decrypt result (WASM)
405
- BrowserπŸ”-->>UserπŸ§‘β€πŸ’»: flag / score / g
406
- </pre>
407
- </div>
408
  </header>
409
 
410
  <!-- Wizard Steps -->
@@ -415,12 +377,12 @@ sequenceDiagram
415
  <h2 id="step1">1. Keys</h2>
416
  <div class="card-content">
417
  <div class="controls" style="margin-top: 0;">
418
- <p id="keygenStatus" class="status" aria-live="polite">Ready to generate keys</p>
419
  <span id="keygenSpin" class="loader" hidden aria-label="Generating keys"></span>
420
  </div>
421
  <div style="display:flex; gap:var(--spacing-unit); margin-top:auto">
422
- <button id="btnKeygen" class="btn" aria-describedby="keygenStatus">πŸ”‘ Generate keys</button>
423
- <button id="btnLoadSaved" class="btn" aria-describedby="keygenStatus">πŸ—οΈ Load keys</button>
424
  </div>
425
  </div>
426
  </section>
@@ -436,8 +398,7 @@ sequenceDiagram
436
  <label for="tokenInput" class="visually-hidden">Text to encrypt</label>
437
  <textarea id="tokenInput" rows="2" placeholder="Enter text to encrypt or use the example below" autocomplete="off"></textarea>
438
  <div style="display: flex; gap: calc(var(--spacing-unit) * 1); margin-bottom: calc(var(--spacing-unit) * 2); flex-wrap: wrap; align-items: center;">
439
- <button id="btnWatermarked" class="btn" style="min-width: auto; padding: calc(var(--spacing-unit) * 1) calc(var(--spacing-unit) * 1.5); font-size: 1rem;">✨ Use watermarked example</button>
440
- <span style="font-size: 1rem; color: var(--black); opacity: 0.7;">← Try this to see watermark detection in action</span>
441
  </div>
442
  <div class="controls" style="margin-top: auto;">
443
  <button id="btnEncrypt" class="btn" disabled>πŸ›‘οΈ Encrypt</button>
@@ -453,8 +414,8 @@ sequenceDiagram
453
  <h2 id="step3">3. Send to server</h2>
454
  <div class="card-content">
455
  <div>
456
- <p id="srvStatus" class="status" aria-live="polite">Waiting for encrypted data...</p>
457
- <p id="srvComputing" class="status" aria-live="polite" hidden>Server computing...</p>
458
  </div>
459
  <div class="controls" style="margin-top: auto;">
460
  <button id="btnSend" class="btn" disabled>πŸ“‘ Send</button>
@@ -474,7 +435,7 @@ sequenceDiagram
474
  <button id="btnDecrypt" class="btn" disabled>πŸ”“ Decrypt</button>
475
  </div>
476
  <div class="disclaimer" style="margin-top: calc(var(--spacing-unit) * 3); font-size: 0.9rem; color: var(--black); opacity: 0.7; line-height: 1.5;">
477
- <p><strong>Note about reliability:</strong> Watermark detection is most reliable with longer texts (100+ tokens). In this demo, we limit input to 16 tokens for performance, which may affect accuracy. Detection improves significantly with 10+ tokens but is less reliable with very short texts.</p>
478
  </div>
479
  </div>
480
  </section>
 
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Private AI Text Detector – Check if your encrypted text is AI-generated</title>
7
  <link rel="icon" type="image/x-icon" href="favicon.ico">
8
 
9
  <style>
 
56
  margin-inline: auto;
57
  }
58
  .logo {
59
+ height: 40px;
 
 
60
  }
61
  .contact-btn {
62
  border: 2px solid var(--black);
 
86
  max-width: var(--container-max);
87
  margin: calc(var(--spacing-unit) * 4) auto calc(var(--spacing-unit) * 10);
88
  padding-inline: calc(var(--spacing-unit) * 4);
89
+ grid-template-columns: 1fr;
90
  }
91
  .hero h1 {
92
  font-size: clamp(3rem, 6vw, 4.5rem);
 
299
  opacity: 0.8;
300
  }
301
 
302
+ /* Result type styling */
303
+ .watermark-flag.inconclusive {
304
+ color: #f57c00;
305
+ }
306
+
307
+ .watermark-flag.watermarked {
308
+ color: #2e7d32;
309
+ }
310
+
311
+ .watermark-flag.ai-generated {
312
+ color: #1976d2;
313
+ }
314
+
315
  /* Responsive adjustments */
316
  @media (max-width: 968px) {
317
  .hero {
 
351
 
352
  <!-- external scripts -->
353
  <script type="module" src="https://belladoreai.github.io/llama3-tokenizer-js/bundle/llama3-tokenizer-with-baked-data.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  </head>
355
  <body>
356
  <!-- Navbar -->
357
  <nav class="navbar">
358
+ <img src="zama_logo.webp" alt="Zama logo" class="logo" />
359
  <a href="https://www.zama.ai/contact" class="contact-btn" target="_blank" rel="noopener noreferrer">Contact us</a>
360
  </nav>
361
 
362
  <!-- Hero -->
363
  <header class="hero" role="banner">
364
  <div class="hero-copy">
365
+ <h1>Private AI Text Detection</h1>
366
  <div class="explanation-text">
367
+ Private SynthID uses Google's SynthID technology to identify AI-generated text while preserving privacy through Fully Homomorphic Encryption (FHE). This means you can learn whether your text was produced by an AIβ€”without anyone ever seeing the content. Learn more about <a href="https://deepmind.google/science/synthid/" target="_blank">SynthID</a> and <a href="https://www.zama.ai/" target="_blank">FHE applications</a>.
368
  </div>
369
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  </header>
371
 
372
  <!-- Wizard Steps -->
 
377
  <h2 id="step1">1. Keys</h2>
378
  <div class="card-content">
379
  <div class="controls" style="margin-top: 0;">
380
+ <p id="keygenStatus" class="status" aria-live="polite">Generate new keys (a few minutes on first run)</p>
381
  <span id="keygenSpin" class="loader" hidden aria-label="Generating keys"></span>
382
  </div>
383
  <div style="display:flex; gap:var(--spacing-unit); margin-top:auto">
384
+ <button id="btnKeygen" class="btn" aria-describedby="keygenStatus">πŸ”‘ Generate new keys</button>
385
+ <button id="btnLoadSaved" class="btn" aria-describedby="keygenStatus">πŸ—οΈ Load saved keys</button>
386
  </div>
387
  </div>
388
  </section>
 
398
  <label for="tokenInput" class="visually-hidden">Text to encrypt</label>
399
  <textarea id="tokenInput" rows="2" placeholder="Enter text to encrypt or use the example below" autocomplete="off"></textarea>
400
  <div style="display: flex; gap: calc(var(--spacing-unit) * 1); margin-bottom: calc(var(--spacing-unit) * 2); flex-wrap: wrap; align-items: center;">
401
+ <button id="btnWatermarked" class="btn" style="min-width: auto; padding: calc(var(--spacing-unit) * 1) calc(var(--spacing-unit) * 1.5); font-size: 1rem;">✨ Load sample AI text</button>
 
402
  </div>
403
  <div class="controls" style="margin-top: auto;">
404
  <button id="btnEncrypt" class="btn" disabled>πŸ›‘οΈ Encrypt</button>
 
414
  <h2 id="step3">3. Send to server</h2>
415
  <div class="card-content">
416
  <div>
417
+ <p id="srvStatus" class="status" aria-live="polite">Waiting for encrypted data… (server processing can take several minutes)</p>
418
+ <p id="srvComputing" class="status" aria-live="polite" hidden>Server computing…</p>
419
  </div>
420
  <div class="controls" style="margin-top: auto;">
421
  <button id="btnSend" class="btn" disabled>πŸ“‘ Send</button>
 
435
  <button id="btnDecrypt" class="btn" disabled>πŸ”“ Decrypt</button>
436
  </div>
437
  <div class="disclaimer" style="margin-top: calc(var(--spacing-unit) * 3); font-size: 0.9rem; color: var(--black); opacity: 0.7; line-height: 1.5;">
438
+ <p><strong>Note about reliability:</strong> AI text detection works best with longer passages (100+ tokens). In this demo, input is limited to 16 tokens for performance, which may affect accuracy. Reliability improves significantly with 10+ tokens but is less reliable on very short snippets.</p>
439
  </div>
440
  </div>
441
  </section>
wasm-demo.js CHANGED
@@ -394,18 +394,36 @@ $('btnDecrypt').onclick = () => {
394
  console.log('[Main] Starting decryption...');
395
  const dec = decrypt_serialized_u64_radix_flat_wasm(encServerResult, clientKey);
396
  const [flag, score_scaled, total_g] = Array.from(dec);
397
- const score = (Number(score_scaled) / 1e6).toFixed(6);
398
  console.log('[Main] Decryption successful');
399
- console.log(`[Main] Result - flag: ${flag}, score: ${score}, total_g: ${total_g}`);
400
 
401
- // Create elegant result display
402
- const isWatermarked = Number(flag) === 1;
403
- const flagText = isWatermarked ? 'βœ… Watermarked' : '❌ Not Watermarked';
404
- const scoreText = `Confidence Score: ${score}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
 
406
  $('decResult').innerHTML = `
407
- <div class="watermark-flag">${flagText}</div>
408
- <div class="watermark-score">${scoreText}</div>
409
  `;
410
  } catch (e) {
411
  console.error('[Main] Decryption error:', e);
 
394
  console.log('[Main] Starting decryption...');
395
  const dec = decrypt_serialized_u64_radix_flat_wasm(encServerResult, clientKey);
396
  const [flag, score_scaled, total_g] = Array.from(dec);
397
+ const rawScore = Number(score_scaled) / 1e6;
398
  console.log('[Main] Decryption successful');
399
+ console.log(`[Main] Result - flag: ${flag}, raw_score: ${rawScore}, total_g: ${total_g}`);
400
 
401
+ // Convert to confidence value between 0 and 1
402
+ const confidence = Math.max(0, Math.min(1, rawScore));
403
+
404
+ // Determine result based on confidence ranges
405
+ let resultText, confidenceText, resultClass;
406
+
407
+ if (confidence < 0.5) {
408
+ // Problematic range - should not be addressed according to user
409
+ resultText = '⚠️ Inconclusive';
410
+ confidenceText = `Confidence: ${(confidence * 100).toFixed(1)}% (insufficient data)`;
411
+ resultClass = 'inconclusive';
412
+ } else if (confidence >= 0.5 && confidence < 0.6) {
413
+ // Very likely to be watermarked (close to 0.5)
414
+ resultText = 'βœ… AI-Generated (Watermarked)';
415
+ confidenceText = `Confidence: ${(confidence * 100).toFixed(1)}%`;
416
+ resultClass = 'watermarked';
417
+ } else {
418
+ // Between 0.6 and 1 - highly likely to be AI generated
419
+ resultText = 'πŸ€– AI-Generated';
420
+ confidenceText = `Confidence: ${(confidence * 100).toFixed(1)}%`;
421
+ resultClass = 'ai-generated';
422
+ }
423
 
424
  $('decResult').innerHTML = `
425
+ <div class="watermark-flag ${resultClass}">${resultText}</div>
426
+ <div class="watermark-score">${confidenceText}</div>
427
  `;
428
  } catch (e) {
429
  console.error('[Main] Decryption error:', e);
zama_logo.webp ADDED