# mozz.mutator

> A module of mozz_mlake's API.

Byte-level mutation operators for fuzzing.

Seven shipped mutators plus a weighted ``MutatorChain`` that picks one at
random.  All mutators take a ``Span[UInt8, _]`` input and return a new
``List[UInt8]`` — they never mutate in place.

Use ``default_mutator()`` to get the standard weighted chain used by
``fuzz()``.

Example:
    ```mojo
    var rng = Xoshiro256(seed=1)
    var chain = default_mutator()
    var input = List[UInt8](0x48, 0x65, 0x6C, 0x6C, 0x6F)  # "Hello"
    var mutated = chain.mutate(Span[UInt8, _](input), rng)
    ```

## Structs

### `MutatorId`

```mojo
struct MutatorId
```

Integer IDs for each built-in mutator (used by ``MutatorChain``).

Implements: `Movable`

#### `BIT_FLIP`

```mojo
comptime BIT_FLIP = Int(0)
```

#### `BYTE_SUBSTITUTION`

```mojo
comptime BYTE_SUBSTITUTION = Int(1)
```

#### `BYTE_INSERTION`

```mojo
comptime BYTE_INSERTION = Int(2)
```

#### `BYTE_DELETION`

```mojo
comptime BYTE_DELETION = Int(3)
```

#### `BLOCK_DUPLICATION`

```mojo
comptime BLOCK_DUPLICATION = Int(4)
```

#### `SPLICE`

```mojo
comptime SPLICE = Int(5)
```

#### `BOUNDARY_INT`

```mojo
comptime BOUNDARY_INT = Int(6)
```

### `BitFlip`

```mojo
struct BitFlip
```

Flip 1–4 random bits at random positions.

Effective for discovering off-by-one errors and flag-dependent branches.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a BitFlip mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Flip 1–4 random bits in a copy of ``input``.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `ByteSubstitution`

```mojo
struct ByteSubstitution
```

Replace 1–4 bytes with random or boundary values.

Boundary values (0x00, 0x7F, 0x80, 0xFF, etc.) are chosen with 30%
probability to hit common parser edge cases.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a ByteSubstitution mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Replace 1–4 bytes with random or boundary values.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `ByteInsertion`

```mojo
struct ByteInsertion
```

Insert 1–8 random bytes at a random position.

Exercises length-parsing code paths that may assume fixed-size fields.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a ByteInsertion mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Insert 1–8 random bytes at a random position.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `ByteDeletion`

```mojo
struct ByteDeletion
```

Delete 1–8 bytes at a random position.

Exercises length checks and under-read recovery paths.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a ByteDeletion mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Delete 1–8 bytes starting at a random position.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `BlockDuplication`

```mojo
struct BlockDuplication
```

Duplicate a random 1–32 byte slice and insert it elsewhere.

Useful for exercising repeated-field parsers and length-prefix bugs.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a BlockDuplication mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Copy a random block and insert it at a random position.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `Splice`

```mojo
struct Splice
```

Splice the tail of a second corpus entry onto the current input.

Cross-pollination across corpus seeds can expose stateful interaction
bugs that single-input mutation misses.

When no second seed is available the input is returned unchanged.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, corpus: List[List[UInt8]])
```

Create a Splice mutator with a snapshot of the corpus.

Args:

- `corpus`: Current corpus seeds (copied for safety).

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Splice a random corpus entry onto the first half of ``input``.

Args:

- `input`: The primary input bytes.
- `rng`: PRNG state (advanced in-place).

### `BoundaryInt`

```mojo
struct BoundaryInt
```

Replace a 1–2 byte run with an interesting integer boundary value.

Targets off-by-one errors on integer boundaries commonly exploitable in
binary protocol parsers (e.g. payload-length fields).

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self)
```

Create a BoundaryInt mutator.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Replace 1 or 2 bytes at a random position with a boundary value.

Args:

- `input`: The input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

### `MutatorChain`

```mojo
struct MutatorChain
```

Randomly selects one mutator from a weighted list and applies it.

Weights are cumulative; selection is O(n) weighted-random using the
total weight sum.

Example:
```mojo
var chain = default_mutator()
var out = chain.mutate(Span[UInt8, _](input), rng)
```

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, ids: List[Int], weights: List[UInt32], corpus: List[List[UInt8]] = List())
```

Construct a chain with the given mutator IDs and weights.

Args:

- `ids`: List of ``MutatorId.*`` constants.
- `weights`: Parallel list of positive integer weights.
- `corpus`: Optional corpus snapshot for ``Splice`` (may be empty).

#### `update_corpus`

```mojo
def update_corpus(mut self, corpus: List[List[UInt8]])
```

Refresh the corpus snapshot used by the ``Splice`` mutator.

Args:

- `corpus`: Updated corpus seeds.

#### `mutate`

```mojo
def mutate(self, input: Span[UInt8], mut rng: Xoshiro256) -> List[UInt8]
```

Pick a mutator by weighted random draw and apply it.

Args:

- `input`: Input bytes to mutate.
- `rng`: PRNG state (advanced in-place).

## Functions

### `default_mutator`

```mojo
def default_mutator() -> MutatorChain
```

Return the standard weighted mutator chain used by ``fuzz()``.

Default weights:
- ``BitFlip``: 30
- ``ByteSubstitution``: 25
- ``ByteInsertion``: 15
- ``ByteDeletion``: 10
- ``BlockDuplication``: 10
- ``Splice``: 5
- ``BoundaryInt``: 5
