> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Keystore Encryption

> How to encrypt private keys using Web3 Secret Storage

## Overview

Keystore encryption transforms a raw private key into a password-protected JSON structure. The process uses key derivation functions (KDF) and symmetric encryption to ensure the private key cannot be recovered without the correct password.

## Encryption Process

### Algorithm Flow

```
Password + Salt
       │
       ▼
   ┌───────┐
   │  KDF  │ (scrypt or PBKDF2)
   └───────┘
       │
       ▼
 Derived Key (32 bytes)
       │
       ├──────────────────┐
       │                  │
       ▼                  ▼
 Encryption Key     MAC Key
  (16 bytes)       (16 bytes)
       │                  │
       ▼                  │
┌─────────────┐           │
│ AES-128-CTR │           │
└─────────────┘           │
       │                  │
       ▼                  │
   Ciphertext ───────────►│
                          │
                          ▼
                   ┌─────────────┐
                   │ Keccak256   │
                   │(MAC Key +   │
                   │ Ciphertext) │
                   └─────────────┘
                          │
                          ▼
                        MAC
```

### Step by Step

1. **Generate random salt** (32 bytes) and **IV** (16 bytes)
2. **Derive key** from password using KDF (scrypt or PBKDF2)
3. **Split derived key**: first 16 bytes for encryption, next 16 for MAC
4. **Encrypt private key** with AES-128-CTR using encryption key and IV
5. **Compute MAC** as `keccak256(macKey || ciphertext)`
6. **Assemble keystore** JSON structure

## Basic Encryption

```typescript theme={null}
import * as Keystore from '@tevm/voltaire/crypto/Keystore';
import * as PrivateKey from '@tevm/voltaire/PrivateKey';

const privateKey = PrivateKey.from(
  '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
);

// Default encryption (scrypt)
const keystore = await Keystore.encrypt(privateKey, 'my-password');

console.log(JSON.stringify(keystore, null, 2));
```

Output:

```json theme={null}
{
  "version": 3,
  "id": "e4b8a7c2-1234-5678-9abc-def012345678",
  "crypto": {
    "cipher": "aes-128-ctr",
    "ciphertext": "a7b8c9d0e1f2...",
    "cipherparams": {
      "iv": "1a2b3c4d5e6f..."
    },
    "kdf": "scrypt",
    "kdfparams": {
      "dklen": 32,
      "n": 262144,
      "r": 8,
      "p": 1,
      "salt": "9a8b7c6d5e4f..."
    },
    "mac": "f1e2d3c4b5a6..."
  }
}
```

## Encryption Options

### KDF Selection

<Tabs>
  <Tab title="Scrypt (Default)">
    ```typescript theme={null}
    // Scrypt - memory-hard, GPU-resistant (recommended)
    const keystore = await Keystore.encrypt(privateKey, password, {
      kdf: 'scrypt'
    });
    ```

    **Pros:**

    * Memory-hard (expensive to parallelize)
    * GPU/ASIC resistant
    * Higher security against brute-force

    **Cons:**

    * Slower (\~2-5 seconds default)
    * Higher memory usage
  </Tab>

  <Tab title="PBKDF2">
    ```typescript theme={null}
    // PBKDF2 - faster, widely supported
    const keystore = await Keystore.encrypt(privateKey, password, {
      kdf: 'pbkdf2'
    });
    ```

    **Pros:**

    * Faster (\~500ms default)
    * Lower memory usage
    * Widely supported

    **Cons:**

    * Not memory-hard
    * GPU-parallelizable
    * Lower security per iteration
  </Tab>
</Tabs>

### Scrypt Parameters

```typescript theme={null}
const keystore = await Keystore.encrypt(privateKey, password, {
  kdf: 'scrypt',
  scryptN: 262144,  // CPU/memory cost (power of 2)
  scryptR: 8,       // Block size
  scryptP: 1        // Parallelization factor
});
```

| Parameter | Default | Description                                          |
| --------- | ------- | ---------------------------------------------------- |
| `scryptN` | 262144  | CPU/memory cost (2^18). Higher = slower, more secure |
| `scryptR` | 8       | Block size. Higher = more memory                     |
| `scryptP` | 1       | Parallelization. Higher = more parallelizable        |

**Memory formula:** `128 * N * r * p` bytes

Default: `128 * 262144 * 8 * 1 = 256 MB`

### PBKDF2 Parameters

```typescript theme={null}
const keystore = await Keystore.encrypt(privateKey, password, {
  kdf: 'pbkdf2',
  pbkdf2C: 262144  // Iteration count
});
```

| Parameter | Default | Description                                   |
| --------- | ------- | --------------------------------------------- |
| `pbkdf2C` | 262144  | Iteration count. Higher = slower, more secure |

