Skip to content

Commit

Permalink
Implement bn254 (aka alt_bn128) pairings, G1, G2.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Aug 3, 2024
1 parent 3426037 commit f3ef397
Show file tree
Hide file tree
Showing 17 changed files with 2,904 additions and 1,002 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
- [ed25519, X25519, ristretto255](#ed25519-x25519-ristretto255)
- [ed448, X448, decaf448](#ed448-x448-decaf448)
- [bls12-381](#bls12-381)
- [bn254 aka alt_bn128](#bn254-aka-alt_bn128)
- [All available imports](#all-available-imports)
- [Accessing a curve's variables](#accessing-a-curves-variables)
- [Abstract API](#abstract-api)
Expand Down Expand Up @@ -246,8 +247,30 @@ Same RFC7748 / RFC8032 / IRTF draft are followed.

#### bls12-381

```ts
import { bls12_381 } from '@noble/curves/bls12-381';
```

See [abstract/bls](#bls-barreto-lynn-scott-curves).

#### bn254 aka alt_bn128

```ts
import { bn254 } from '@noble/curves/bn254';

console.log(
bn254.G1,
bn254.G2,
bn254.pairing
)
```

The API mirrors [abstract/bls](#bls-barreto-lynn-scott-curves).

The curve was previously called alt_bn128.
The implementation is compatible with [EIP-196](https://eips.ethereum.org/EIPS/eip-196) and
[EIP-197](https://eips.ethereum.org/EIPS/eip-197).

#### All available imports

```typescript
Expand Down Expand Up @@ -590,7 +613,7 @@ use aggregated, batch-verifiable
using Boneh-Lynn-Shacham signature scheme.

The module doesn't expose `CURVE` property: use `G1.CURVE`, `G2.CURVE` instead.
Only BLS12-381 is implemented currently.
Only BLS12-381 is currently implemented.
Defining BLS12-377 and BLS24 should be straightforward.

Main methods and properties are:
Expand Down
30 changes: 24 additions & 6 deletions benchmark/bls.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { readFileSync } from 'fs';
import { readFileSync } from 'node:fs';
import { mark, run } from 'micro-bmark';
import { bls12_381 as bls } from '../bls12-381.js';

const G2_VECTORS = readFileSync('../test/bls12-381/bls12-381-g2-test-vectors.txt', 'utf-8')
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const G2_VECTORS = readFileSync(
`${__dirname}/../test/bls12-381/bls12-381-g2-test-vectors.txt`,
'utf-8'
)
.trim()
.split('\n')
.map((l) => l.split(':'));
Expand Down Expand Up @@ -40,9 +45,22 @@ run(async () => {
await mark('verify', 50, () => bls.verify(sig, '09', pub));
await mark('pairing', 100, () => bls.pairing(p1, p2));

const scalars1 = Array(4096).fill(0).map(i => 2n ** 235n - BigInt(i));
const scalars2 = Array(4096).fill(0).map(i => 2n ** 241n + BigInt(i));
const points = scalars1.map(s => bls.G1.ProjectivePoint.BASE.multiply(s));
const scalars1 = Array(4096)
.fill(0)
.map((i) => 2n ** 235n - BigInt(i));
const scalars2 = Array(4096)
.fill(0)
.map((i) => 2n ** 241n + BigInt(i));
const points = scalars1.map((s) => bls.G1.ProjectivePoint.BASE.multiply(s));
const pointsG2 = scalars1.map((s) => bls.G2.ProjectivePoint.BASE.multiply(s));

const pairingBatch = 10;
await mark(`pairing${pairingBatch}`, 10, () => {
const res = [];
for (let i = 0; i < pairingBatch; i++) res.push({ g1: points[i], g2: pointsG2[i] });
bls.pairingBatch(res);
});

await mark('MSM 4096 scalars x points', 1, () => {
// naive approach, not using multi-scalar-multiplication
let sum = bls.G1.ProjectivePoint.ZERO;
Expand Down
Loading

0 comments on commit f3ef397

Please sign in to comment.