Signatures
What are signatures in Filecoin
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 among with the assurance that each message was generated by specific individuals. In other words, it is infeasible for another individual i to generate a signed message that appears to have been generated by j.
We use signatures in filecoin to verify something was done by someone. For example, we use signatures in order to validate deal messages which represent an action like a storage deals. We also use signatures to determine who generated a particular message, determine public keys–which can be recovered from signed data and a signature, and find filecoin addresses which generated from a public key.
- Messages (From users to the blockchain)
- Tickets (Signature of proof - Mining)
- Block signature (Signature over all data in the block - done by block leader)
Interface
Filecoin requires a system that fulfils the following interface to function correctly.
Note: Message
is used here as the object being signed, but this interface should also work for other things that need to be signed.
type Signature interface {
// Sign generates a proof that miner `M` generate message `m`
//
// Out:
// sig - a series of bytes representing a signature usually `r`|`s`
// err - a standard error message indicating any process issues
// In:
// m - a series of bytes representing a message to be signed
// sk - a private key which cryptographically links `M` to `sig`
//
Sign(m Message, sk PrivateKey) (sig SignatureBytes, err error)
// Verify validates the statement: only `M` could have generated `sig`
// given the validator has a message `m`, a signature `sig`, and a
// public key `pk`.
//
// Out:
// valid - a boolean value indicating the signature is valid
// err - a standard error message indicating any process issues
// In:
// m - a series of bytes representing the signed message
// pk - the public key belonging to the signer `M`
// sig - a series of bytes representing a signature usually `r`|`s`
//
Verify(m Messgage, pk PublicKey, sig SignatureBytes) (valid bool, err error)
// Recover, as its name implies, recovers a public key associated with a
// particular signature. In the case of ECDSA signatures, this function can
// be fulfilled via the 'ECRecover' method. If a different signature scheme
// is used, then some other mechanism of 'recovering' a message authors
// public key must be provided.
//
// 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) (pk PublicKey, err error)
}
Secp256k1 Signatures
Currently, Filecoin uses secp256k1 signatures to fulfill the above interface. All signatures on messages, blocks, and tickets currently use the same scheme and format.
Signing Messages
To generate a signature for the Message
type, first serialize it, then hash the serialized bytes with blake2b-256. Then, take the 32 byte digest output the hash and compute the secp256k1 signature over it.
Wire Format
We use standard secp256k1 signature serialization, as described below. For more details on how the Filecoin Signature
type is serialized, see the relevant section in the data structures spec
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