Digital Signature Basics

How to use the slides - Full screen (new tab)
Slides Content
--- title: Digital Signature Basics description: Hands-on application of digital signature duration: 1 hour ---

Digital Signatures Basics

Signature API

Signature libraries should generally all expose some basic functions:

  • fn generate_key(r) -> sk;
    Generate a sk (secret key) from some input r.
  • fn public_key(sk) -> pk;
    Return the pk (public key) from a sk.
  • fn sign(sk, msg) -> signature;
    Takes sk and a message; returns a digital signature.
  • fn verify(pk, msg, signature) -> bool;
    For the inputs pk, a message, and a signature; returns whether the signature is valid.


The input r could be anything, for example the movement pattern of a mouse.

For some cryptographies (ECDSA), the verify might not take in the public key as an input. It takes in the message and signature, and returns the public key if it is valid.

Subkey Demo

Key Generation and Signing


See the Jupyter notebook and/or HackMD cheat sheet for this lesson.

  1. Generate a secret key
  2. Sign a message
  3. Verify the signature
  4. Attempt to alter the message

Hash Functions

There are two lessons dedicated to hash functions.
But they are used as part of all signing processes.

For now, we only concern ourselves with using Blake2.

Hashed Messages

As mentioned in the introduction,
it's often more practical to sign the hash of a message.

Therefore, the sign/verify API may be used like:

  • fn sign(sk, H(msg)) -> signature;
  • fn verify(pk, H(msg), signature) -> bool;

Where H is a hash function (for our purposes, Blake2).
This means the verifier will need to run the correct hash function on the message.

Cryptographic Guarantees

Signatures provide many useful properties:

  • Confidentiality: Weak, the same as a hash
  • Authenticity: Yes
  • Integrity: Yes
  • Non-repudiation: Yes


If a hash is signed, you can prove a signature is valid without telling anyone the actual message that was signed, just the hash.

Signing Payloads

Signing payloads are an important part of system design.
Users should have credible expectations about how their messages are used.

For example, when a user authorizes a transfer,
they almost always mean just one time.


There need to be explicit rules about how a message is interpreted. If the same signature can be used in multiple contexts, there is the possibility that it will be maliciously resubmitted.

In an application, this typically looks like namespacing in the signature payload.

Signing and Verifying


Note that signing and encryption are not inverses.

Replay Attacks

Replay attacks occur when someone intercepts and resends a valid message.
The receiver will carry out the instructions since the message contains a valid signature.

  • Since we assume that channels are insecure, all messages should be considered intercepted.
  • The "receiver", for blockchain purposes, is actually an automated system.


Lack of context is the problem. Solve by embedding the context and intent _within the message being signed. Tell the story of Ethereum Classic replays.

Replay Attack Prevention

Signing payloads should be designed so that they can
only be used one time and in one context.

  • Monotonically increasing account nonces
  • Timestamps (or previous blocks)
  • Context identifiers like genesis hash and spec versions

Signature Schemes


  • Uses Secp256k1 elliptic curve.
  • ECDSA (used initially in Bitcoin/Ethereum) was developed to work around the patent on Schnorr signatures.
  • ECDSA complicates more advanced cryptographic techniques, like threshold signatures.
  • Nondeterministic


  • Schnorr signature designed to reduce mistakes in implementation and usage in classical applications, like TLS certificates.
  • Signing is 20-30x faster than ECDSA signatures.
  • Deterministic


Sr25519 addresses several small risk factors that emerged
from Ed25519 usage by blockchains.

Use in Substrate

  • Sr25519 is the default key type in most Substrate-based applications.
  • Its public key is 32 bytes and generally used to identify key holders (likewise for ed25519).
  • Secp256k1 public keys are 33 bytes, so their hash is used to represent their holders.