Skip to content

Using ECC for (Multi-)Signatures

Math-powered methods for proving message authenticity, sounds great, doesn't it?

@
Nov 29, 202410 min read
I am not a cryptographer, nor a mathematician. This article is the result of my own research and understanding of the subject. If you find any mistakes, please let me know!
The vast majority of what is written here is taken from various sources, which are listed at the end of this article. I highly recommend you to read them if you want to dive deeper into the subject.

Elliptic curves may not write your emails, but they can help prove you sent them. Our goal is to output a signature $(r, s)$ for a given message $m$, so that the recipient can verify that the sender is authentic. The sender's keys are $(p, P)$, with $p$ the private key, and $P$ the public one.

ECDSA Signatures

Let's take a look at the Elliptic Curve Digital Signature Algorithm (ECDSA).

  1. Compute the hash $h = H(m)$ where $H(x)$ is any cryptographic hash function (e.g. SHA-256).
  2. Generate a random $k$ number in in the current subgroup.
  3. Calculate the associated random point on the curve $K = k dot G$, with $G$ a generator, with $x_K$ the $x$-coordinate of this point.
  4. Calculate the signature $s = k^(-1) dot (h + x_K dot p)$, where $k^(-1)$ is the modular inverse of $k$.

By sending $(r, s)$, you confirm you know:

  • The content of the message $m$
  • The private key $p$ associated to $P = p dot G$

The verifier may follow this procedure to check if the message $m$ that he received along with $(r,s)$ is authentic:

  1. Compute the hash $h = H(m)$ with the same cryptographic hash function defined before.
  2. Calculate the modular inverse of $s$: $S = s^(-1)$
  3. Recover the random point used in the signature process: $K = h S dot G + r S dot P$
  4. Check whether $x_K = r$, if so, then the message is authentic.

To prove this works, let's start with the definition of the signature $s$:

& s = k^(-1) dot (h + x_K dot p) \ <==>& s dot k = h + x_K dot p \ <==>& underbrace(s dot k = h + r dot p, (a))

Incorporate $(a)$ into $K$:

K &= h S dot G + r S dot P \ &= h s^(-1) dot G + r s^(-1) dot (p dot G) \ &= s^(-1) (h dot G + r dot (p dot G)) \ &= s^(-1) underbrace((h + r dot p), (a)) dot G \ &= underbrace(s^(-1) s, = 1) dot k dot G \ &= underline(k dot G)

Which is just our definition of $K$ when generating the signature.

Cool Kids Public Key Recovery

Let's suppose you are talking through a Tin can telephone with your friend and every byte you send matters. You don't want to send the public key $P$ along with the signature $(r, s)$ because that's just too much data. Instead, you can recover the public key from the signature and the message.

Given $x_K$, there are typically two candidate points $K'_i$ that fit. And since we know that $K = h S dot G + r S dot P$, which we just verified works, it can be rearranged to isolate the public key $P$:

K'_i &= h S dot G + r S dot P_i \ <==> P_i &= s^(-1)(r K'_i - h G)

To choose which one is the correct one, we need to verify the signature with each $P_i$:

Ki=hSdotG+rSdotPi=(xK,yK) xK=?rK_i = h S dot G + r S dot P_i = (x_K, y_K) \ x_K =^? r

This ambiguity is often removed by adding a single bit $b in {0,1}$ into the signature message: $(r, s, b)$

Schnorr Signatures

Schnorr signatures are a bit like ECDSA, but faster and simpler. We are going to use the same keys $(p, P)$ as before, with $p$ the private key and $P$ the public one. We'll first see the procedure and then discuss the mathematical proof of why this works.

  1. Sample a random nonce $r <- ZZ_n$
What the hell is

$ZZ_n$ ?

The set $ZZ_n$ is a cyclic group of integers, isomorphic to the quotient group $ZZ slash n ZZ$. It is basically just the set of integers modulo $n$.

ZZn=0,1,2,...,n−1ZZ_n = {0, 1, 2, ..., n-1}

In our case, $n$ is the order (how many points are in) of the subgroup generated by $G$. If the curve's cofactor $h$ is 1, then $n$ is the order of the curve. If $h$ is not 1, the order is $n/h = "ord"(G)$

  1. Multiply it by the generator: $R = r G$
  2. We can now compute the challenge $e = H(R || P || m)$
  3. And the signature: $s = r + e p$

The final signature is $(R, s)$.

Once the signature has been emitted, verifying it is as easy as checking:

sdotG=R+ePs dot G = R + e P

To know $e$, the verifier needs to know the message $m$, the public key $P$. In some cases, you might not need to include the public key into the challenge and simply hash $e = H(R || m)$.

Why it Works

There isn't really a proof needed for the verifying step as it's just factoring out $G$, but here you are:

& s dot G = R + e P \ <==>& s dot G = underbrace(r G, R) + h underbrace(p G, P) \ <==>& s dot G = (r + e p) dot G \

One trickier part is to explain why we are adding a random nonce $r$ to both the signature and the challenge. This value has to be sampled randomly and must not be reused. If it is, the private key can be recovered. Let's first take the case where no $r$ is used:

& s = e p \ <==>& p = s^(-1) e

Recovering the private key is as simple as multiplying the challenge $e$ by the modular inverse of $s$. Not good.

Now, let's take the case where $r$ is reused, with two messages $m_1$ and $m_2$, along with their respective signatures $(R, s_1)$ and $(R, s_2)$:

