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

# 0x0f BLS12-381 G2 Mul

> BLS12-381 G2 scalar multiplication

<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:** `0x000000000000000000000000000000000000000f`
**Introduced:** Prague (EIP-2537)
**EIP:** [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537)

The BLS12-381 G2 Mul precompile performs scalar multiplication on the BLS12-381 curve's G2 group. It multiplies a G2 point by a scalar, computing `scalar * point`. This operation is fundamental for BLS signature schemes, zero-knowledge proofs, and cryptographic protocols requiring operations over extension fields.

BLS12-381 provides 128 bits of security and is the foundation of Ethereum 2.0's consensus layer signature scheme.

## Gas Cost

**Fixed:** `45000` gas

## G2 vs G1

**G2 scalar multiplication** operates on points over the Fp2 extension field:

* **G1 points:** 128 bytes (2 Fp coordinates)
* **G2 points:** 256 bytes (2 Fp2 coordinates)
* **G1 mul gas:** 12,000
* **G2 mul gas:** 45,000 (3.75x more expensive)
* **Cost driver:** Extension field arithmetic is significantly more complex

## Input Format

```
Offset | Length | Description
-------|--------|-------------
0      | 64     | x.c0 (point x-coordinate c0 component, big-endian)
64     | 64     | x.c1 (point x-coordinate c1 component, big-endian)
128    | 64     | y.c0 (point y-coordinate c0 component, big-endian)
192    | 64     | y.c1 (point y-coordinate c1 component, big-endian)
256    | 32     | scalar (multiplier, big-endian)
```

Total input length: 288 bytes (256 bytes G2 point + 32 bytes scalar)

G2 point must satisfy curve equation: `y^2 = x^3 + 4(1 + u)` over Fp2.
Scalar can be any 256-bit value (automatically reduced modulo curve order).

## Output Format

```
Offset | Length | Description
-------|--------|-------------
0      | 64     | x.c0 (result point x-coordinate c0 component, big-endian)
64     | 64     | x.c1 (result point x-coordinate c1 component, big-endian)
128    | 64     | y.c0 (result point y-coordinate c0 component, big-endian)
192    | 64     | y.c1 (result point y-coordinate c1 component, big-endian)
```

Total output length: 256 bytes

## Usage Example

### TypeScript

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

// Multiply G2 point by scalar
// Using point at infinity (valid edge case: O * k = O)
const point = new Uint8Array(256); // All zeros = point at infinity

const scalar = Bytes32('0x0000000000000000000000000000000000000000000000000000000000000005'); // multiply by 5

const input = new Uint8Array(288);
input.set(point, 0);
input.set(scalar, 256);

const result = execute(
  PrecompileAddress.BLS12_G2_MUL,
  input,
  50000n,
  Hardfork.PRAGUE
);

