0
# Utility Functions
1
2
Essential utility functions for byte manipulation, hashing, key derivation operations, and mathematical utilities. These functions support the core cryptographic operations and provide common helpers for working with ed25519.
3
4
## Capabilities
5
6
### Byte Utilities
7
8
The `etc` object provides essential utilities for byte manipulation and mathematical operations.
9
10
```typescript { .api }
11
const etc: {
12
/** Convert bytes to hex string */
13
bytesToHex(b: Bytes): string;
14
15
/** Convert hex string to bytes */
16
hexToBytes(hex: string): Bytes;
17
18
/** Concatenate multiple byte arrays */
19
concatBytes(...arrs: Bytes[]): Bytes;
20
21
/** Modular arithmetic operation */
22
mod(a: bigint, b?: bigint): bigint;
23
24
/** Modular inversion */
25
invert(num: bigint, md: bigint): bigint;
26
27
/** Generate cryptographically secure random bytes */
28
randomBytes(len?: number): Bytes;
29
};
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { etc } from '@noble/ed25519';
36
37
// Hex conversion
38
const bytes = new Uint8Array([255, 0, 128, 64]);
39
const hex = etc.bytesToHex(bytes); // "ff008040"
40
const restored = etc.hexToBytes(hex);
41
console.log(bytes.every((b, i) => b === restored[i])); // true
42
43
// Byte concatenation
44
const part1 = new Uint8Array([1, 2, 3]);
45
const part2 = new Uint8Array([4, 5, 6]);
46
const combined = etc.concatBytes(part1, part2); // [1, 2, 3, 4, 5, 6]
47
48
// Random bytes generation
49
const randomKey = etc.randomBytes(32); // 32 random bytes
50
const randomNonce = etc.randomBytes(); // Default length
51
52
// Mathematical operations
53
const result = etc.mod(17n, 5n); // 2n
54
const inverse = etc.invert(3n, 7n); // Modular inverse of 3 mod 7
55
```
56
57
### Hash Functions
58
59
The `hashes` object provides access to SHA-512 hash functions required for ed25519 operations.
60
61
```typescript { .api }
62
const hashes: {
63
/** Asynchronous SHA-512 hash function using WebCrypto */
64
sha512Async(message: Bytes): Promise<Bytes>;
65
66
/** Synchronous SHA-512 hash function (must be set by user) */
67
sha512: undefined | ((message: Bytes) => Bytes);
68
};
69
70
/** Convenience alias for hashes.sha512Async - asynchronous hash function */
71
function hash(msg: Bytes): Promise<Bytes>;
72
```
73
74
**Usage Examples:**
75
76
```typescript
77
import { hashes, hash } from '@noble/ed25519';
78
79
// Async hashing (works out of the box)
80
const message = new TextEncoder().encode('Hello, World!');
81
const hashAsync = await hashes.sha512Async(message);
82
83
// Using the convenience function (async)
84
const hashResult = await hash(message);
85
86
// Setting up sync hashing
87
import { sha512 } from '@noble/hashes/sha512';
88
hashes.sha512 = sha512;
89
90
// Now sync operations work
91
const syncHash = hashes.sha512(message);
92
console.log(Buffer.from(hashAsync).equals(Buffer.from(syncHash))); // true
93
```
94
95
### Advanced Key Utilities
96
97
The `utils` object provides advanced key derivation and management functions.
98
99
```typescript { .api }
100
const utils: {
101
/** Get extended public key information asynchronously */
102
getExtendedPublicKeyAsync(secretKey: Bytes): Promise<ExtK>;
103
104
/** Get extended public key information synchronously (requires hashes.sha512) */
105
getExtendedPublicKey(secretKey: Bytes): ExtK;
106
107
/** Generate random secret key with optional seed */
108
randomSecretKey(seed?: Bytes): Bytes;
109
};
110
111
/** Extended key information structure */
112
type ExtK = {
113
/** First 32 bytes of SHA-512(secretKey) */
114
head: Bytes;
115
/** Second 32 bytes of SHA-512(secretKey) used as prefix */
116
prefix: Bytes;
117
/** Scalar derived from head for key operations */
118
scalar: bigint;
119
/** Public key point */
120
point: Point;
121
/** Public key in byte representation */
122
pointBytes: Bytes;
123
};
124
```
125
126
**Usage Examples:**
127
128
```typescript
129
import { utils } from '@noble/ed25519';
130
131
// Generate random secret key
132
const secretKey = utils.randomSecretKey();
133
console.log(secretKey.length); // 32
134
135
// Deterministic key from seed
136
const seed = new Uint8Array(32).fill(42);
137
const deterministicKey = utils.randomSecretKey(seed);
138
139
// Get extended key information (async)
140
const extendedInfo = await utils.getExtendedPublicKeyAsync(secretKey);
141
console.log('Head length:', extendedInfo.head.length); // 32
142
console.log('Prefix length:', extendedInfo.prefix.length); // 32
143
console.log('Scalar:', extendedInfo.scalar);
144
console.log('Point bytes length:', extendedInfo.pointBytes.length); // 32
145
146
// Sync version (requires hash function)
147
import { sha512 } from '@noble/hashes/sha512';
148
import { hashes } from '@noble/ed25519';
149
hashes.sha512 = sha512;
150
151
const syncExtended = utils.getExtendedPublicKey(secretKey);
152
console.log('Extended keys match:',
153
Buffer.from(extendedInfo.pointBytes).equals(Buffer.from(syncExtended.pointBytes))
154
);
155
```
156
157
### Mathematical Utilities
158
159
Additional mathematical operations exposed through the `etc` object for advanced use cases.
160
161
```typescript { .api }
162
/**
163
* Modular arithmetic with optional modulus
164
* @param a - Number to reduce
165
* @param b - Modulus (defaults to curve order if not provided)
166
* @returns a mod b
167
*/
168
etc.mod(a: bigint, b?: bigint): bigint;
169
170
/**
171
* Modular multiplicative inverse
172
* @param num - Number to invert
173
* @param md - Modulus
174
* @returns Multiplicative inverse of num modulo md
175
*/
176
etc.invert(num: bigint, md: bigint): bigint;
177
```
178
179
**Usage Examples:**
180
181
```typescript
182
import { etc } from '@noble/ed25519';
183
184
// Basic modular arithmetic
185
const a = 123456789n;
186
const b = 1000n;
187
const remainder = etc.mod(a, b); // 789n
188
189
// Modular inverse for cryptographic operations
190
const num = 7n;
191
const modulus = 13n;
192
const inverse = etc.invert(num, modulus); // 2n (because 7 * 2 ≡ 1 (mod 13))
193
194
// Verify the inverse
195
const product = etc.mod(num * inverse, modulus);
196
console.log(product); // 1n
197
198
// Using with curve parameters for advanced operations
199
const curveOrder = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn;
200
const scalar = 12345n;
201
const reduced = etc.mod(scalar, curveOrder);
202
```
203
204
### Random Number Generation
205
206
Cryptographically secure random number generation for keys and nonces.
207
208
```typescript { .api }
209
/**
210
* Generate cryptographically secure random bytes using WebCrypto
211
* @param len - Number of bytes to generate (default: 32)
212
* @returns Random byte array
213
*/
214
etc.randomBytes(len?: number): Bytes;
215
216
/**
217
* Generate random secret key with optional deterministic seed
218
* @param seed - Optional seed for deterministic generation
219
* @returns 32-byte secret key
220
*/
221
utils.randomSecretKey(seed?: Bytes): Bytes;
222
```
223
224
**Usage Examples:**
225
226
```typescript
227
import { etc, utils } from '@noble/ed25519';
228
229
// Generate random bytes for various purposes
230
const nonce = etc.randomBytes(16); // 16-byte nonce
231
const salt = etc.randomBytes(32); // 32-byte salt
232
const defaultRandom = etc.randomBytes(); // 32 bytes (default)
233
234
// Generate secret keys
235
const randomSecretKey = utils.randomSecretKey();
236
const deterministicSecretKey = utils.randomSecretKey(salt);
237
238
console.log('All keys are 32 bytes:',
239
randomSecretKey.length === 32 && deterministicSecretKey.length === 32
240
);
241
```
242
243
## Error Handling
244
245
Utility functions throw errors for invalid inputs:
246
247
- Invalid hex strings in `hexToBytes`
248
- Invalid byte arrays in `bytesToHex`
249
- Division by zero in modular operations
250
- Invalid secret key formats in extended key operations
251
252
```typescript
253
import { etc, utils } from '@noble/ed25519';
254
255
try {
256
// Invalid hex string
257
etc.hexToBytes('invalid-hex-string');
258
} catch (error) {
259
console.log('Invalid hex format');
260
}
261
262
try {
263
// Invalid secret key length
264
const invalidKey = new Uint8Array(31); // Should be 32
265
await utils.getExtendedPublicKeyAsync(invalidKey);
266
} catch (error) {
267
console.log('Invalid secret key length');
268
}
269
```
270
271
## Types
272
273
```typescript { .api }
274
type Bytes = Uint8Array;
275
276
type ExtK = {
277
head: Bytes;
278
prefix: Bytes;
279
scalar: bigint;
280
point: Point;
281
pointBytes: Bytes;
282
};
283
```