0
# Utilities
1
2
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.
3
4
## Capabilities
5
6
### Hashing
7
8
SHA-512 cryptographic hash function for message digests and key derivation.
9
10
```javascript { .api }
11
/**
12
* Computes SHA-512 hash of a message
13
* @param {Uint8Array} message - The message to hash
14
* @returns {Uint8Array} SHA-512 hash (64 bytes)
15
*/
16
nacl.hash(message): Uint8Array
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
const nacl = require('tweetnacl');
23
24
// Hash a simple message
25
const message = new TextEncoder().encode("Hello, world!");
26
const hash = nacl.hash(message);
27
console.log(hash.length); // 64
28
29
// Hash for key derivation
30
function deriveKey(password, salt) {
31
const combined = new Uint8Array(password.length + salt.length);
32
combined.set(password);
33
combined.set(salt, password.length);
34
return nacl.hash(combined).slice(0, 32); // Take first 32 bytes as key
35
}
36
37
const password = new TextEncoder().encode("my-password");
38
const salt = nacl.randomBytes(16);
39
const derivedKey = deriveKey(password, salt);
40
```
41
42
**Multiple Round Hashing:**
43
44
```javascript
45
const nacl = require('tweetnacl');
46
47
// Hash multiple times for key stretching
48
function hashMultiple(data, rounds) {
49
let result = nacl.hash(data);
50
for (let i = 1; i < rounds; i++) {
51
result = nacl.hash(result);
52
}
53
return result;
54
}
55
56
const data = new TextEncoder().encode("sensitive data");
57
const stretched = hashMultiple(data, 10000);
58
```
59
60
### Random Byte Generation
61
62
Cryptographically secure random byte generation using platform-appropriate sources.
63
64
```javascript { .api }
65
/**
66
* Generates cryptographically secure random bytes
67
* @param {number} length - Number of random bytes to generate
68
* @returns {Uint8Array} Array of random bytes
69
* @throws {Error} If no secure PRNG is available
70
*/
71
nacl.randomBytes(length): Uint8Array
72
```
73
74
**Usage Examples:**
75
76
```javascript
77
const nacl = require('tweetnacl');
78
79
// Generate random keys
80
const secretKey = nacl.randomBytes(32);
81
const nonce = nacl.randomBytes(24);
82
83
// Generate random data for testing
84
const randomData = nacl.randomBytes(100);
85
86
// Generate random identifiers
87
const sessionId = nacl.randomBytes(16);
88
const userId = Array.from(nacl.randomBytes(8))
89
.map(b => b.toString(16).padStart(2, '0'))
90
.join('');
91
```
92
93
### Constant-Time Comparison
94
95
Secure comparison function that prevents timing attacks.
96
97
```javascript { .api }
98
/**
99
* Compares two arrays in constant time to prevent timing attacks
100
* @param {Uint8Array} x - First array to compare
101
* @param {Uint8Array} y - Second array to compare
102
* @returns {boolean} True if arrays are equal and non-zero length, false otherwise
103
*/
104
nacl.verify(x, y): boolean
105
```
106
107
**Usage Examples:**
108
109
```javascript
110
const nacl = require('tweetnacl');
111
112
// Compare authentication tokens safely
113
function verifyToken(receivedToken, expectedToken) {
114
return nacl.verify(receivedToken, expectedToken);
115
}
116
117
const token1 = new TextEncoder().encode("secret-token-123");
118
const token2 = new TextEncoder().encode("secret-token-123");
119
const token3 = new TextEncoder().encode("secret-token-456");
120
121
console.log(nacl.verify(token1, token2)); // true
122
console.log(nacl.verify(token1, token3)); // false
123
124
// Verify hashes securely
125
const data = new TextEncoder().encode("important data");
126
const hash1 = nacl.hash(data);
127
const hash2 = nacl.hash(data);
128
129
console.log(nacl.verify(hash1, hash2)); // true
130
```
131
132
**Important Timing Attack Prevention:**
133
134
```javascript
135
const nacl = require('tweetnacl');
136
137
// WRONG: Vulnerable to timing attacks
138
function unsafeVerify(received, expected) {
139
if (received.length !== expected.length) return false;
140
for (let i = 0; i < received.length; i++) {
141
if (received[i] !== expected[i]) return false; // Early return leaks timing
142
}
143
return true;
144
}
145
146
// CORRECT: Constant-time comparison
147
function safeVerify(received, expected) {
148
return nacl.verify(received, expected);
149
}
150
```
151
152
### PRNG Configuration
153
154
Configure custom pseudo-random number generator for environments without standard crypto APIs.
155
156
```javascript { .api }
157
/**
158
* Sets a custom pseudo-random number generator function
159
* @param {function} fn - Function that fills array with random bytes: (x: Uint8Array, n: number) => void
160
* @returns {void}
161
*/
162
nacl.setPRNG(fn): void
163
```
164
165
**Usage Example:**
166
167
```javascript
168
const nacl = require('tweetnacl');
169
170
// Custom PRNG implementation (example only - don't use in production)
171
function customPRNG(x, n) {
172
// This is just an example - use a cryptographically secure source
173
const crypto = require('crypto');
174
const bytes = crypto.randomBytes(n);
175
for (let i = 0; i < n; i++) {
176
x[i] = bytes[i];
177
}
178
}
179
180
// Set custom PRNG
181
nacl.setPRNG(customPRNG);
182
183
// Now randomBytes will use the custom function
184
const randomData = nacl.randomBytes(32);
185
```
186
187
**Platform Detection Example:**
188
189
```javascript
190
// TweetNaCl.js automatically detects and configures PRNG based on environment:
191
192
// Browser: Uses window.crypto.getRandomValues or window.msCrypto.getRandomValues
193
// Node.js: Uses crypto.randomBytes
194
// Custom: Can be overridden with nacl.setPRNG
195
196
// Check if PRNG is available
197
try {
198
nacl.randomBytes(1);
199
console.log("Secure PRNG is available");
200
} catch (error) {
201
console.log("No secure PRNG available - need to configure one");
202
// Set custom PRNG here
203
}
204
```
205
206
## Constants
207
208
```javascript { .api }
209
nacl.hash.hashLength: number // 64 - Length of SHA-512 hash in bytes
210
```
211
212
## Security Considerations
213
214
### Random Number Generation
215
216
- **Platform Security**: TweetNaCl.js automatically uses the most secure random source available on each platform.
217
- **Custom PRNG**: Only use `setPRNG` if you understand cryptographic security requirements. Poor random sources break security.
218
- **Fallback Handling**: If no secure PRNG is available, functions requiring randomness will throw exceptions.
219
220
### Constant-Time Operations
221
222
- **Timing Attacks**: Always use `nacl.verify` for comparing sensitive data like tokens, hashes, or MACs.
223
- **Early Returns**: Never use standard comparison operators for security-sensitive comparisons.
224
- **Zero-Length Arrays**: `nacl.verify` returns false for zero-length arrays to prevent edge case vulnerabilities.
225
226
### Hashing
227
228
- **One-Way Function**: SHA-512 is cryptographically one-way - hashes cannot be reversed to recover original data.
229
- **Collision Resistance**: SHA-512 is designed to prevent finding two inputs that produce the same hash.
230
- **Key Derivation**: For deriving keys from passwords, consider using key derivation functions like PBKDF2 or scrypt instead of plain hashing.
231
232
## Integration with Other Functions
233
234
These utilities are used throughout TweetNaCl.js:
235
236
- `randomBytes`: Used by key generation functions (`nacl.box.keyPair`, `nacl.sign.keyPair`)
237
- `hash`: Used internally by signing operations and can be used for custom key derivation
238
- `verify`: Essential for secure token/MAC verification in custom authentication schemes
239
- `setPRNG`: Allows customization for specialized environments or testing scenarios