> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/a16z/jolt/llms.txt
> Use this file to discover all available pages before exploring further.

# Grumpkin Inline

> High-performance Grumpkin elliptic curve operations for Jolt zkVM

## Overview

The Grumpkin inline provides optimized elliptic curve operations for the Grumpkin curve, which is the cycle curve for BN254. This makes it particularly useful for recursive proof systems and applications built on top of BN254-based SNARKs.

## API Reference

### `GrumpkinFq`

Base field element (point coordinates).

```rust theme={null}
pub struct GrumpkinFq {
    e: ark_grumpkin::Fq,  // Montgomery form internally
}
```

#### Methods

```rust theme={null}
pub fn new(e: Fq) -> Self;
pub fn from_u64_arr(arr: &[u64; 4]) -> Result<Self, GrumpkinError>;
pub fn from_u64_arr_unchecked(arr: &[u64; 4]) -> Self;
pub fn fq(&self) -> Fq;
pub fn zero() -> Self;
pub fn negative_seventeen() -> Self;  // Curve constant
pub fn is_zero(&self) -> bool;
pub fn neg(&self) -> Self;
pub fn add(&self, other: &GrumpkinFq) -> Self;
pub fn sub(&self, other: &GrumpkinFq) -> Self;
pub fn dbl(&self) -> Self;
pub fn tpl(&self) -> Self;
pub fn mul(&self, other: &GrumpkinFq) -> Self;
pub fn square(&self) -> Self;
pub fn div(&self, other: &GrumpkinFq) -> Self;                    // Uses inline
pub fn div_assume_nonzero(&self, other: &GrumpkinFq) -> Self;     // Uses inline
```

### `GrumpkinFr`

Scalar field element (private keys, scalars).

```rust theme={null}
pub struct GrumpkinFr {
    e: ark_grumpkin::Fr,  // Montgomery form internally
}
```

#### Methods

```rust theme={null}
pub fn new(e: Fr) -> Self;
pub fn from_u64_arr(arr: &[u64; 4]) -> Result<Self, GrumpkinError>;
pub fn from_u64_arr_unchecked(arr: &[u64; 4]) -> Self;
pub fn fr(&self) -> Fr;
pub fn zero() -> Self;
pub fn is_zero(&self) -> bool;
pub fn neg(&self) -> Self;
pub fn add(&self, other: &GrumpkinFr) -> Self;
pub fn sub(&self, other: &GrumpkinFr) -> Self;
pub fn mul(&self, other: &GrumpkinFr) -> Self;
pub fn square(&self) -> Self;
pub fn div(&self, other: &GrumpkinFr) -> Self;                    // Uses inline
pub fn div_assume_nonzero(&self, other: &GrumpkinFr) -> Self;     // Uses inline
```

### `GrumpkinPoint`

Affine point on the Grumpkin curve.

```rust theme={null}
pub struct GrumpkinPoint {
    x: GrumpkinFq,
    y: GrumpkinFq,
}
```

#### Methods

```rust theme={null}
pub fn new(x: GrumpkinFq, y: GrumpkinFq) -> Result<Self, GrumpkinError>;
pub fn new_unchecked(x: GrumpkinFq, y: GrumpkinFq) -> Self;
pub fn from_u64_arr(arr: &[u64; 8]) -> Result<Self, GrumpkinError>;
pub fn from_u64_arr_unchecked(arr: &[u64; 8]) -> Self;
pub fn to_u64_arr(&self) -> [u64; 8];  // Returns Montgomery form
pub fn x(&self) -> GrumpkinFq;
pub fn y(&self) -> GrumpkinFq;
pub fn generator() -> Self;
pub fn infinity() -> Self;              // Represented as (0, 0)
pub fn is_infinity(&self) -> bool;
pub fn is_on_curve(&self) -> bool;
pub fn neg(&self) -> Self;
pub fn double(&self) -> Self;
pub fn add(&self, other: &GrumpkinPoint) -> Self;
pub fn double_and_add(&self, other: &GrumpkinPoint) -> Self;
```

### Error Handling

```rust theme={null}
pub trait UnwrapOrSpoilProof<T> {
    fn unwrap_or_spoil_proof(self) -> T;
}

impl<T> UnwrapOrSpoilProof<T> for Result<T, GrumpkinError> { /* ... */ }
```

Use `.unwrap_or_spoil_proof()` to make proofs unsatisfiable on error.

## Usage Examples

### Point Addition

```rust theme={null}
use grumpkin_inline::GrumpkinPoint;

#[jolt::provable]
fn add_points(p1: [u64; 8], p2: [u64; 8]) -> [u64; 8] {
    let point1 = GrumpkinPoint::from_u64_arr(&p1).unwrap();
    let point2 = GrumpkinPoint::from_u64_arr(&p2).unwrap();
    point1.add(&point2).to_u64_arr()
}
```

### Field Division

```rust theme={null}
use grumpkin_inline::GrumpkinFq;

#[jolt::provable]
fn field_inverse(x: [u64; 4]) -> [u64; 4] {
    let elem = GrumpkinFq::from_u64_arr(&x).unwrap();
    let one = GrumpkinFq::from_u64_arr(&[1, 0, 0, 0]).unwrap();
    let inv = one.div(&elem);  // Uses inline
    inv.fq().into_bigint().0
}
```

### Pedersen Hash Commitment

