You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.8 KiB

  1. # bLSAG ring signatures overview
  2. *2022-07-20*
  3. > Note: I’m not a mathematician, I’m just an amateur on math. These notes are just an attempt to try to sort the notes that I took while learning abut bLSAG.
  4. <br>
  5. bLSAG: Back's Linkable Spontaneous Anonymous Group signatures
  6. - signer ambiguity
  7. - linkability
  8. - unforgeability
  9. ### Setup
  10. Let $G$ be the generator of an EC group.
  11. We use a hash function $\mathcal{H}_p$, which maps to curve points in EC, and a normal hash $\mathcal{H}_n$, which maps to $\mathbb{Z}_p$.
  12. Signer's key pair: $k_{\pi}$, s.t. $K_{\pi} = k_{\pi} \cdot G \in \mathcal{R}$, with secret index $\pi$.
  13. Set of Public Keys: $\mathcal{R} = \{ K_1, K_2, \ldots, K_n \}$
  14. ```python
  15. def new_key():
  16. k = F.random_element()
  17. K = g * k # g is the generator of the EC group
  18. return K
  19. ```
  20. ### Signature
  21. 1. compute key image: $\tilde{K} = k_{\pi} \mathcal{H_p} ( K_{\pi}) \in G$
  22. ```python
  23. key_image = k * hashToPoint(K)
  24. ```
  25. 2. Generate $\alpha \in^R \mathbb{Z}_p$, and $r_i \in^R \mathbb{Z}_p$, for $i \in \{1, 2, \ldots, n \}$, with $i \neq \pi$
  26. - $r_i$ is used for the fake responses
  27. ```python
  28. a = F.random_element()
  29. r = [None] * len(R)
  30. for i in range(0, len(R)):
  31. if i==pi:
  32. continue
  33. r[i] = mod(F.random_element(), p)
  34. ```
  35. 3. Compute $c_{\pi + 1} = \mathcal{H}_n ( m, [\alpha G], [\alpha \mathcal{H}_p(K_{\pi})])$
  36. ```python
  37. c[pi1] = hash(R, m, a * g, hashToPoint(R[pi]) * a, p)
  38. ```
  39. 4. for $i=\pi + 1, \pi +2, \ldots, n, 1, 2, \ldots, \pi -1$, calculate, replacing $n+1 \rightarrow 1$
  40. $$
  41. c_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
  42. $$
  43. - Notice that (from step 3 & 4):<br>
  44. $\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (\tilde{K})$,<br>
  45. where $\tilde{K}= k_{\pi} \mathcal{H_p} ( K_{\pi})$, so:<br>
  46. $\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (k_{\pi} \mathcal{H}_p(K_{\pi}))$<br>
  47. which is equal to,<br>
  48. $\alpha \cdot \mathcal{H}_p (K_{\pi}) = (r_{\pi} + c_{\pi} \cdot k_{\pi}) \cdot \mathcal{H}_p(K_{\pi})$<br>
  49. From where we can see: $\alpha = r_{\pi} + c_{\pi} \cdot k_{\pi}$<br>
  50. which we can rearrange to
  51. $r_{\pi} = \alpha - c_{\pi} \cdot k_{\pi}$.<br><br>
  52. ```python
  53. for j in range(0, len(R)-1):
  54. i = mod(pi1+j, len(R))
  55. i1 = mod(pi1+j +1, len(R))
  56. c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
  57. r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
  58. ```
  59. 6. Define $r_{\pi} = \alpha - c_{\pi} k_{\pi} \mod{p}$
  60. ```python
  61. r[pi] = mod(a - c[pi] * k, p)
  62. ```
  63. Signature: $\sigma(m) = (c_1, r_1, \ldots, r_n)$, with key image $\tilde{K}$ and ring $\mathcal{R}$.
  64. - $len(\sigma(m)) = 1+n$
  65. ```python
  66. return [c[0], r]
  67. ```
  68. <br><br><br>
  69. #### Step by step (simplified):
  70. <div style="overflow:auto;">
  71. <div style="width: 60%; float:left; height: 360px; overflow-y:scroll;">
  72. <img src="img/posts/ring-sig/step00.png" style="width:100%;" />
  73. <img src="img/posts/ring-sig/step00.png" style="width:100%;" />
  74. <img src="img/posts/ring-sig/step01.png" style="width:100%;" />
  75. <img src="img/posts/ring-sig/step02.png" style="width:100%;" />
  76. <img src="img/posts/ring-sig/step03.png" style="width:100%;" />
  77. <img src="img/posts/ring-sig/step04.png" style="width:100%;" />
  78. <img src="img/posts/ring-sig/step05.png" style="width:100%;" />
  79. <img src="img/posts/ring-sig/step06.png" style="width:100%;" />
  80. </div>
  81. <div style="width: 40%; float:right; margin-top:80px;">
  82. <ul>
  83. <li>Generate $r_i \in^R \mathbb{Z_p}$</li>
  84. <li>Compute $c_{i+1}$ from $r_i$</li>
  85. <li>Link $r_{\pi}$ with $c_{\pi}$</li>
  86. </ul>
  87. </div>
  88. </div>
  89. *You can scroll down the images through the step-by-step diagrams.*
  90. <br>
  91. It reminds in some way to the approach to close a box like the one in the picture:
  92. ![](img/posts/ring-sig/box-closed.png)
  93. <br><br><br>
  94. ### Verification
  95. 1. check $p \tilde{K} \stackrel{?}{=} 0$
  96. - to ensure that $\tilde{K} \in G$ (and not in a cofactor group of $G$)
  97. 2. for $i = 1, 2, \ldots, n$, replacing $n+1 \rightarrow 1$
  98. $$
  99. c'_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
  100. $$
  101. 3. check $c_1 \stackrel{?}{=} c'_i$
  102. ```python
  103. c[0] = c1
  104. for j in range(0, len(R)):
  105. i = mod(j, len(R))
  106. i1 = mod(j+1, len(R))
  107. c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
  108. r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
  109. assert c1 == c[0]
  110. ```
  111. <br><br>
  112. ## Links
  113. Toy implementation:
  114. - Sage: https://github.com/arnaucube/math/blob/master/ring-signatures.sage
  115. - Rust: https://github.com/arnaucube/ring-signatures-rs
  116. Resources:
  117. - *"Zero to Monero"* - https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf
  118. (section *"3.4 Back’s Linkable Spontaneous Anonymous Group (bLSAG) signatures"*)