# ECDSA & Signers

## Signers

Ox exports utilities for the following ECDSA signers:

* [`Secp256k1`](/api/Secp256k1): Utilities for the [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) elliptic curve – the primary curve used on the Ethereum protocol.
* [`P256`](/api/P256): Utilities for [NIST P256](https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-186.pdf) cryptography. Commonly used in [Ethereum Account Abstraction](https://ethereum.org/en/roadmap/account-abstraction/).
* [`WebAuthnP256`](/api/WebAuthnP256): P256 utilities using the [Web Authentication API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API). Commonly used in Ethereum Account Abstraction.
* [`WebCryptoP256`](/api/WebCryptoP256): P256 utilities using the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API). Commonly used in Ethereum Account Abstraction.

:::note
We won't cover `WebAuthnP256` in this guide, please refer to the [WebAuthn Signers](/guides/webauthn) guide instead.
:::

### Private Keys

We can generate private keys using one of the Signer modules with their respective generation function:

* [`Secp256k1.randomPrivateKey`](/api/Secp256k1/randomPrivateKey)
* [`P256.randomPrivateKey`](/api/P256/randomPrivateKey)
* [`WebCryptoP256.createKeyPair`](/api/WebCryptoP256/createKeyPair)

```ts twoslash
import { P256, Secp256k1, WebCryptoP256 } from 'ox'

// Generate a private key on the secp256k1 curve.
const privateKey = Secp256k1.randomPrivateKey()
//    ^?



// Generate a private key on the P256 curve.
const privateKey_2 = P256.randomPrivateKey()
//    ^?



// Generate a private key on the P256 curve using the Web Crypto API.
const keypair = await WebCryptoP256.createKeyPair()
//    ^?






```

:::note
**Note:** Private keys generated by `WebCryptoP256` are [non-extractable](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey/extractable) by default – meaning they cannot be exported or serialized by the runtime.
:::

### Public Keys

We can extract Public Keys from Private Keys using one of the respective Signer functions:

* [`Secp256k1.getPublicKey`](/api/Secp256k1/getPublicKey)
* [`P256.getPublicKey`](/api/P256/getPublicKey)

```ts twoslash
import { Secp256k1, P256 } from 'ox'

{
  const privateKey = Secp256k1.randomPrivateKey()
  const publicKey = Secp256k1.getPublicKey({ privateKey })
  //    ^?
}






{
  const privateKey = P256.randomPrivateKey()
  const publicKey = P256.getPublicKey({ privateKey })
}
```

We can also extract an Ethereum Address from a Public Key using [`Address.fromPublicKey`](/api/Address/fromPublicKey):

```ts twoslash
import { Address, Secp256k1 } from 'ox'

const privateKey = Secp256k1.randomPrivateKey()
const publicKey = Secp256k1.getPublicKey({ privateKey })
const address = Address.fromPublicKey(publicKey)
//    ^?


```

### Signing

Payloads are signed using the respective Signer's `sign` function:

* [`Secp256k1.sign`](/api/Secp256k1/sign)
* [`P256.sign`](/api/P256/sign)
* [`WebCryptoP256.sign`](/api/WebCryptoP256/sign)

```ts twoslash
import { Secp256k1, P256, WebCryptoP256, WebAuthnP256 } from 'ox'

const payload = '0xdeadbeef'

// secp256k1
{
  const privateKey = Secp256k1.randomPrivateKey()
  const signature = Secp256k1.sign({ payload, privateKey })
  //    ^?
}






// P256
{
  const privateKey = P256.randomPrivateKey()
  const signature = P256.sign({ payload, privateKey })
}

// WebCrypto-P256
{
  const { privateKey } = await WebCryptoP256.createKeyPair()
  const signature = WebCryptoP256.sign({ payload, privateKey })
}
```

### Verification

Signatures can be verified against the signing payload and respective public key using the respective Signer's `verify` function:

* [`Secp256k1.verify`](/api/Secp256k1/verify)
* [`P256.verify`](/api/P256/verify)
* [`WebCryptoP256.verify`](/api/WebCryptoP256/verify)

```ts twoslash
import { Secp256k1, P256, WebCryptoP256 } from 'ox' // [!code focus]

const payload = '0xdeadbeef' // [!code focus]

// secp256k1 // [!code focus]
{ // [!code focus]
  const privateKey = Secp256k1.randomPrivateKey()
  const publicKey = Secp256k1.getPublicKey({ privateKey })
  const signature = Secp256k1.sign({ payload, privateKey })
  const verified = Secp256k1.verify({ payload, publicKey, signature }) // [!code focus]
} // [!code focus]

// P256 // [!code focus]
{ // [!code focus]
  const privateKey = P256.randomPrivateKey()
  const publicKey = P256.getPublicKey({ privateKey })
  const signature = P256.sign({ payload, privateKey })
  const verified = P256.verify({ payload, publicKey, signature }) // [!code focus]
} // [!code focus]

// WebCrypto-P256 // [!code focus]
{ // [!code focus]
  const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
  const signature = await WebCryptoP256.sign({ payload, privateKey })
  const verified = await WebCryptoP256.verify({ payload, publicKey, signature }) // [!code focus]
} // [!code focus]
```