### Custom Salt and IV

```typescript theme={null}
// For deterministic testing or specific requirements
const salt = new Uint8Array(32);
crypto.getRandomValues(salt);

const iv = new Uint8Array(16);
crypto.getRandomValues(iv);

const keystore = await Keystore.encrypt(privateKey, password, {
  salt,
  iv
});
```

<Warning>
  Only provide custom salt/IV for testing or specific compliance requirements. Random generation (default) is recommended for security.
</Warning>

### Custom UUID

```typescript theme={null}
const keystore = await Keystore.encrypt(privateKey, password, {
  uuid: 'my-custom-uuid-12345678'
});

console.log(keystore.id); // 'my-custom-uuid-12345678'
```

## Performance Tuning

### Fast Encryption (Testing/Development)

```typescript theme={null}
// Much faster (~50-100ms) but less secure
const keystore = await Keystore.encrypt(privateKey, password, {
  kdf: 'scrypt',
  scryptN: 1024,  // Very low
  scryptR: 1,
  scryptP: 1
});
```

### Balanced (Mobile/Web)

```typescript theme={null}
// Balance of speed and security (~200-500ms)
const keystore = await Keystore.encrypt(privateKey, password, {
  kdf: 'scrypt',
  scryptN: 16384,
  scryptR: 8,
  scryptP: 1
});
```

### Maximum Security (Cold Storage)

```typescript theme={null}
// Slower (~10-30s) but maximum security
const keystore = await Keystore.encrypt(privateKey, password, {
  kdf: 'scrypt',
  scryptN: 1048576,  // 2^20
  scryptR: 8,
  scryptP: 1
});
```

## Error Handling

```typescript theme={null}
import * as Keystore from '@tevm/voltaire/crypto/Keystore';

try {
  const keystore = await Keystore.encrypt(privateKey, password);
  console.log('Encryption successful');
} catch (error) {
  if (error instanceof Keystore.EncryptionError) {
    console.error('Encryption failed:', error.message);
  }
}
```

## Advanced Usage

### Deterministic Encryption (Testing)

```typescript theme={null}
// Same inputs = same output (for testing only)
const fixedSalt = new Uint8Array(32).fill(1);
const fixedIv = new Uint8Array(16).fill(2);
const fixedUuid = 'test-uuid-12345678';

const keystore1 = await Keystore.encrypt(privateKey, password, {
  salt: fixedSalt,
  iv: fixedIv,
  uuid: fixedUuid
});

const keystore2 = await Keystore.encrypt(privateKey, password, {
  salt: fixedSalt,
  iv: fixedIv,
  uuid: fixedUuid
});

// keystore1 and keystore2 are identical
```

### Batch Encryption

```typescript theme={null}
async function encryptMultiple(privateKeys, password) {
  return Promise.all(
    privateKeys.map(pk => Keystore.encrypt(pk, password))
  );
}

const keystores = await encryptMultiple(
  [privateKey1, privateKey2, privateKey3],
  'shared-password'
);
```

### Progress Indication

Since encryption can take several seconds with default parameters:

```typescript theme={null}
async function encryptWithProgress(privateKey, password, onProgress) {
  onProgress('Generating salt and IV...');

  onProgress('Deriving key (this may take a moment)...');
  const keystore = await Keystore.encrypt(privateKey, password);

  onProgress('Complete!');
  return keystore;
}

// Usage
const keystore = await encryptWithProgress(
  privateKey,
  password,
  (status) => console.log(status)
);
```

## Encryption Components Explained

### Salt

* **Purpose:** Ensures different derived keys for same password
* **Size:** 32 bytes (256 bits)
* **Generation:** `crypto.getRandomValues()`
* **Storage:** Stored in `kdfparams.salt` (hex-encoded)

### IV (Initialization Vector)

* **Purpose:** Ensures different ciphertexts for same key
* **Size:** 16 bytes (128 bits)
* **Generation:** `crypto.getRandomValues()`
* **Storage:** Stored in `cipherparams.iv` (hex-encoded)

### Derived Key

* **Purpose:** Convert password to fixed-length encryption key
* **Size:** 32 bytes (256 bits)
* **Split:** First 16 bytes = encryption key, last 16 bytes = MAC key

### MAC (Message Authentication Code)

* **Purpose:** Verify password correctness and data integrity
* **Algorithm:** Keccak256
* **Input:** `macKey || ciphertext`
* **Size:** 32 bytes (256 bits)

## References

* [Web3 Secret Storage Definition](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition)
* [Scrypt Paper](https://www.tarsnap.com/scrypt/scrypt.pdf)
* [AES-CTR Mode (NIST SP 800-38A)](https://csrc.nist.gov/publications/detail/sp/800-38a/final)
