> ## 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.

# 0x05 ModExp

> Modular exponentiation for RSA and other cryptographic operations

<Warning>
  **This page is a placeholder.** All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
</Warning>

## Overview

**Address:** `0x0000000000000000000000000000000000000005`
**Introduced:** Byzantium (EIP-198)
**EIP:** [EIP-198](https://eips.ethereum.org/EIPS/eip-198), [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565)

The ModExp precompile computes modular exponentiation: `(base^exponent) mod modulus`. This enables efficient RSA signature verification, Fermat primality testing, and other advanced cryptographic operations in smart contracts.

EIP-198 introduced ModExp in Byzantium. EIP-2565 (Berlin) reduced gas costs to make RSA verification practical.

## Gas Cost

**Complex formula that varies by hardfork:**

Pre-Berlin: `max(200, complexity * iteration_count / GQUADDIVISOR)`
Berlin+: `max(200, complexity * iteration_count / GQUADDIVISOR_v2)`

Where:

* `complexity = mult_complexity * max(length(base), length(modulus))`
* `mult_complexity = (max(length(base), length(modulus)) / 8)^2` if max > 64, else `mult_complexity = max(length(base), length(modulus))^2 / 4`
* `iteration_count = max(exponent_bitlength - 1, 1)` adjusted for exponent head
* Minimum gas: `200`

The exact calculation is in `src/crypto/ModExp/calculateGas`

**Examples:**

* Small inputs (1-byte each): \~200 gas
* 256-byte RSA (2048-bit): \~50,000+ gas
* 512-byte RSA (4096-bit): \~200,000+ gas

## Input Format

```
Offset | Length | Description
-------|--------|-------------
0      | 32     | base_length (big-endian u256)
32     | 32     | exponent_length (big-endian u256)
64     | 32     | modulus_length (big-endian u256)
96     | base_length | base value (big-endian)
96+base_length | exponent_length | exponent value (big-endian)
96+base_length+exponent_length | modulus_length | modulus value (big-endian)
```

Minimum input length: 96 bytes (length headers only)

## Output Format

Output length equals `modulus_length` specified in input.

```
Offset | Length | Description
-------|--------|-------------
0      | modulus_length | (base^exponent mod modulus) as big-endian
```

Returns empty output if `modulus_length = 0`.

## Usage Example

```typescript theme={null}
import { execute, PrecompileAddress } from '@tevm/voltaire/precompiles';
import { Hardfork } from '@tevm/voltaire/primitives/Hardfork';
import * as Hex from '@tevm/voltaire/Hex';

// Compute 2^3 mod 5 = 8 mod 5 = 3
const input = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000001' + // base_length = 1
  '0000000000000000000000000000000000000000000000000000000000000001' + // exponent_length = 1
  '0000000000000000000000000000000000000000000000000000000000000001' + // modulus_length = 1
  '02' + // base = 2
  '03' + // exponent = 3
  '05'   // modulus = 5
);

const result = execute(
  PrecompileAddress.MODEXP,
  input,
  100000n,
  Hardfork.CANCUN
);

if (result.success) {
  console.log('Result:', result.output[0]); // 3
  console.log('Gas used:', result.gasUsed);
} else {
  console.error('Error:', result.error);
}
```

## Error Conditions

* Input length \< 96 bytes
* Out of gas (gas cost depends on input sizes)
* Modulus = 0 (returns error)
* Integer overflow in length values

## Use Cases

* **RSA signature verification:** Verify RSA-2048, RSA-4096 signatures on-chain
* **Zero-knowledge proofs:** Perform modular arithmetic for zkSNARKs
* **Cryptographic protocols:** Diffie-Hellman key exchange, ElGamal encryption
* **Primality testing:** Fermat and Miller-Rabin primality tests
* **Number theory:** Modular inverses, Chinese remainder theorem

## Implementation Details

* **Zig:** Uses multi-precision arithmetic from ModExp crypto module
* **TypeScript:** BigInt-based modular exponentiation with square-and-multiply
* **Integration:** Depends on ModExp.calculateGas for hardfork-specific gas calculation
* **Optimization:** Binary exponentiation (square-and-multiply algorithm)

## RSA Verification Example

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

// RSA-2048 verification (256-byte values)
const baseLen = 256;
const expLen = 3;  // Common public exponent: 65537
const modLen = 256;

// Example RSA-2048 input (signature verification)
const base = Hex('0x' + 'ab'.repeat(256)); // Signature (256 bytes)
const exponent = Hex('0x010001'); // Public exponent 65537 (3 bytes)
const modulus = Hex('0x' + 'cd'.repeat(256)); // RSA modulus (256 bytes)

const input = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000100' + // base_length = 256
  '0000000000000000000000000000000000000000000000000000000000000003' + // exponent_length = 3
  '0000000000000000000000000000000000000000000000000000000000000100' + // modulus_length = 256
  Hex.toHex(base).slice(2) +
  Hex.toHex(exponent).slice(2) +
  Hex.toHex(modulus).slice(2)
);

const result = execute(
  PrecompileAddress.MODEXP,
  input,
  1000000n, // RSA needs significant gas
  Hardfork.CANCUN
);

// result.output should equal expected message hash
```

## Gas Cost Reduction (EIP-2565)

Berlin hard fork (EIP-2565) reduced gas costs significantly:

| Input Size   | Pre-Berlin  | Berlin    | Reduction |
| ------------ | ----------- | --------- | --------- |
| 2048-bit RSA | \~300,000   | \~50,000  | 83%       |
| 4096-bit RSA | \~1,200,000 | \~200,000 | 83%       |

This made RSA verification practical for many use cases.

## Edge Cases

* **Zero exponent:** Returns 1 (any number to power 0 is 1)
* **Modulus = 1:** Returns 0 (anything mod 1 is 0)
* **Base > modulus:** Automatically reduced mod modulus
* **Truncated input:** Missing bytes treated as zero
* **Zero modulus:** Returns error (division by zero)

## Test Vectors

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

// Test 1: 2^3 mod 5 = 3
const input1 = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000001' + // base_len = 1
  '0000000000000000000000000000000000000000000000000000000000000001' + // exp_len = 1
  '0000000000000000000000000000000000000000000000000000000000000001' + // mod_len = 1
  '02' + '03' + '05' // base=2, exp=3, mod=5
);
// Expected: 0x03

// Test 2: 3^1 mod 5 = 3
const input2 = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '03' + '01' + '05' // base=3, exp=1, mod=5
);
// Expected: 0x03

// Test 3: 5^0 mod 7 = 1 (zero exponent)
const input3 = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '05' + '00' + '07' // base=5, exp=0, mod=7
);
// Expected: 0x01

// Test 4: Zero modulus error
const input4 = Hex(
  '0x' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '0000000000000000000000000000000000000000000000000000000000000001' +
  '02' + '03' + '00' // base=2, exp=3, mod=0
);
// Expected: Error (division by zero)
```

## References

### Specifications

* [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) - Appendix E (Precompiled Contracts)
* [EIP-198: Big Integer Modular Exponentiation](https://eips.ethereum.org/EIPS/eip-198)
* [EIP-2565: ModExp Gas Cost](https://eips.ethereum.org/EIPS/eip-2565)

### Related

* [Crypto: ModExp](/crypto/modexp)
* [Primitives: GasConstants](/primitives/gasconstants)
* [Precompiles Overview](/precompiles)