### Recovery

Public Keys can be recovered from a signature and payload using the Signer's respective function:

* [`Secp256k1.recoverPublicKey`](/api/Secp256k1/recoverPublicKey)
* [`P256.recoverPublicKey`](/api/P256/recoverPublicKey)

```ts twoslash
import { Secp256k1, P256, WebCryptoP256 } from 'ox' // [!code focus]

const payload = '0xdeadbeef' // [!code focus]

// secp256k1 // [!code focus]
{ // [!code focus]
  const privateKey = Secp256k1.randomPrivateKey()
  const signature = Secp256k1.sign({ payload, privateKey })
  const publicKey = Secp256k1.recoverPublicKey({ payload, signature }) // [!code focus]
} // [!code focus]

// P256 // [!code focus]
{ // [!code focus]
  const privateKey = P256.randomPrivateKey()
  const signature = P256.sign({ payload, privateKey })
  const publicKey = P256.recoverPublicKey({ payload, signature }) // [!code focus]
} // [!code focus]
```

## Signatures

Signatures in Ox are represented via the [`Signature.Signature`](/api/Signature/types#signaturesignature) type – an object containing the standard ECDSA signature components of:

* `r`: a 32-byte `Hex` string representing the `r` component of the signature.
* `s`: a 32-byte `Hex` string representing the `s` component of the signature.
* `yParity` (or "recovery bit"): an optional `number` representing the recovery bit of the signature – typically utilized for recovery operations.

Examples:

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

// Signature with a recovery bit (yParity)
const signature = Signature.from({
  r: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf',
  s: '0x4a90a229a244495b41890987806fcbd2d5d23fc0dbe5f5256c2613c039d76db8',
  yParity: 0,
})

// Signature without a recovery bit (yParity)
const signature_2 = Signature.from({
  r: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf',
  s: '0x4a90a229a244495b41890987806fcbd2d5d23fc0dbe5f5256c2613c039d76db8',
})
```

:::note
It is important to note that `yParity` (recovery bit) may not be present in *all* types of ECDSA signatures generated by Ox's Signers. For example, the `WebCryptoP256` & `WebAuthnP256` Signers do not return a `yParity` value.
:::

### Serializing

You may need to serialize a Signature into Hex or Bytes format for specific use cases. You can do this using the [`Signature.toHex`](/api/Signature/toHex) or [`Signature.toBytes`](/api/Signature/toBytes) functions:

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

const signature = Signature.from({
  r: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf',
  s: '0x4a90a229a244495b41890987806fcbd2d5d23fc0dbe5f5256c2613c039d76db8',
  yParity: 0,
})
const serialized = Signature.toHex(signature)
//    ^?


const serialized_bytes = Signature.toBytes(signature)
//    ^?


```

## Public Keys

Public Keys in Ox can come in two forms: a compressed and uncompressed format. Generally, you will interact with uncompressed Public Keys, but it is important to be aware of the format.

Public Keys are represented via the [`PublicKey.PublicKey`](/api/PublicKey/types#publickeypublickey) type – an object containing the standard ECDSA public key components of:

* `prefix`: a `number` representing the prefix of the public key (`4` for uncompressed, `2` or `3` for compressed).
* `x`: a 32-byte `Hex` string representing the `x` coordinate of the public key.
* `y`: (if uncompressed) a 32-byte `Hex` string representing the `y` coordinate of the public key.

An example Public Key:

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

// Uncompressed
const publicKey = PublicKey.from({
  prefix: 4,
  x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75',
  y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5',
})

// Compressed
const publicKey_2 = PublicKey.from({
  prefix: 2,
  x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75',
})
```

### Serializing

You may need to serialize a Public Key into Hex or Bytes format for specific use cases. You can do this using the [`PublicKey.toHex`](/api/PublicKey/toHex) or [`PublicKey.toBytes`](/api/PublicKey/toBytes) functions:

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

const publicKey = PublicKey.from({
  x: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf',
  y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5',
})
const serialized = PublicKey.toHex(publicKey)
//    ^?


const serialized_bytes = PublicKey.toBytes(publicKey)
//    ^?


```

## Related Modules

| Module                              | Description                                                                                                                                                                                                                                                                                              |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [P256](/api/P256)                   | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography.                                                                                                            |
| [PublicKey](/api/PublicKey)         | Utility functions for working with ECDSA public keys.                                                                                                                                                                                                                                                    |
| [Secp256k1](/api/Secp256k1)         | Utility functions for [secp256k1](https://www.secg.org/sec2-v2.pdf) ECDSA cryptography.                                                                                                                                                                                                                  |
| [Signature](/api/Signature)         | Utility functions for working with ECDSA signatures.                                                                                                                                                                                                                                                     |
| [WebAuthnP256](/api/WebAuthnP256)   | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography using the [Web Authentication API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) |
| [WebCryptoP256](/api/WebCryptoP256) | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography using the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)                 |
