### Signatures- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures`

- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures`

Signatures are cryptographic functions that attest to the origin of a particular message. In the context of Filecoin, signatures are used to send and receive messages with the assurance that each message was generated by a specific entity. In other words, it is infeasible for an entity i to generate a signed message that appears to have been generated by j, with j != i.

Filecoin uses signatures to associate an action to a given party. For example, Filecoin uses signatures in order to validate deal messages which represent an action like a storage deal. Filecoin uses signatures to verify the authenticity of the following objects (non exhaustive list):

- Messages: Users authenticate their messages to the blockchain.
- Tickets: Miner authenticates its ticket (see Storage Miner).
- Blocks: Block leader signs over all data in the block.

#### Messages- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.messages`

- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.messages`

To generate a signature for the Message type, compute the signature over the message’s CID (taken as a byte array).

**Note**: for each specific use of a signature scheme, it is recommended to use a domain separation tag to treat the hash function as an independent random oracle. These tags are indicated in the relevant places throughout the specs.
Read more about this in
Randomness.

#### Signature Types- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.signature-types`

- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.signature-types`

Filecoin currently uses two types of signatures:

- ECDSA signatures over the Secp256k1 elliptic curve to authenticate user messages, mainly for compatibility with external blockchain systems.
- BLS signatures over the BLS12-381 group of curves

Both signature types fulfill the `Signature`

interface
and each type have additional functionality as explained below.

```
type Message Bytes
type SecretKey Bytes
type PublicKey Bytes
type SignatureBytes Bytes
type SigKeyPair struct {
PublicKey
SecretKey
}
type Signature struct {
Type SigType @(internal)
Sig SignatureBytes @(internal)
}
type SigType enum {
ECDSASigType
BLSSigType
}
```

##### ECDSA Signatures- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.ecdsa-signatures`

- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.ecdsa-signatures`

Filecoin uses the ECDSA signature algorithm over the secp256k1 curve to authenticate the blockchain messages. The main reason is to be able to validate messages from other blockchain systems that uses secp256k1 (such as Bitcoin or exchanges in general). ECDSA signatures offer an additional useful functionality as well: to recover the public key from a given signature. This feature can allow space to be saved on the blockchain by extracting the public key locally from the signature rather than specifying an ID of the public key.

```
// ECDSA implements the Signature interface using the ECDSA algorithm with
// the Secp256k1 elliptic curve.
type ECDSA struct {
// The Signature object is the one returned from SigKeyPair.Sign(). It can
// be casted to ECDSA to get the additional functionality described below.
Signature
// Recover recovers a public key associated with a particular signature.
//
// Out:
// pk - the public key associated with `M` who signed `m`
// err - a standard error message indicating any process issues
// **
// In:
// m - a series of bytes representing the signed message
// sig - a series of bytes representing a signature usually `r`|`s`
//
Recover(m Message, sig SignatureBytes) struct {pk PublicKey, err error}
}
```

**Wire Format**: Filecoin uses the standard secp256k1 signature serialization,
as described below. For more details on how the Filecoin `Signature`

type is
serialized, see
Signature.

```
SignatureBytes = [0x30][len][0x02][r][indicator][s][indicator][recovery]
```

`s`

= Scalar of size 32 bytes

`r`

= Compressed elliptic curve point (x-coordinate) of size 32 bytes

`recovery`

= Information needed to recover a public key from `sig`

.

- LSB(0) = parity of y-coordinate of r
- LSB(1) = overflow indicator

`indicator`

= a 2 byte formatting indicator

**External References**:
Elliptic Curve Cryptography Paper

##### BLS Signatures- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.bls-signatures`

- State
`wip`

- Theory Audit
`coming`

- Edit this section
`section-algorithms.crypto.signatures.bls-signatures`

Filecoin uses the BLS signature scheme over the BLS12-381 group of elliptic curves. You can find the default Rust implementation in Filecoin’s repo.

