Skip to main content

Try it Live

Run BLS12-381 examples in the interactive playground
Future Plans: This page is planned and under active development. Examples are placeholders and will be replaced with accurate, tested content.

G1 Operations

G1 is the base field elliptic curve group used for BLS signatures. Points are 48 bytes compressed or 96 bytes uncompressed.

G1 Curve Equation

y² = x³ + 4 over Fp
Base Field: Fp (381-bit prime) Group Order: r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 Cofactor: h = 1 (prime order group)

Point Formats

Uncompressed (96 bytes, padded to 128 for precompiles)

| x-coordinate | y-coordinate |
|   48 bytes   |   48 bytes   |
| (padded 64)  | (padded 64)  |

Compressed (48 bytes)

MSB flags:
  • Bit 7: compression flag (1)
  • Bit 6: infinity flag
  • Bit 5: y-coordinate sign
  • Bits 0-4: part of x-coordinate

Operations

Point Addition

Add two G1 points using EIP-2537 format:
import { bls12_381 } from '@tevm/voltaire/crypto';

const p1 = new Uint8Array(128); // First G1 point
const p2 = new Uint8Array(128); // Second G1 point

const input = new Uint8Array(256);
input.set(p1, 0);
input.set(p2, 128);

const output = new Uint8Array(128);
await bls12_381.g1Add(input, output);
Gas Cost: 500 (EIP-2537) Time: ~15 μs (native)

Scalar Multiplication

Multiply G1 point by scalar:
const point = new Uint8Array(128);
const scalar = Bytes32(); // Fr element

const input = new Uint8Array(160);
input.set(point, 0);
input.set(scalar, 128);

const output = new Uint8Array(128);
await bls12_381.g1Mul(input, output);
Algorithm: GLV (Gallant-Lambert-Vanstone) endomorphism Gas Cost: 12,000 (EIP-2537) Time: ~80 μs (native)

Multi-Scalar Multiplication (MSM)

Compute sum(scalar_i * point_i) efficiently:
const n = 100; // number of points
const input = new Uint8Array(160 * n);

for (let i = 0; i < n; i++) {
  const offset = 160 * i;
  input.set(points[i], offset);      // 128 bytes
  input.set(scalars[i], offset + 128); // 32 bytes
}

const output = new Uint8Array(128);
await bls12_381.g1Msm(input, output);
Algorithm: Pippenger’s algorithm Gas Cost: Variable (discount for batch) Time: ~8ms for 100 points (vs ~8ms for 100 individual muls)

Infinity Point

Point at infinity is the identity element:
const infinity = new Uint8Array(128);
// All zeros represents infinity

// Adding infinity to any point returns that point
const result = await g1Add(point, infinity);
// result === point

Subgroup Membership

All points in G1 are in the prime-order subgroup (cofactor = 1). No additional subgroup check needed beyond curve equation validation.

Performance

Native (BLST on x86_64):
  • Addition: ~15 μs
  • Doubling: ~12 μs
  • Scalar mul: ~80 μs
  • MSM (100): ~8 ms (~80 μs per point)
  • MSM (1000): ~45 ms (~45 μs per point)
Speedup Techniques:
  • Endomorphism decomposition (GLV)
  • Precomputed multiples
  • Batch inversion for affine conversion

Use Cases

  • BLS signature storage (48 bytes compressed)
  • Message hashing (hash-to-curve → G1)
  • Signature aggregation (G1 addition)
  • Proof generation (MSM for commitment schemes)