# Bls

Utility functions for [BLS12-381](https://hackmd.io/@benjaminion/bls12-381) cryptography.

:::info
The `Bls` module is a friendly wrapper over [`@noble/curves/bls12-381`](https://github.com/paulmillr/noble-curves), an **audited** implementation of BLS12-381.
:::

## Examples

Below are some examples demonstrating common usages of the `Bls` module:

* [Computing a Random Private Key](#computing-a-random-private-key)

* [Getting a Public Key](#getting-a-public-key)

* [Signing a Payload](#signing-a-payload)

* [Verifying a Signature](#verifying-a-signature)

* [Aggregating Public Keys & Signatures](#aggregating-public-keys-&-signatures)

* [Verify Aggregated Signatures](#verify-aggregated-signatures)

### Computing a Random Private Key

A random private key can be computed using [`Bls.randomPrivateKey`](/api/Bls/randomPrivateKey):

```ts twoslash
import { Bls } from 'ox'

const privateKey = Bls.randomPrivateKey()
// @log: '0x...'
```

### Getting a Public Key

A public key can be derived from a private key using [`Bls.getPublicKey`](/api/Bls/getPublicKey):

```ts twoslash
import { Bls } from 'ox'

const privateKey = Bls.randomPrivateKey()
const publicKey = Bls.getPublicKey({ privateKey })
// @log: { x: 3251...5152n, y: 1251...5152n, z: 1n }
```

### Signing a Payload

A payload can be signed using [`Bls.sign`](/api/Bls/sign):

```ts twoslash
import { Bls } from 'ox'

const privateKey = Bls.randomPrivateKey()
const signature = Bls.sign({
  payload: '0xdeadbeef',
  privateKey
})
// @log: { x: 1251...5152n, y: 1251...5152n, z: 1n }
```

### Verifying a Signature

A signature can be verified using [`Secp256k1.verify`](/api/Secp256k1/verify):

```ts twoslash
import { Bls } from 'ox'

const privateKey = Bls.randomPrivateKey()
const publicKey = Bls.getPublicKey({ privateKey })
const signature = Bls.sign({
  payload: '0xdeadbeef',
  privateKey
})

const isValid = Bls.verify({
  // [!code focus]
  payload: '0xdeadbeef', // [!code focus]
  publicKey, // [!code focus]
  signature // [!code focus]
}) // [!code focus]
// @log: true
```

### Aggregating Public Keys & Signatures

Public keys and signatures can be aggregated using [`Bls.aggregate`](/api/Bls/aggregate):

```ts twoslash
import { Bls } from 'ox'

const publicKeys = [
  Bls.getPublicKey({ privateKey: '0x...' }),
  Bls.getPublicKey({ privateKey: '0x...' })
]
const publicKey = Bls.aggregate(publicKeys)

const signatures = [
  Bls.sign({ payload: '0x...', privateKey: '0x...' }),
  Bls.sign({ payload: '0x...', privateKey: '0x...' })
]
const signature = Bls.aggregate(signatures)
```

### Verify Aggregated Signatures

We can also pass a public key and signature that was aggregated with [`Bls.aggregate`](/api/Bls/aggregate) to `Bls.verify`.

```ts twoslash
import { Bls, Hex } from 'ox'

const payload = Hex.random(32)
const privateKeys = Array.from({ length: 100 }, () =>
  Bls.randomPrivateKey()
)

const publicKeys = privateKeys.map((privateKey) =>
  Bls.getPublicKey({ privateKey })
)
const signatures = privateKeys.map((privateKey) =>
  Bls.sign({ payload, privateKey })
)

const publicKey = Bls.aggregate(publicKeys) // [!code focus]
const signature = Bls.aggregate(signatures) // [!code focus]

const valid = Bls.verify({ payload, publicKey, signature }) // [!code focus]
```

## Functions

| Name                | Description                         |
| ------------------- | ----------------------------------- |
| [`Bls.aggregate`](/api/Bls/aggregate) | Aggregates a set of BLS points that are either on the G1 or G2 curves (ie. public keys or signatures). |
| [`Bls.createKeyPair`](/api/Bls/createKeyPair) | Creates a new BLS12-381 key pair consisting of a private key and its corresponding public key. |
| [`Bls.getPublicKey`](/api/Bls/getPublicKey) | Computes the BLS12-381 public key from a provided private key. |
| [`Bls.randomPrivateKey`](/api/Bls/randomPrivateKey) | Generates a random BLS12-381 private key. |
| [`Bls.sign`](/api/Bls/sign) | Signs the payload with the provided private key. |
| [`Bls.verify`](/api/Bls/verify) | Verifies a payload was signed by the provided public key(s). |

## Types

| Name                | Description                         |
| ------------------- | ----------------------------------- |
| [`Bls.Size`](/api/Bls/types#blssize) |  |
