Skip to main 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)