CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tweetnacl

Port of TweetNaCl cryptographic library to JavaScript providing comprehensive cryptographic primitives

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

Core utility functions including SHA-512 hashing, secure random byte generation, constant-time comparison, and PRNG configuration. These functions support the cryptographic operations and provide essential security primitives.

Capabilities

Hashing

SHA-512 cryptographic hash function for message digests and key derivation.

/**
 * Computes SHA-512 hash of a message
 * @param {Uint8Array} message - The message to hash
 * @returns {Uint8Array} SHA-512 hash (64 bytes)
 */
nacl.hash(message): Uint8Array

Usage Examples:

const nacl = require('tweetnacl');

// Hash a simple message
const message = new TextEncoder().encode("Hello, world!");
const hash = nacl.hash(message);
console.log(hash.length); // 64

// Hash for key derivation
function deriveKey(password, salt) {
  const combined = new Uint8Array(password.length + salt.length);
  combined.set(password);
  combined.set(salt, password.length);
  return nacl.hash(combined).slice(0, 32); // Take first 32 bytes as key
}

const password = new TextEncoder().encode("my-password");
const salt = nacl.randomBytes(16);
const derivedKey = deriveKey(password, salt);

Multiple Round Hashing:

const nacl = require('tweetnacl');

// Hash multiple times for key stretching
function hashMultiple(data, rounds) {
  let result = nacl.hash(data);
  for (let i = 1; i < rounds; i++) {
    result = nacl.hash(result);
  }
  return result;
}

const data = new TextEncoder().encode("sensitive data");
const stretched = hashMultiple(data, 10000);

Random Byte Generation

Cryptographically secure random byte generation using platform-appropriate sources.

/**
 * Generates cryptographically secure random bytes
 * @param {number} length - Number of random bytes to generate
 * @returns {Uint8Array} Array of random bytes
 * @throws {Error} If no secure PRNG is available
 */
nacl.randomBytes(length): Uint8Array

Usage Examples:

const nacl = require('tweetnacl');

// Generate random keys
const secretKey = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);

// Generate random data for testing
const randomData = nacl.randomBytes(100);

// Generate random identifiers
const sessionId = nacl.randomBytes(16);
const userId = Array.from(nacl.randomBytes(8))
  .map(b => b.toString(16).padStart(2, '0'))
  .join('');

Constant-Time Comparison

Secure comparison function that prevents timing attacks.

/**
 * Compares two arrays in constant time to prevent timing attacks
 * @param {Uint8Array} x - First array to compare
 * @param {Uint8Array} y - Second array to compare
 * @returns {boolean} True if arrays are equal and non-zero length, false otherwise
 */
nacl.verify(x, y): boolean

Usage Examples:

const nacl = require('tweetnacl');

// Compare authentication tokens safely
function verifyToken(receivedToken, expectedToken) {
  return nacl.verify(receivedToken, expectedToken);
}

const token1 = new TextEncoder().encode("secret-token-123");
const token2 = new TextEncoder().encode("secret-token-123");
const token3 = new TextEncoder().encode("secret-token-456");

console.log(nacl.verify(token1, token2)); // true
console.log(nacl.verify(token1, token3)); // false

// Verify hashes securely
const data = new TextEncoder().encode("important data");
const hash1 = nacl.hash(data);
const hash2 = nacl.hash(data);

console.log(nacl.verify(hash1, hash2)); // true

Important Timing Attack Prevention:

const nacl = require('tweetnacl');

// WRONG: Vulnerable to timing attacks
function unsafeVerify(received, expected) {
  if (received.length !== expected.length) return false;
  for (let i = 0; i < received.length; i++) {
    if (received[i] !== expected[i]) return false; // Early return leaks timing
  }
  return true;
}

// CORRECT: Constant-time comparison
function safeVerify(received, expected) {
  return nacl.verify(received, expected);
}

PRNG Configuration

Configure custom pseudo-random number generator for environments without standard crypto APIs.

/**
 * Sets a custom pseudo-random number generator function
 * @param {function} fn - Function that fills array with random bytes: (x: Uint8Array, n: number) => void
 * @returns {void}
 */
nacl.setPRNG(fn): void

Usage Example:

const nacl = require('tweetnacl');

// Custom PRNG implementation (example only - don't use in production)
function customPRNG(x, n) {
  // This is just an example - use a cryptographically secure source
  const crypto = require('crypto');
  const bytes = crypto.randomBytes(n);
  for (let i = 0; i < n; i++) {
    x[i] = bytes[i];
  }
}

// Set custom PRNG
nacl.setPRNG(customPRNG);

// Now randomBytes will use the custom function
const randomData = nacl.randomBytes(32);

Platform Detection Example:

// TweetNaCl.js automatically detects and configures PRNG based on environment:

// Browser: Uses window.crypto.getRandomValues or window.msCrypto.getRandomValues
// Node.js: Uses crypto.randomBytes
// Custom: Can be overridden with nacl.setPRNG

// Check if PRNG is available
try {
  nacl.randomBytes(1);
  console.log("Secure PRNG is available");
} catch (error) {
  console.log("No secure PRNG available - need to configure one");
  // Set custom PRNG here
}

Constants

nacl.hash.hashLength: number    // 64 - Length of SHA-512 hash in bytes

Security Considerations

Random Number Generation

  • Platform Security: TweetNaCl.js automatically uses the most secure random source available on each platform.
  • Custom PRNG: Only use setPRNG if you understand cryptographic security requirements. Poor random sources break security.
  • Fallback Handling: If no secure PRNG is available, functions requiring randomness will throw exceptions.

Constant-Time Operations

  • Timing Attacks: Always use nacl.verify for comparing sensitive data like tokens, hashes, or MACs.
  • Early Returns: Never use standard comparison operators for security-sensitive comparisons.
  • Zero-Length Arrays: nacl.verify returns false for zero-length arrays to prevent edge case vulnerabilities.

Hashing

  • One-Way Function: SHA-512 is cryptographically one-way - hashes cannot be reversed to recover original data.
  • Collision Resistance: SHA-512 is designed to prevent finding two inputs that produce the same hash.
  • Key Derivation: For deriving keys from passwords, consider using key derivation functions like PBKDF2 or scrypt instead of plain hashing.

Integration with Other Functions

These utilities are used throughout TweetNaCl.js:

  • randomBytes: Used by key generation functions (nacl.box.keyPair, nacl.sign.keyPair)
  • hash: Used internally by signing operations and can be used for custom key derivation
  • verify: Essential for secure token/MAC verification in custom authentication schemes
  • setPRNG: Allows customization for specialized environments or testing scenarios

Install with Tessl CLI

npx tessl i tessl/npm-tweetnacl

docs

box.md

index.md

lowlevel.md

scalarmult.md

secretbox.md

sign.md

utilities.md

tile.json