if (result.success) {
  const resultPoint = result.output; // 256 bytes
  const xc0 = result.output.slice(0, 64);
  const xc1 = result.output.slice(64, 128);
  const yc0 = result.output.slice(128, 192);
  const yc1 = result.output.slice(192, 256);
  console.log('Result G2 point:', { xc0, xc1, yc0, yc1 });
  console.log('Gas used:', result.gasUsed); // 45000
} else {
  console.error('Error:', result.error);
}
```

### Zig

```zig theme={null}
const std = @import("std");
const precompiles = @import("precompiles");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Create input: G2 point (256 bytes) + scalar (32 bytes)
    var input = [_]u8{0} ** 288;
    // ... populate G2 point coordinates
    input[287] = 5; // scalar = 5

    // Execute G2 multiplication
    const result = try precompiles.bls12_g2_mul.execute(
        allocator,
        &input,
        100000
    );
    defer result.deinit(allocator);

    std.debug.print("Gas used: {}\n", .{result.gas_used}); // 45000
    std.debug.print("Output length: {}\n", .{result.output.len}); // 256
}
```

## Error Conditions

* **Out of gas:** gasLimit \< 45,000
* **Invalid input length:** input.len != 288
* **Point not on curve:** coordinates don't satisfy G2 curve equation
* **Invalid field element:** coordinate component >= field modulus
* **Invalid point:** point not in correct subgroup

## Use Cases

* **BLS signature verification:** Key derivation and signature operations
* **Threshold signatures:** Generate signature shares
* **Key generation:** Derive public keys from private scalars
* **Commitment schemes:** Pedersen-like commitments over G2
* **Zero-knowledge proofs:** zkSNARKs and zkSTARKs on BLS12-381
* **Ethereum 2.0:** Validator key operations

## Implementation Details

* **Zig:** Uses BLST library optimized for BLS12-381
* **TypeScript:** Wraps @noble/curves bls12-381 G2 operations
* **Algorithm:** Windowed scalar multiplication for efficiency
* **Security:** Constant-time execution prevents timing attacks
* **Optimization:** Double-and-add with precomputed tables

## Special Cases

* **Scalar = 0:** Returns point at infinity (256 bytes of zeros)
* **Scalar = 1:** Returns input point unchanged
* **Scalar = group order:** Returns point at infinity (r\*P = O)
* **Point at infinity input:** Returns point at infinity regardless of scalar
* **Scalar > group order:** Automatically reduced modulo group order

## Scalar Arithmetic

Scalars are elements of F\_r where r is the curve order:

* **Group order (r):** Same as BLS12-381 scalar field order
* **Modular reduction:** Scalars wrap around modulo r
* **Zero scalar:** Always produces point at infinity
* **Negative scalars:** Equivalent to positive via modular arithmetic

## Extension Field Operations

G2 scalar multiplication involves Fp2 arithmetic:

* **Field elements:** `a = a.c0 + a.c1*u` where u^2 + 1 = 0
* **Point doubling:** Requires Fp2 squaring and multiplication
* **Point addition:** Complex formula over extension field
* **Cost:** Each Fp2 operation is \~3-4x more expensive than Fp

This complexity explains why G2 mul is 3.75x more expensive than G1 mul.

## Gas Comparison

| Operation      | G1 Gas | G2 Gas | Ratio |
| -------------- | ------ | ------ | ----- |
| Addition       | 500    | 800    | 1.6x  |
| Multiplication | 12,000 | 45,000 | 3.75x |
| MSM (base)     | 12,000 | 45,000 | 3.75x |

The multiplication cost ratio reflects the increased complexity of extension field arithmetic.

## Performance Considerations

* **Expensive operation:** 45,000 gas is substantial
* **Batch with MSM:** For multiple scalar muls, use G2 MSM with discount
* **Precomputation:** Cache commonly used multiples when possible
* **G1 vs G2 choice:** Use G1 operations when either group works
* **Signature verification:** Typically requires 1-2 G2 muls

## Test Vectors

```typescript theme={null}
// Generator * 0 = Identity
const scalar = 0n;
const result = bls12G2Mul(G2_GENERATOR, scalar);
// result = point at infinity (256 bytes of zeros)

// Generator * 1 = Generator
const result = bls12G2Mul(G2_GENERATOR, 1n);
// result = G2_GENERATOR

// Point * group_order = Identity
const result = bls12G2Mul(somePoint, groupOrder);
// result = point at infinity
```

## BLS Signature Context

In BLS signature schemes:

* **Public keys:** Often G2 points derived via scalar multiplication
* **Signature verification:** Requires G2 scalar operations
* **Key aggregation:** Combine public keys via G2 addition
* **Threshold schemes:** Generate key shares with G2 mul

## Security Considerations

* **128-bit security:** BLS12-381 provides quantum-resistant classical security
* **Side-channel resistance:** Constant-time implementation prevents timing attacks
* **Subgroup checks:** Implementation validates points are in correct subgroup
* **Field validation:** Coordinates must be valid field elements

## Gas Cost Justification

The 45,000 gas cost reflects:

1. **Extension field arithmetic:** Fp2 operations are computationally intensive
2. **Security overhead:** Subgroup and validity checks
3. **Scalar multiplication:** Requires \~255 point operations on average
4. **Memory operations:** 256-byte point representation

Compared to BN254 mul (6,000 gas), the higher cost accounts for stronger security and extension field complexity.

## Related

* [Precompile: BLS12-381 G2 Add](/evm/precompiles/bls12-g2-add)
* [Precompile: BLS12-381 G2 MSM](/evm/precompiles/bls12-g2-msm)
* [Precompile: BLS12-381 G1 Mul](/evm/precompiles/bls12-g1-mul)
* [Precompile: BLS12-381 Pairing](/evm/precompiles/bls12-pairing)
* [Crypto: BLS12-381](/crypto/bls12-381)
* [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537)