cases(spaces1=r+e1p<==>r=(s1−e1p)spacescript((a)),spaces2=r+e2p<==>r=(s2−e2p)spacescript((b)))cases( space s_1 = r + e_1 p <==> r = (s_1 - e_1 p) space script((a)), space s_2 = r + e_2 p <==> r = (s_2 - e_2 p) space script((b)) )

Combining $(a)$ and $(b)$:

& r = (s_1 - e_1 p) = (s_2 - e_2 p) \ <==>& e_1 p - e_2 p = s_1 - s_2 \ <==>& p dot (e_1 - e_2) = s_1 - s_2 \ <==>& p = (s_1 - s_2) / (e_1 - e_2)

You may see $r$ as an additional unknown variable that is used to prevent the linear equation system from being solved, because for $n$ messages, you have $n$ equations and $n+1$ unknowns, which is unsolvable in our case.

Aggregating Signatures

Schnorr signatures have the nice property that they can be aggregated, this means that a group of people can sign a message $m$ together and the signature can be verified as if it was signed by a single person. Let's consider our signing group $S = {a,b,c}$ for Alice, Bob and Charlie respectively.

&underline("Alice") &&underline("Bob") &&underline("Charlie") \ &R_a = r_a dot G quad &&R_b = r_b dot G quad &&R_c = r_c dot G \

The aggregated nonce is simply the sum of all nonces:

R &= sum_(i in S) R_i \ &= R_a + R_b + R_c \ &= (r_a + r_b + r_c) dot G

Likewise for the public key:

P &= sum_(i in S) P_i \ &= P_a + P_b + P_c \ &= (p_a + p_b + p_c) dot G

Each of them computes the challenge $e$ along with the final signature $s_i$ with the parameters just agreed upon:

e=H(R∣∣P∣∣m) si=epi+rie = H(R || P || m) \ s_i = e p_i + r_i

Everyone now sends their $s_i$ to the group.

And aggregate again:

s=sum(iinS)sis = sum_(i in S) s_i

Because we are just adding signatures parts together, we can group the nonces and the private keys in our final signature:

s &= sum_(i in S) s_i \ &= sum_(i in S) (e p_i + r_i) \ &= e p_a + r_a + e p_b + r_b + e p_c + r_c \ &= underbrace(r_a + r_b + r_c, "Nonces") + e underbrace((p_a + p_b + p_c), "Private Keys") \ &= sum_(i in S) r_i + e dot sum_(i in S) p_i

In the verifying step, multiplying each side by $G$:

s G &= sum_(i in S) r_i dot G + e dot sum_(i in S) p_i dot G \ &= sum_(i in S) R_i + e dot sum_(i in S) P_i \ &= R + e P

But wait!

At no point in this procedure, we ever check if the nonces or the public keys provided are honest. What if Charlie provided a malicious key $P^*_c$ in the sharing step ? Because everyone doesn't send their public key at the exact same time, Carol could wait for everyone to send theirs, and compute:

P^*_c = P_c - P_a - P_b \

The aggregated key will look like:

P &= sum_(i in S) P_i \ &= P_a + P_b + P^*_c \ &= P_a + P_b + (P_c - P_a - P_b) \ &= P_c

Carol just wiped everyone else from the signing key, and is now in full control of the signature. How can we prevent that ?

Multi-Signatures, don't trust, verify

The most common way to prevent this is to force everyone to provide a proof that their public key is honest. This is done by providing a Proof of Knowledge for the private key, proving that they know the private key associated to the public key they provided.

Let's take the case of a prover Patricia and a verifier Victor. Patricia wants to prove that she knows the private key $p$ associated to the public key $P = p dot G$. The proof is done in four steps:

  1. Patricia samples $r <- ZZ_n$ at random and sends $R = r dot G$ to Victor.
  2. Victor sends a challenge $c <- ZZ_n$ to Patricia.
  3. Patricia computes $z = r + c p$ and sends it to Victor.
  4. Victor verifies that $z dot G = R + c P$.

This works because:

z &= r + c p \ z dot G &= (r + c p) dot G \ &= r dot G + c p dot G \ &= R + c P

But what if Patricia doesn't know the associated private key but still wants to prove that her key is honest ? Remember commitment schemes ? We can use them here. In our case, every participant will commit to their public key before disclosing it. Think of it as putting your public key in a box, sealing it and waiting for everyone to do the same before opening it. Let's get back to our group $S = {a,b,c}$:

  1. Each participant $i$ hashes their public key $P_i$ and sends $H(P_i)$ to everyone.
  2. Once everyone has sent their hash, they disclose their public key $P_i$.
  3. Everyone verifies that the hash they received matches the public key.
  4. The signing process continues as usual.

This way, everyone can be sure that the public keys are honest and that no one is trying to pull a fast one.

There's more!

Random nonces are also aggregated, and at no point we are verifying that they are authentic. The exploit method is a bit trickier, I recommend you to read this article by conduition on the subject if you want to know the details.

References and Suggested readings

  • Practical Cryptography for Developers - Digital Signatures
    Svetlin Nakov
    cryptobook.nakov.com
  • A Dive Into the Math Behind Bitcoin Schnorr Signatures
    conduition.io
  • Wagner's Birthday Attack - How to Break InsecureMuSig
    conduition.io
  • How to Prove Schnorr Assuming Schnorr: Security of Multi- and Threshold Signatures
    Elizabeth Crites, Chelsea Komlo, and Mary Maller
    eprint.iacr.org

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions