5.9 KiB
+++ title = "bLSAG ring signatures" date = 2024-06-27 description = "A few notes on the bLSAG elliptic curve ring signing algorithm" insert_anchor_links = "left" [taxonomies] tags = ["cryptography", "mathematics"] [extra] katex = true +++
A ring signature is a cryptographic proof that a message is original and authentified by someone in a given assembly, without revealing this person's identity.
For example, jury members may each one give their decision anonymously, so that the other jury members or the public cannot make a link between any decision and any member. In order to ensure the decisions are authentic, with each one is attached a ring signature that enables to prove it has been emitted by a jury member.
Multiple ring signature algorithms exist. Here will be introduced bLSAG, which has the property of enabling the detection of multiple distinct signatures emitted by the same person. In our example of a jury, we want indeed to ensure nobody voted twice. a voté deux fois.
The main source of this introduction to bLSAG is Zero to Monero 2.0.0 (page 29) and the Rust library nazgul which implements multiple ring signature schemes including bLSAG. Moreover, this article serves as additional documentation to the Rust library orodruin that I developed in order to implement anonymous transactions in Duniter.
Required: basics in algebra and cryptology. Knowledge of elliptic curves is not needed.
Notations
\mathbb{Z}/l\mathbb{Z}
the integers modulol
E
an elliptic curve (finite set of points, forming a group in which the discrete logarithm problem is assumed to be difficult)G
a generator ofE
\mathbin\Vert
the concatenation operatorx[n]
the remainder of the euclidean division ofx
byn
H
a cryptographic hashing function (depending on the context, its image is in\mathbb{Z}/l\mathbb{Z}
or inE
)- We will talk about the ring
\mathcal{R}
, meaning an ordered set of public keys, not meaning an algebraic structure of ring. Yes this is ambiguous.
Signature
The signature \sigma(m)
of a message m
, by the secret key k_\pi
of which the public key K_\pi
is in the ring \mathcal{R}=\\\{K_1,\ldots,K_n\\\}
, is obtained as follows:
k_\pi \in \mathbb{Z}/l\mathbb{Z}
Alice's private keyK_\pi = G k_\pi \in E
Alice's public key\tilde K_\pi = k_\pi H(K_\pi) \in E
Alice's key imager_1,\ldots,r_{\pi-1},\alpha,r_{\pi+1},\ldots,r_n
random numbers in\mathbb{Z}/l\mathbb{Z}
c_{\pi+1} = H(m \mathbin\Vert \alpha G \mathbin\Vert \alpha H(K_\pi))
\forall i \in \\\{\pi+1,\ldots,n,1,\ldots,\pi-1\\\},\ c_{i+1[n]} = H(m \mathbin\Vert r_i G + c_i K_i \mathbin\Vert r_i H(K_i) + c_i \tilde K_\pi)
r_\pi = \alpha - c_\pi k_\pi
\sigma(m) = (\mathcal{R}, \tilde K_\pi, c_1, (r_1, \ldots, r_n))
Verification
- Check
l\tilde K_\pi=0
c_1' = c_1
\forall i \in \\\{1,\ldots,n\\\},\ c_{i+1}' = H(m \mathbin\Vert r_i G + c_i' K_i \mathbin\Vert r_i H(K_i) + c_i' \tilde K_\pi)
- Check
c_1 = c_{n+1}'
We can now understand why a ring. We are forming a ring, or circle, with all the keys, then the challenge rotates around the ring. Each key modifies it by turn. In order to get the same, original challenge at the end, we need that one key somewhere in the ring (without us knowing where) made the right modification that finally cancels the noise created by the others. annule le bruit créé par les autres.
Correctness
Let's show that the verification algorithm is correct. First we recall the following definitions:
k_\pi
Alice's private keyK_\pi = G k_\pi
Alice's public key\tilde K_\pi = k_\pi H(K_\pi)
Alice's key imagec_{\pi+1} = H(m \mathbin\Vert \alpha G \mathbin\Vert \alpha H(K_\pi))
\forall i \in \\\{\pi+1,\ldots,n,1,\ldots,\pi-1\\\},\ c_{i+1[n]} = H(m \mathbin\Vert r_i G + c_i K_i \mathbin\Vert r_i H(K_i) + c_i \tilde K_\pi)
r_\pi = \alpha - c_\pi k_\pi
Our aim is to successively build the c_i'
and find c_1=c_{n+1}'
iff the signature is authentic.
\begin{align*}
c_1 = c_{n+1}'
&\Leftrightarrow
\begin{cases}
r_n G + c_n K_n = r_n G + c_n' K_n \\
r_n H(K_n) + c_n \tilde K_\pi = r_n H(K_n) + c_n' \tilde K_\pi
\end{cases} \\
&\Leftrightarrow
\begin{cases}
c_n K_n = c_n' K_n \\
c_n \tilde K_\pi = c_n' \tilde K_\pi
\end{cases} \\
&\Leftarrow c_n = c_n' \\
&\Leftrightarrow
\begin{cases}
c_{n-1} K_{n-1} = c_{n-1}' K_{n-1} \\
c_{n-1} \tilde K_\pi = c_{n-1}' \tilde K_\pi
\end{cases} \\
&\Leftarrow c_{\pi+1} = c_{\pi+1}' \quad\text{by induction} \\
&\Leftrightarrow
\begin{cases}
\alpha G = r_\pi G + c_\pi K_\pi &\quad\text{(1)}\\
\alpha H(K_\pi) = r_\pi H(K_\pi) + c_\pi \tilde K_\pi &\quad\text{(2)}
\end{cases}
\end{align*}
Let's show that (1) and (2) hold:
\begin{align*}
\text{(1)}
&\Leftrightarrow \alpha G = (\alpha - c_\pi k_\pi) G + c_\pi K_\pi \\
&\Leftrightarrow \alpha G = \alpha G + c_\pi k_\pi + c_\pi K_\pi G \\
&\Leftarrow K_\pi = k_\pi G
\end{align*}
\begin{align*}
\text{(2)}
&\Leftrightarrow \alpha H(K_\pi) = (\alpha - c_\pi k_\pi) H(K_\pi) + c_\pi \tilde K \\
&\Leftrightarrow \alpha H(K_\pi) = \alpha H(K_\pi) - c_\pi k_\pi H(K_\pi) + c_\pi k_\pi H(K_\pi)
\end{align*}
Hence the signature is correct.
Security
Without making a security proof, we can have an feeling of what makes this system safe:
Is the signature unfalsifiable, i.e. are we unable to forge a correct signature without knowing k_\pi
? We see that the proofs of (1) and (2) use r_\pi = \alpha - c_\pi k_\pi
, that is the private key.
Is the signature anonymous, i.e. are we unable to find \pi
from the signature? We have that r_\pi
is noised by \alpha
. We can not distinguish r_\pi
from the other r_i
, because they are uniformly random like \alpha
and c_\pi
(which is a hash), and because k_\pi
is secret.