```
// BLS implements the Signature interface using the BLS signature scheme
// with the BLS12-381 group of elliptic curves.
type BLS struct {
// This signature is the one returned from SigKeyPair.Sign(). It can be
// casted to a BLS signature struct to get the additional functionalities.
Signature
// This represents the largest potential value for a BLS signature in Bytes
MaxSigValue() Bytes
// Aggregates this BLS signature and `sig` into one BLS signature that can
// be verified against the aggregation of the two public key that signed
// the aggregated signatures.
Aggregate(sig2 SignatureBytes) SignatureBytes
// VerifyAggregate verifies the aggregate signature with the aggregate
// public key over all the distinct messages given. Note that if all
// messages are the same, it is sufficient and correct to only call
// `Verify` since it is a subset of `VerifyAggregate`.
VerifyAggregate(messages [Message], aggPk BLSPublicKey, aggSig SignatureBytes) bool
}
// BLSPublicKey is a PublicKey with an addition method to aggregate public keys
// together.
type BLSPublicKey struct {
PublicKey
// Aggregate this public key with p2 into one public key. This aggregated
// public key can
// - verify aggregated signatures signed by the two BLSPublicKey
// - be aggregated further down with other (aggregated or not) BLSPublicKey.
Aggregate(p2 BLSPublicKey) BLSPublicKey
}
```

```
package crypto
import util "github.com/filecoin-project/specs/util"
func (self *BLS_I) Verify(input util.Bytes, pk PublicKey, sig util.Bytes) bool {
// blsPk := pk.(*BLSPublicKey)
// 1. Verify public key according to string_to_curve section 2.6.2.1. in
// https://tools.ietf.org/html/draft-boneh-bls-signature-00#page-12
// 2. Verify signature according to section 2.3
// https://tools.ietf.org/html/draft-boneh-bls-signature-00#page-8
panic("bls.Verify TODO")
return false
}
func (self *BLS_I) MaxSigValue() util.Bytes {
panic("TODO")
}
func (self *BLS_I) Sign(input util.Bytes, sk *SecretKey) bool {
panic("see 2.3 in https://tools.ietf.org/html/draft-boneh-bls-signature-00#page-8")
return false
}
func (self *BLS_I) Aggregate(sig2 util.Bytes) util.Bytes {
panic("see 2.5 in https://tools.ietf.org/html/draft-boneh-bls-signature-00#page-8")
var ret util.Bytes
return ret
}
func (self *BLS_I) VerifyAggregate(messages []util.Bytes, aggPk PublicKey, aggSig util.Bytes) bool {
panic("see 2.5.2 in https://tools.ietf.org/html/draft-boneh-bls-signature-00#page-9")
return false
}
```

**Choice of group**: The BLS signature requires the use of a pairing-equipped
curve which generally yield three groups: G_1, G_2 and G_T. In the BLS signature
scheme, there is a choice on which group to define the public key and the
signature:

- Public key is on G_1 and signature on G_2
- Public key is on G_2 and signature on G_1

The group G_1 is “smaller” and hence offer faster arithmetic operations and
smaller byte representation of its elements. Filecoin currently uses the group
**G_1 for representing public keys** and the group **G_2 for representing
signatures**.

**Wire Format**: Filecoin uses the standard way to serialize BLS signatures as
explained in the
RFC Section
2.6.1.

**Rationale**:
BLS signatures have two main characteristics that are making them ideal
candidates in recent blockchain systems:

- BLS signatures are deterministic: for a given message and a given secret key, the signature is always the same. That feature removes an important security weakness of most randomized signature schemes: signer must never re-use the same randomness twice otherwise this reveals its private key. As well, deterministic signatures are an ideal candidate to reduce the attack surface in terms of grinding, which is a real concern in recent proof of stake systems.
- BLS signatures are aggregatable: one can aggregate signatures from different signers into one single signature. This feature enables drastically saving space on the blockchain, especially when aggregating user messages.

**Aggregation Functionality**: The aggregation functionality is commutative and
associative, enabling *partial* aggregation. For example, given
`(PK1, sig1), (PK2, sig2), (PK3, sig3)`

, one can first aggregate `(PK12 = PK1 + PK2, sig12 = sig1 + sig2)`

then aggregate with the third tuple to produce
`(PK123 = PK12 + PK3, sig123 = sig12 + sig3)`

.

**Aggregation Security**: The naive BLS signature aggregation scheme is
vulnerable to rogue-key attacks where the attacker can freely choose its public
key. To prevent against this class of attacks there exists three different kind
of measures, as explained
here:

- Enforce distinct messages
- Prove knowledge of the secret key
- Use a modified scheme (such as BLS Multi Sig)

Fortunately, Filecoin can enforce the first condition to safely use the
aggregation property:
Filecoin uses aggregation only for aggregating message signatures within a
single block. Since Filecoin uses the account model to represent the state of
the chain, each message for a given signer is used in combination with a nonce
to avoid replay attacks. As a direct consequence, every message is unique
thereby the aggregation is done on distinct messages. Obviously, the
**assumption** here is that the block producer **enforces that distinction** and
the other miners will **check all messages** to make sure they are valid.