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
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

DBDD_predict.sage 5.7KB

  1. from fpylll import *
  2. from math import log
  3. load("../framework/DBDD_generic.sage")
  4. load("../framework/proba_utils.sage")
  5. class DBDD_predict(DBDD_generic):
  6. """
  7. This class defines all the elements defining a DBDD instance
  8. in a prediction mode
  9. """
  10. def __init__(self, B, S, mu, u=None, verbosity=1, **kwargs):
  11. self.Bvol = kwargs.get('Bvol', logdet(B))
  12. self.verbosity = verbosity
  13. self.S = S
  14. self._dim = S.nrows()
  15. self.PP = 0 * S # Span of the projections so far (orthonormal)
  16. # Orthogonal span of the intersection so far so far (orthonormal)
  17. self.PI = 0 * S
  18. self.PI[-1, -1] = 1
  19. self.u = u
  20. self.u_original = u
  21. self.projections = 0
  22. self.save = {"save": None}
  23. self.can_constraints = S.nrows() * [1]
  24. self.can_constraints[-1] = None
  25. self.estimate_attack(silent=True)
  26. def dim(self):
  27. return self._dim
  28. def S_diag(self):
  29. return [self.S[i, i] for i in range(self.S.nrows())]
  30. def volumes(self):
  31. Bvol = self.Bvol
  32. Svol = logdet(self.S + self.PP + self.PI)
  33. dvol = Bvol - Svol / 2.
  34. return (Bvol, Svol, dvol)
  35. @not_after_projections
  36. @hint_integration_wrapper(force=True)
  37. def integrate_perfect_hint(self, v, l):
  38. V = concatenate(v, -l)
  39. for i in range(self.S.nrows()):
  40. if V[0, i]:
  41. self.can_constraints[i] = None
  42. V -= V * self.PI
  43. den = scal(V * V.T)
  44. if den == 0:
  45. raise RejectedHint("Redundant hint")
  46. self.PI += V.T * (V / den)
  47. VS = V * self.S
  48. self.Bvol += log(den) / 2
  49. self._dim -= 1
  50. den = scal(VS * V.T)
  51. self.S -= VS.T * (VS / den)
  52. @not_after_projections
  53. @hint_integration_wrapper(force=True)
  54. def integrate_modular_hint(self, v, l, k, smooth=True):
  55. V = concatenate(v, -l)
  56. for i in range(self.S.nrows()):
  57. if V[0, i] and self.can_constraints[i] is not None:
  58. f = (k / V[0, i]).numerator()
  59. self.can_constraints[i] = lcm(f, self.can_constraints[i])
  60. VS = V * self.S
  61. den = scal(VS * V.T)
  62. if den == 0:
  63. raise RejectedHint("Redundant hint")
  64. if not smooth:
  65. raise NotImplementedError()
  66. self.Bvol += log(k)
  67. @not_after_projections
  68. @hint_integration_wrapper(force=True)
  69. def integrate_approx_hint(self, v, l, variance, aposteriori=False):
  70. if variance < 0:
  71. raise InvalidHint("variance must be non-negative !")
  72. if variance == 0:
  73. raise InvalidHint("variance=0 : must use perfect hint !")
  74. V = concatenate(v, 0)
  75. if not aposteriori:
  76. VS = V * self.S
  77. d = scal(VS * V.T)
  78. self.S -= (1 / (variance + d) * VS.T) * VS
  79. else:
  80. VS = V * self.S
  81. # test if eigenvector
  82. #if not scal(VS * V.T)**2 == scal(VS * VS.T) * scal(V * V.T):
  83. #raise RejectedHint("Not an eigenvector of Σ,")
  84. if not scal(VS * VS.T):
  85. raise RejectedHint("0-Eigenvector of Σ forbidden,")
  86. # New formulae
  87. den = scal(VS * V.T)
  88. self.S += (((variance - den) / den**2) * VS.T ) * VS
  89. @not_after_projections
  90. @hint_integration_wrapper()
  91. def integrate_approx_hint_fulldim(self, center,
  92. covariance, aposteriori=False):
  93. # Using http://www.cs.columbia.edu/~liulp/pdf/linear_normal_dist.pdf
  94. # with A = Id
  95. if not aposteriori:
  96. d = self.S.nrows() - 1
  97. if self.S.rank() != d or covariance.rank() != d:
  98. raise InvalidHint("Covariances not full dimensional")
  99. zero = vec(d * [0])
  100. F = (self.S + block4(covariance, zero.T, zero, vec([1]))).inverse()
  101. F[-1, -1] = 0
  102. self.S -= self.S * F * self.S
  103. else:
  104. raise NotImplementedError()
  105. @hint_integration_wrapper(force=False)
  106. def integrate_short_vector_hint(self, v):
  107. V = concatenate(v, 0)
  108. V -= V * self.PP
  109. den = scal(V * V.T)
  110. if den == 0:
  111. raise InvalidHint("Projects to 0,")
  112. VPI = V * self.PI
  113. if scal(VPI * VPI.T):
  114. raise InvalidHint("Not in Span(Λ),")
  115. if is_cannonical_direction(v):
  116. i, vi = cannonical_param(V)
  117. if vi % self.can_constraints[i]:
  118. raise InvalidHint("Not in Λ,")
  119. else:
  120. if self.verbosity:
  121. self.logging("Not sure if in Λ,",
  122. style="WARNING", newline=False)
  123. self.projections += 1
  124. self.Bvol -= log(RR(den)) / 2.
  125. self._dim -= 1
  126. self.PP += V.T * (V / den)
  127. # This is slower, but equivalent:
  128. # PV = identity_matrix(self.S.ncols()) - projection_matrix(V)
  129. # X = PV.T * self.S * PV
  130. R = (self.S * V.T) * (V / den)
  131. self.S -= R
  132. L = (V.T / den) * (V * self.S)
  133. self.S -= L
  134. @not_after_projections
  135. @hint_integration_wrapper(force=True)
  136. def integrate_q_modular_hint(self, v, l, q):
  137. # Copy-Paste of "perfect hint" integration
  138. V = concatenate(v, -l)
  139. for i in range(self.S.nrows()):
  140. if V[0, i]:
  141. self.can_constraints[i] = None
  142. V -= V * self.PI
  143. den = scal(V * V.T)
  144. if den == 0:
  145. raise RejectedHint("Redundant hint")
  146. self.PI += V.T * (V / den)
  147. VS = V * self.S
  148. self.Bvol += log(den) / 2
  149. self._dim -= 1
  150. den = scal(VS * V.T)
  151. self.S -= VS.T * (VS / den)
  152. def attack(self):
  153. self.logging("Can't run the attack in simulation.", style="WARNING")
  154. return None