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
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.

instance_gen.sage 6.8KB

  1. from random import shuffle, randint
  2. load("../framework/proba_utils.sage")
  3. load("../framework/DBDD_predict_diag.sage")
  4. load("../framework/DBDD_predict.sage")
  5. load("../framework/DBDD.sage")
  6. def initialize_from_LWE_instance(dbdd_class, n, q, m, D_e,
  7. D_s, diag=False, verbosity=1):
  8. """
  9. constructor that builds a DBDD instance from a LWE instance
  10. :n: (integer) size of the secret s
  11. :q: (integer) modulus
  12. :m: (integer) size of the error e
  13. :D_e: distribution of the error e (dictionnary form)
  14. :D_s: distribution of the secret s (dictionnary form)
  15. """
  16. if verbosity:
  17. logging(" Build DBDD from LWE ", style="HEADER")
  18. logging("n=%3d \t m=%3d \t q=%d" % (n, m, q), style="VALUE")
  19. # define the mean and sigma of the instance
  20. mu_e, s_e = average_variance(D_e)
  21. mu_s, s_s = average_variance(D_s)
  22. mu = vec(m * [mu_e] + n * [mu_s] + [1])
  23. S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  24. # draw matrix A and define the lattice
  25. A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  26. B = build_LWE_lattice(-A, q)
  27. D = build_LWE_lattice(A/q, 1/q)
  28. # draw the secrets
  29. s = vec([draw_from_distribution(D_s) for _ in range(n)])
  30. e = vec([draw_from_distribution(D_e) for _ in range(m)])
  31. # compute the public value t and build a target
  32. b = (s * A.T + e) % q
  33. tar = concatenate([b, [0] * n])
  34. B = kannan_embedding(B, tar)
  35. D = kannan_embedding(D, concatenate([-b/q, [0] * n])).T
  36. u = concatenate([e, s, [1]])
  37. return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity, D=D, Bvol=m*log(q))
  38. def initialize_from_LWR_instance(dbdd_class, n, q, p, m, D_s, verbosity=1):
  39. if verbosity:
  40. logging(" Build DBDD from LWR ", style="HEADER")
  41. logging("n=%3d \t m=%3d \t q=%d \t p=%d" % (n, m, q, p), style="VALUE")
  42. D_e = build_mod_switching_error_law(q, p)
  43. # draw matrix A and define the lattice
  44. A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  45. s = vec([draw_from_distribution(D_s) for _ in range(n)])
  46. B = build_LWE_lattice(-A, q)
  47. b = q / p * ((p / q) * s * A.T).apply_map(lambda x: x.round(mode='down'))
  48. e = b - s * A.T
  49. tar = concatenate([b, [0] * n])
  50. B = kannan_embedding(B, tar)
  51. u = concatenate([e, s, [1]])
  52. # define the mean and sigma of the instance
  53. mu_e, s_e = average_variance(D_e)
  54. mu_s, s_s = average_variance(D_s)
  55. mu = vec(m * [mu_e] + n * [mu_s] + [1])
  56. S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  57. return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity)
  58. def initialize_round5_instance(dbdd_class, n, q, p, h, m, D_e,
  59. D_s, verbosity=1):
  60. if verbosity:
  61. logging(" Build DBDD from round5 ", style="HEADER")
  62. logging("n=%3d \t m=%3d \t q=%d \t p=%d" % (n, m, q, p), style="VALUE")
  63. # draw matrix A and define the lattice
  64. assert (h % 2 == 0), "Round5 requires 2 to divide h"
  65. A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  66. s = h / 2 * [1] + h / 2 * [-1] + (n - h) * [0]
  67. shuffle(s)
  68. s = vec(s)
  69. B = build_LWE_lattice(-A, q)
  70. b = vec([q / p * (round((p / q) * ((s * A.T)[0][i] % q)) % p)
  71. for i in range(n)])
  72. e = vec([((- s * A.T)[0][i] + b[0][i]) % q
  73. if ((- s * A.T)[0][i] + b[0][i]) % q < q / 2
  74. else ((- s * A.T)[0][i] + b[0][i]) % q - q
  75. for i in range(n)])
  76. tar = concatenate([b, [0] * n])
  77. B = kannan_embedding(B, tar)
  78. u = concatenate([e, s, [1]])
  79. # define the mean and sigma of the instance
  80. mu_e, s_e = average_variance(D_e)
  81. mu_s, s_s = average_variance(D_s)
  82. mu = vec(m * [mu_e] + n * [mu_s] + [1])
  83. S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  84. return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity)
  85. def initialize_LAC_instance(dbdd_class, n, q, m, D_e, D_s, verbosity=1):
  86. if verbosity:
  87. logging(" Build DBDD for LAC ", style="HEADER")
  88. logging("n=%3d \t m=%3d \t q=%d" % (n, m, q), style="VALUE")
  89. # draw matrix A and define the lattice
  90. A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  91. B = build_LWE_lattice(-A, q)
  92. assert (n % 4 == 0) and (m % 4 == 0), "LAC requires 4 to divide n and m"
  93. s = (n / 4) * [0, 1, 0, -1]
  94. shuffle(s)
  95. s = vec(s)
  96. e = (m / 4) * [0, 1, 0, -1]
  97. shuffle(e)
  98. e = vec(e)
  99. b = (s * A.T + e) % q
  100. tar = concatenate([b, [0] * n])
  101. B = kannan_embedding(B, tar)
  102. u = concatenate([e, s, [1]])
  103. # define the mean and sigma of the instance
  104. mu_e, s_e = average_variance(D_e)
  105. mu_s, s_s = average_variance(D_s)
  106. mu = vec(m * [mu_e] + n * [mu_s] + [1])
  107. S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  108. return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity)
  109. def initialize_NTRU_instance(dbdd_class, n, q, m, D_e, D_s, verbosity=1):
  110. if verbosity:
  111. logging(" Build DBDD for NTRU HPS VERSION ", style="HEADER")
  112. logging("n=%3d \t m=%3d \t q=%d" % (n, m, q), style="VALUE")
  113. assert (q % 16 == 0), "NTRU-HPS requires 16 to divide q"
  114. A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  115. B = build_LWE_lattice(-A, q)
  116. if q / 8 - 2 <= 2 * n / 3:
  117. hamming_weight = (q / 16 - 1)
  118. else:
  119. hamming_weight = floor(n / 3)
  120. s = hamming_weight * [1] + hamming_weight * \
  121. [-1] + (n - 2 * hamming_weight) * [0]
  122. shuffle(s)
  123. s = vec(s)
  124. e = vec([draw_from_distribution(D_e) for _ in range(m)])
  125. b = (s * A.T + e) % q
  126. tar = concatenate([b, [0] * n])
  127. B = kannan_embedding(B, tar)
  128. u = concatenate([e, s, [1]])
  129. # define the mean and sigma of the instance
  130. mu_e, s_e = average_variance(D_e)
  131. mu_s, s_s = average_variance(D_s)
  132. mu = vec(m * [mu_e] + n * [mu_s] + [1])
  133. S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  134. return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity)
  135. # def initialize_NTRU_prime_instance(dbdd_class, n, q, m, h, D_f,
  136. # D_g, verbosity=1):
  137. # if verbosity:
  138. # logging(" Build DBDD for NTRU PRIME VERSION ", style="HEADER")
  139. # logging("n=%3d \t m=%3d \t q=%d \t h=%d" % (n, m, q, h), style="VALUE")
  140. # A = matrix([[randint(0, q) for _ in range(n)] for _ in range(m)])
  141. # B = build_LWE_lattice(-A, q)
  142. # e = h * [1] + (n - h) * [0]
  143. # shuffle(e)
  144. # e = [(-1) ** randint(0, 1) * e[i] for i in range(len(e))]
  145. # e = vec(e)
  146. # s = vec([draw_from_distribution(D_g) for _ in range(m)])
  147. # b = (s * A.T + e) % q
  148. # tar = concatenate([b, [0] * n])
  149. # B = kannan_embedding(B, tar)
  150. # u = concatenate([e, s, [1]])
  151. # # define the mean and sigma of the instance
  152. # mu_e, s_e = average_variance(D_g)
  153. # mu_s, s_s = average_variance(D_f)
  154. # mu = vec(m * [mu_e] + n * [mu_s] + [1])
  155. # S = diagonal_matrix(m * [s_e] + n * [s_s] + [0])
  156. # return A, b, dbdd_class(B, S, mu, u, verbosity=verbosity)