Skip to content
Back to skills

Stanford Crypto Patterns

ASecurity

Side-channel-resistant cryptography patterns from Stanford SJCL. Constant-time operations, AES-CCM authenticated encryption, PBKDF2 key derivation, random number generation, and timing-attack-safe comparisons. Sources: bitwiseshiftleft/sjcl (Stanford JavaScript Crypto Library).

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 9, 2026
ai-agentsjavascriptjavanodeapiperformance

Works with

  • api

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add yanacuti1121/Yana-AI --skill stanford-crypto-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Stanford Crypto Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Stanford Crypto Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yanacuti1121-stanford-crypto-patterns/badge)](https://www.skillsdirectory.com/skills/yanacuti1121-stanford-crypto-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: stanford-crypto-patterns
description: Side-channel-resistant cryptography patterns from Stanford SJCL. Constant-time operations, AES-CCM authenticated encryption, PBKDF2 key derivation, random number generation, and timing-attack-safe comparisons. Sources: bitwiseshiftleft/sjcl (Stanford JavaScript Crypto Library).
origin: yana-ai — synthesized from bitwiseshiftleft/sjcl (BSD-2-Clause, Stanford University)
license: Apache-2.0
version: 1.0.0
compatibility: yana-ai >= 1.3.49
---

# /stanford-crypto-patterns

## When to Use

- Environments where timing-attack resistance is critical (secret comparison)
- AES-CCM authenticated encryption (alternative to GCM with simpler nonce handling)
- SJCL PRNG for cryptographic random number generation
- Academic/compliance contexts requiring vetted, peer-reviewed crypto library

## Do NOT use for

- New Node.js code — prefer built-in `crypto` module (WebCrypto API) for standard cases
- Performance-critical bulk encryption (pure JS SJCL is slower than native C bindings)

---

## Constant-time comparison (timing-attack safe)

```javascript
import sjcl from 'sjcl'

// WRONG: regular string comparison leaks timing info
// if (secretA === secretB) ...  ← fails early on first mismatch

// RIGHT: constant-time comparison via XOR of bitArrays
function constantTimeEqual(a: string, b: string): boolean {
  if (a.length !== b.length) return false
  const aWords = sjcl.codec.utf8String.toBits(a)
  const bWords = sjcl.codec.utf8String.toBits(b)

  let diff = 0
  for (let i = 0; i < aWords.length; i++) {
    diff |= aWords[i] ^ bWords[i]
  }
  return diff === 0
}
```

---

## AES-CCM authenticated encryption

```javascript
import sjcl from 'sjcl'

function encryptSJCL(plaintext: string, passphrase: string): string {
  // sjcl.encrypt handles: PBKDF2 key derivation + AES-CCM + random IV + MAC
  const encrypted = sjcl.encrypt(passphrase, plaintext, {
    ks:  256,      // AES key size: 128 | 192 | 256
    ts:  128,      // authentication tag size: 64 | 96 | 128 bits
    iter: 100_000, // PBKDF2 iterations
    mode: 'ccm',   // ccm | gcm | ocb2
  })
  return encrypted  // JSON string with iv, salt, ct, adata, mac
}

function decryptSJCL(encrypted: string, passphrase: string): string {
  try {
    return sjcl.decrypt(passphrase, encrypted)
  } catch (e) {
    throw new Error('[sjcl] decryption failed — wrong passphrase or tampered data')
  }
}
```

---

## Cryptographic random bytes

```javascript
// SJCL PRNG (seeded from system entropy via window.crypto or a custom entropy function)
function secureRandom(bytes: number): string {
  const wordCount = Math.ceil(bytes / 4)
  const words     = sjcl.random.randomWords(wordCount, 10)  // paranoia level 10
  return sjcl.codec.hex.fromBits(words).slice(0, bytes * 2)
}

// Session nonce
const nonce = secureRandom(16)   // 32-char hex = 128-bit nonce
```

---

## PBKDF2 key derivation

```javascript
function deriveKeySJCL(passphrase: string, saltHex: string, iterations = 100_000): string {
  const salt  = sjcl.codec.hex.toBits(saltHex)
  const key   = sjcl.misc.pbkdf2(passphrase, salt, iterations, 256)
  return sjcl.codec.hex.fromBits(key)
}
```

---

## SHA-256 / HMAC

```javascript
const hash = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('data'))

const key  = sjcl.codec.utf8String.toBits(process.env.HMAC_KEY!)
const mac  = sjcl.codec.hex.fromBits(new sjcl.misc.hmac(key).encrypt('message'))
```

---

## Anti-Fake-Pass Checklist

```
❌ sjcl.random.randomWords without seeding → throws on missing entropy in Node.js (use node-crypto seed)
❌ sjcl.encrypt paranoia < 6 → low entropy tolerance warning; use 8-10 for production
❌ Comparing MAC tags with === → timing attack; use constantTimeEqual above
❌ AES-CCM nonce reused → catastrophic, breaks authentication (SJCL uses random IV by default)
❌ sjcl in browser vs Node.js → window.crypto auto-seed in browser, must manually add entropy in Node
❌ sjcl output is JSON object — stringify before storing, parse before decrypting
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.