Fork of the official github repository of the framework Leaky-LWE-Estimator, a Sage Toolkit to attack and estimate the hardness of LWE with Side Information. https://github.com/lducas/leaky-LWE-Estimator
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

4 år sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. # A Sage Toolkit to attack and estimate the hardness of LWE with Side Information
  2. This repository contains the artifacts associated to the article
  3. [DDGR20] **LWE with Side Information: Attacks and Concrete Security Estimation**
  4. by _Dana Dachman-Soled, Léo Ducas, Huijing Gong, Mélissa Rossi_
  5. https://eprint.iacr.org/2020/292.pdf
  6. The code is written for Sage 9.0 (Python 3 Syntax).
  7. ## Organization
  8. The library itself is to be found in the `framework` folder.
  9. `Sec5.2_validation` and `Sec6_applications` contain the code to reproduce our experiments.
  10. ## How to use the full-fledged version
  11. The full-fledged implementation is called when the class of the instance is DBDD. Let us create a small LWE instance and estimate its security in bikz. The code should be run from the directories `Sec5.2_validation` or `Sec6_applications`.
  12. ```sage
  13. sage: load("../framework/instance_gen.sage")
  14. ....: n = 70
  15. ....: m = n
  16. ....: q = 3301
  17. ....: D_s = build_centered_binomial_law(40)
  18. ....: D_e = D_s
  19. ....: A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s)
  20. ....: # In such parameter range, no need to integrate q-vectors
  21. ....: beta, delta = dbdd.estimate_attack()
  22. ```
  23. ```text
  24. Build DBDD from LWE
  25. n= 70 m= 70 q=3301
  26. Attack Estimation
  27. dim=141 δ=1.012362 β=45.40
  28. ```
  29. Our full-fledged implementation contains an attack procedure that runs BKZ with iterating gradually the block size. It then compares the recovered secret with the actual one.
  30. ```sage
  31. sage: secret = dbdd.attack()
  32. ```
  33. ```text
  34. Running the Attack
  35. Running BKZ-42 Success !
  36. ```
  37. Here, the block size stopped at 42 while an average blocksize of 45.40 has been estimated. Let us now create four vectors v for making perfect hints. To simulate side information, we compute the hints with the function dbdd.leak(v).
  38. ```sage
  39. sage: # Simulating perfect hints
  40. ....: v0 = vec([randint(0, 1) for i in range(m + n)])
  41. ....: v1 = vec([randint(0, 1) for i in range(m + n)])
  42. ....: v2 = vec([randint(0, 1) for i in range(m + n)])
  43. ....: v3 = vec([randint(0, 1) for i in range(m + n)])
  44. ....: # Computing l = <vi, s>
  45. ....: dbdd.leak(v0), dbdd.leak(v1), dbdd.leak(v2), dbdd.leak(v3)
  46. ```
  47. ```text
  48. (27, -62, -45, -47)
  49. ```
  50. Let us now integrate the perfect hints into our instance.
  51. ```sage
  52. sage: # Integrate perfect hints
  53. ....: _ = dbdd.integrate_perfect_hint(v0, 27)
  54. ....: _ = dbdd.integrate_perfect_hint(v1, -62)
  55. ....: _ = dbdd.integrate_perfect_hint(v2, -45)
  56. ....: _ = dbdd.integrate_perfect_hint(v3, -47)
  57. ```
  58. ```text
  59. integrate perfect hint u0 + u1 + u7 + u8 + u9 + ... = 27 Worthy hint ! dim=140, δ=1.01252643, β=41.93
  60. integrate perfect hint u0 + u2 + u8 + u9 + u10 + ... = -62 Worthy hint ! dim=139, δ=1.01275412, β=38.42
  61. integrate perfect hint u0 + u1 + u3 + u4 + u7 + ... = -45 Worthy hint ! dim=138, δ=1.01293851, β=34.78
  62. integrate perfect hint u1 + u9 + u11 + u12 + u13 + ... = -47 Worthy hint ! dim=137, δ=1.01314954, β=30.91
  63. ```
  64. The cost of the lattice attack has decreased by around 14 bikz. Let us now create four vectors v for making modular hints. To simulate side information, we compute the hint with the function dbdd.leak(v) with different moduli.
  65. ```sage
  66. sage: # Simulating modular hints
  67. ....: v0 = vec([randint(0, 1) for i in range(m + n)])
  68. ....: v1 = vec([randint(0, 1) for i in range(m + n)])
  69. ....: v2 = vec([randint(0, 1) for i in range(m + n)])
  70. ....: v3 = vec([randint(0, 1) for i in range(m + n)])
  71. ....: # Computing l = <vi, s> mod k
  72. ....: dbdd.leak(v0)%2, dbdd.leak(v1)%3, dbdd.leak(v2)%4, dbdd.leak(v3)%5
  73. ```
  74. ```text
  75. (1, 1, 2, 3)
  76. ```
  77. Let us now integrate the modular hints into our instance. We assume smoothness. In other words, the lattice is sparsified but the covariance matrix and average remain the same.
  78. ```sage
  79. sage: # Integrate modular hints
  80. ....: _ = dbdd.integrate_modular_hint(v0, 1, 2, True)
  81. ....: _ = dbdd.integrate_modular_hint(v1, 1, 3, True)
  82. ....: _ = dbdd.integrate_modular_hint(v2, 2, 4, True)
  83. ....: _ = dbdd.integrate_modular_hint(v3, 3, 5, True)
  84. ```
  85. ```text
  86. integrate modular hint (smooth) u2 + u3 + u4 + ... = 1 MOD 2 Worthy hint ! dim=137, δ=1.01318729, β=30.55
  87. integrate modular hint (smooth) u0 + u2 + u10 + ... = 1 MOD 3 Worthy hint ! dim=137, δ=1.01319931, β=29.98
  88. integrate modular hint (smooth) u0 + u4 + u9 + ... = 2 MOD 4 Worthy hint ! dim=137, δ=1.01327415, β=29.24
  89. integrate modular hint (smooth) u2 + u3 + u6 + ... = 3 MOD 5 Worthy hint ! dim=137, δ=1.01331577, β=28.37
  90. ```
  91. As modular hints contain less information than perfect ones, especially for low modulus, the cost of the lattice attack decreased by only 3 bikz. Let us do the same for approximate hints. To simulate side information, we compute the hint with the function dbdd.leak(v) and manually change the value to represent the measurement noise.
  92. ```sage
  93. sage: # Simulating approximate hints
  94. ....: v0 = vec([randint(0, 1) for i in range(m + n)])
  95. ....: v1 = vec([randint(0, 1) for i in range(m + n)])
  96. ....: v2 = vec([randint(0, 1) for i in range(m + n)])
  97. ....: v3 = vec([randint(0, 1) for i in range(m + n)])
  98. ....: # Computing l = <vi, s> + noise
  99. ....: dbdd.leak(v0) + 2, dbdd.leak(v1) + 1, dbdd.leak(v2) - 1, dbdd.leak(v3)
  100. ```
  101. ```text
  102. (-19, -29, -16, 1)
  103. ```
  104. Let us now integrate the approximate hints into our instance. We assume that we want to condition the new information with the prior one and not to erase the previous distribution.
  105. ```sage
  106. sage: # Integrate approximate hints
  107. ....: var = 10
  108. ....: _ = dbdd.integrate_approx_hint(v0, -19, var, aposteriori=False)
  109. ....: _ = dbdd.integrate_approx_hint(v1, -29, var, aposteriori=False)
  110. ....: _ = dbdd.integrate_approx_hint(v2, -16, var, aposteriori=False)
  111. ....: _ = dbdd.integrate_approx_hint(v3, 1, var, aposteriori=False)
  112. ```
  113. ```text
  114. integrate approx hint (conditionning)
  115. u0 + u4 + u5 + u6 + u8 + ... = -19 + χ(σ²=10.000) Worthy hint ! dim=137, δ=1.01322376, β=29.74
  116. integrate approx hint (conditionning)
  117. u0 + u5 + u6 + u7 + u8 + ... = -29 + χ(σ²=10.000) Worthy hint ! dim=137, δ=1.01329667, β=28.56
  118. integrate approx hint (conditionning)
  119. u0 + u4 + u5 + u7 + u12 + ... = -16 + χ(σ²=10.000) Worthy hint ! dim=137, δ=1.01337366, β=27.24
  120. integrate approx hint (conditionning)
  121. u1 + u2 + u3 + u4 + u5 + ... = 1 + χ(σ²=10.000) Worthy hint ! dim=137, δ=1.01340026, β=25.77
  122. ```
  123. Here, the cost of the lattice reduction attack has decreased by 3 bikz.
  124. While all the hints have been integrated, we finally estimate the security and run the attack again.
  125. ```sage
  126. sage: beta, delta = dbdd.estimate_attack()
  127. ....: secret = dbdd.attack()
  128. ```
  129. ```text
  130. Attack Estimation
  131. dim=137 δ=1.013400 β=25.77
  132. Running the Attack
  133. Running BKZ-27 Success !
  134. ```
  135. This time, BKZ stopped at blocksize 27 while the estimation was around 26 bikz.
  136. ## How to use the lightweight version
  137. The lightweight implementation is called when the class of the DBDD instance is `DBDD_predict`. While the heavy basis of the lattice is not stored, only its volume and dimension are stored. Let us create an LWE instance. Before estimating the cost of the lattice reduction attack in bikz, one needs to integrate the q vectors (i.e. drop some LWE samples). Then, the security is computed in bikz thanks to the volume and dimension of the lattice.
  138. ```sage
  139. sage: load("../framework/instance_gen.sage")
  140. ....: n = 512
  141. ....: m = n
  142. ....: q = 2 ^ 15
  143. ....: D_e = {-2: 0.05, -1: 0.20, 0: 0.5, 1: 0.20, 2: 0.05}
  144. ....: D_s = D_e
  145. ....: A, b, dbdd = initialize_from_LWE_instance(DBDD_predict, n, q, m, D_e, D_s)
  146. ....: _ = dbdd.integrate_q_vectors(q, report_every=20)
  147. ....: beta, delta = dbdd.estimate_attack()
  148. ```
  149. ```text
  150. Build DBDD from LWE
  151. n=512 m=512 q=32768
  152. Integrating q-vectors
  153. [...20] integrate short vector hint
  154. Worthy hint ! dim=1024, δ=1.00518248, β=270.72
  155. Attack Estimation
  156. dim=1016 δ=1.005183 β=270.69
  157. ```
  158. We now create a new LWE instance (necessary because the q vectors should always been included at the end). And, we create 4 vectors and simulate side information. Here we only integrate perfect hints.
  159. ```sage
  160. sage: load("../framework/instance_gen.sage")
  161. ....: A, b, dbdd = initialize_from_LWE_instance(DBDD_predict, n, q, m, D_e, D_s)
  162. ....: # Simulating hints
  163. ....: v0 = vec([1 if i < m / 2 else 0 for i in range(m + n)])
  164. ....: v1 = vec([0 if i < m / 2 else 1 for i in range(m + n)])
  165. ....: v2 = vec([1 if i < m else 0 for i in range(m + n)])
  166. ....: v3 = vec([1 if i < m / 4 else 0 for i in range(m + n)])
  167. ....: # Computing l = <vi, s>
  168. ....: dbdd.leak(v0), dbdd.leak(v1), dbdd.leak(v2), dbdd.leak(v3)
  169. ```
  170. ```text
  171. Build DBDD from LWE
  172. n=512 m=512 q=32768
  173. (33, 9, 56, 12)
  174. ```
  175. The hints must be now integrated and we assess the lattice reduction cost. Due to the shape of our vectors, new short vector hints must be integrated.
  176. ```sage
  177. sage: # Integrate hints
  178. ....: _ = dbdd.integrate_perfect_hint(v0, 33)
  179. ....: _ = dbdd.integrate_perfect_hint(v1, 9)
  180. ....: _ = dbdd.integrate_perfect_hint(v2, 56)
  181. ....: _ = dbdd.integrate_perfect_hint(v3, 12)
  182. ....: M = q * identity_matrix(n + m)
  183. ....: V = vec(M[0] - M[1])
  184. ....: i = 0
  185. ....: while dbdd.integrate_short_vector_hint(V):
  186. ....: i += 1
  187. ....: V = vec(M[i] - M[i + 1])
  188. ....: beta, delta = dbdd.estimate_attack()
  189. ```
  190. ```text
  191. integrate perfect hint u0 + u1 + u2 + u3 + u4 + ... = 33 Worthy hint ! dim=1024, δ=1.00519338, β=269.83
  192. integrate perfect hint u256 + u257 + u258 + u259 ... = 9 Worthy hint ! dim=1023, δ=1.00520492, β=268.91
  193. integrate perfect hint u0 + u1 + u2 + u3 + u4 + ... = 56 Worthy hint ! dim=1022, δ=1.00521752, β=268.03
  194. integrate perfect hint u0 + u1 + u2 + u3 + u4 + ... = 12 Worthy hint ! dim=1021, δ=1.00522793, β=267.19
  195. integrate short vector hint 32768*c0 - 32768*c1 ∈ Λ Not sure if in Λ, Unworthy hint, Rejected.
  196. Attack Estimation
  197. dim=1021 δ=1.005228 β=267.19
  198. ```
  199. Here, with 4 perfect hints, the cost of the lattice reduction attack has decreased by around 3 bikz. The blocksize may be actually below 267.19 as there may be residual short vector hints.
  200. ## How to use the super lightweight version
  201. The super lightweight implementation is called when the class of the instance is `DBDD_predict_diag`. Here, we assume that the covariance matrix is always diagonal. Let us create an LWE instance. We integrate the q vectors (i.e. drop some LWE samples) and compute the security in bikz.
  202. ```sage
  203. sage: load("../framework/instance_gen.sage")
  204. ....: n = 512
  205. ....: m = n
  206. ....: q = 2 ^ 15
  207. ....: D_e = {-2: 0.05, -1: 0.20, 0: 0.5, 1: 0.20, 2: 0.05}
  208. ....: D_s = D_e
  209. ....: A, b, dbdd = initialize_from_LWE_instance(DBDD_predict_diag, n, q, m, D_e, D_s)
  210. ....: _ = dbdd.integrate_q_vectors(q, report_every=20)
  211. ....: beta, delta = dbdd.estimate_attack()
  212. ```
  213. ```text
  214. Build DBDD from LWE
  215. n=512 m=512 q=32768
  216. Integrating q-vectors
  217. [...20] integrate short vector hint Worthy hint ! dim=1024, δ=1.00518248, β=270.72
  218. Attack Estimation
  219. dim=1016 δ=1.005183 β=270.69
  220. ```
  221. We create 20 canonical (necessary to keep the covariance matrix diagonal) vectors for integrating perfect hints.
  222. ```sage
  223. sage: A, b, dbdd = initialize_from_LWE_instance(DBDD_predict_diag, n, q, m, D_e, D_s)
  224. ....: # Simulating hints
  225. ....: v = [[] for _ in range(20)]
  226. ....: for i in range(20):
  227. ....: v[i] = canonical_vec(m + n, i)
  228. ```
  229. ```text
  230. Build DBDD from LWE
  231. n=512 m=512 q=32768
  232. ```
  233. The perfect hints are integrated into a new instance and the security is estimated.
  234. ```sage
  235. sage: # Integrate hints
  236. ....: for i in range(20):
  237. ....: _ = dbdd.integrate_perfect_hint(v[i], dbdd.leak(v[i]))
  238. ....: _ = dbdd.integrate_q_vectors(q, report_every=20)
  239. ....: beta, delta = dbdd.estimate_attack()
  240. ```
  241. ```text
  242. integrate perfect hint u0 = -2 Worthy hint ! dim=1024, δ=1.00519245, β=270.02
  243. integrate perfect hint u1 = -1 Worthy hint ! dim=1023, δ=1.00520080, β=269.31
  244. integrate perfect hint u2 = 1 Worthy hint ! dim=1022, δ=1.00520918, β=268.61
  245. integrate perfect hint u3 = 0 Worthy hint ! dim=1021, δ=1.00521757, β=267.91
  246. integrate perfect hint u4 = 1 Worthy hint ! dim=1020, δ=1.00522774, β=267.21
  247. integrate perfect hint u5 = 1 Worthy hint ! dim=1019, δ=1.00523618, β=266.51
  248. integrate perfect hint u6 = 0 Worthy hint ! dim=1018, δ=1.00524465, β=265.81
  249. integrate perfect hint u7 = -2 Worthy hint ! dim=1017, δ=1.00525490, β=265.11
  250. integrate perfect hint u8 = 0 Worthy hint ! dim=1016, δ=1.00526341, β=264.41
  251. integrate perfect hint u9 = 0 Worthy hint ! dim=1015, δ=1.00527195, β=263.71
  252. integrate perfect hint u10 = 2 Worthy hint ! dim=1014, δ=1.00528229, β=263.01
  253. integrate perfect hint u11 = 0 Worthy hint ! dim=1013, δ=1.00529087, β=262.32
  254. integrate perfect hint u12 = 0 Worthy hint ! dim=1012, δ=1.00529947, β=261.62
  255. integrate perfect hint u13 = 2 Worthy hint ! dim=1011, δ=1.00530810, β=260.93
  256. integrate perfect hint u14 = 0 Worthy hint ! dim=1010, δ=1.00531856, β=260.23
  257. integrate perfect hint u15 = 2 Worthy hint ! dim=1009, δ=1.00532723, β=259.54
  258. integrate perfect hint u16 = 1 Worthy hint ! dim=1008, δ=1.00533593, β=258.85
  259. integrate perfect hint u17 = 0 Worthy hint ! dim=1007, δ=1.00534647, β=258.16
  260. integrate perfect hint u18 = -1 Worthy hint ! dim=1006, δ=1.00535522, β=257.46
  261. integrate perfect hint u19 = 1 Worthy hint ! dim=1005, δ=1.00536399, β=256.77
  262. Integrating q-vectors
  263. [...20] integrate short vector hint 32768*c1023 ∈ Λ Worthy hint ! dim=1004, δ=1.00536426, β=256.76
  264. [...20] integrate short vector hint 32768*c1003 ∈ Λ Worthy hint ! dim=984, δ=1.00536755, β=256.54
  265. Attack Estimation
  266. dim=979 δ=1.005368 β=256.53
  267. ```
  268. The integration of 20 perfect hints implies here a loss of 13 bikz.