```rust theme={null}
use grumpkin_inline::{GrumpkinPoint, GrumpkinFr};

#[jolt::provable]
fn pedersen_commit(
    message: [u64; 4],
    randomness: [u64; 4],
    base1: [u64; 8],
    base2: [u64; 8],
) -> [u64; 8] {
    let m = GrumpkinFr::from_u64_arr(&message).unwrap();
    let r = GrumpkinFr::from_u64_arr(&randomness).unwrap();
    let g = GrumpkinPoint::from_u64_arr(&base1).unwrap();
    let h = GrumpkinPoint::from_u64_arr(&base2).unwrap();
    
    // Compute m·G + r·H (simplified - actual scalar mul omitted)
    // This is a conceptual example
    g.add(&h).to_u64_arr()
}
```

### Verify Point on Curve

```rust theme={null}
use grumpkin_inline::{GrumpkinPoint, UnwrapOrSpoilProof};

#[jolt::provable]
fn verify_point_valid(point: [u64; 8]) {
    // If point is not on curve, proof becomes unsatisfiable
    GrumpkinPoint::from_u64_arr(&point).unwrap_or_spoil_proof();
}
```

## Implementation Details

### Curve Equation

Grumpkin: `y² = x³ - 17` over the prime field:

```rust theme={null}
q = BN254 scalar field modulus
  = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
```

Scalar field:

```rust theme={null}
r = BN254 base field modulus  
  = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
```

### Cycle Curve Property

Grumpkin forms a cycle with BN254:

* Grumpkin base field = BN254 scalar field
* Grumpkin scalar field = BN254 base field

This enables efficient recursive proof composition.

### Custom Instructions

The Grumpkin inline provides two advice-only instructions:

1. **`GRUMPKIN_DIVQ_ADV`** (funct3=0x00): Base field division (pure advice, verified)
2. **`GRUMPKIN_DIVR_ADV`** (funct3=0x01): Scalar field division (pure advice, verified)

Both instructions are "advice-only" meaning they provide non-deterministic hints that are then verified:

```rust theme={null}
// Inline provides c as advice
let c = div_inline_advice(a, b);
// Then verify: b * c == a
if b.mul(&c) != a {
    hcf();  // Spoil proof if advice is incorrect
}
```

### Montgomery Form

The implementation uses arkworks' Montgomery form internally:

* Conversions happen at boundaries (`from_u64_arr`, `to_u64_arr`)
* Addition/subtraction work identically in Montgomery and standard form
* Multiplication/division use arkworks on host, inline on guest

### Infinity Representation

Infinity is represented as `(0, 0)` since this point is not on the curve `y² = x³ - 17`:

```rust theme={null}
// For (0, 0): 0² = 0 ≠ 0³ - 17 = -17
```

### Optimized Double-and-Add

The `double_and_add()` method computes `2·P + Q` more efficiently than separate operations:

```rust theme={null}
// Standard: 2 field divisions
let r = p.double();
let result = r.add(&q);

// Optimized: 1 field division (plus other operations)
let result = p.double_and_add(&q);
```

## Error Types

```rust theme={null}
pub enum GrumpkinError {
    InvalidFqElement,  // Value ≥ q
    InvalidFrElement,  // Value ≥ r
    NotOnCurve,        // Point not on y² = x³ - 17
}
```

## Constants

```rust theme={null}
pub const INLINE_OPCODE: u32 = 0x0B;
pub const GRUMPKIN_FUNCT7: u32 = 0x06;

pub const GRUMPKIN_DIVQ_ADV_FUNCT3: u32 = 0x00;
pub const GRUMPKIN_DIVQ_ADV_NAME: &str = "GRUMPKIN_DIVQ_ADV";

pub const GRUMPKIN_DIVR_ADV_FUNCT3: u32 = 0x01;
pub const GRUMPKIN_DIVR_ADV_NAME: &str = "GRUMPKIN_DIVR_ADV";
```

## Performance Characteristics

* **Field division**: \~10-20x faster than pure arkworks
* **Point operations**: Proportionally faster due to division acceleration
* **Advice verification**: Minimal overhead for correctness checks

## Comparison with secp256k1 Inline

| Feature    | secp256k1                   | Grumpkin               |
| ---------- | --------------------------- | ---------------------- |
| Field form | Standard (non-Montgomery)   | Montgomery             |
| Mul inline | Full computation            | N/A (uses arkworks)    |
| Div inline | Full computation            | Advice + verification  |
| GLV        | Yes                         | No                     |
| Use case   | Bitcoin/Ethereum signatures | BN254 recursive proofs |

## Feature Flags

* **`host`**: Enables reference implementation for host-side execution
  * Guest code: Compile WITHOUT this feature
  * Prover code: Compile WITH this feature

## Source Code Location

```
jolt-inlines/grumpkin/
├── src/
│   ├── lib.rs          # Module definitions and constants
│   ├── sdk.rs          # Public API (564 lines)
│   ├── sequence_builder.rs  # Instruction sequences
│   └── host.rs         # Host-side registration
└── Cargo.toml
```

## See Also

* [secp256k1](/api/inlines/secp256k1) - Bitcoin/Ethereum curve
* [BigInt](/api/inlines/bigint) - Used internally for field operations
* [Inlines Overview](/api/inlines/overview) - General information about cryptographic inlines
