Révision 125
pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 125) | ||
---|---|---|
97 | 97 |
NOTE:: |
98 | 98 |
When number >= 2^(emax+1), we return the "fake" binade |
99 | 99 |
[2^(emax+1), +infinity]. Ditto for number <= -2^(emax+1) |
100 |
with interval [-infinity, -2^(emax+1)]. |
|
100 |
with interval [-infinity, -2^(emax+1)]. We want to distinguish |
|
101 |
this case from that of "really" invalid arguments. |
|
101 | 102 |
|
102 | 103 |
""" |
103 | 104 |
# Check the parameters. |
104 |
# RealNumbers only. |
|
105 |
# RealNumbers or RealNumber offspring only. |
|
106 |
# The execption construction is necessary since not all objects have |
|
107 |
# the mro() method. sage.rings.real_mpfr.RealNumber do. |
|
105 | 108 |
try: |
106 | 109 |
classTree = [number.__class__] + number.mro() |
107 | 110 |
if not sage.rings.real_mpfr.RealNumber in classTree: |
... | ... | |
116 | 119 |
return None |
117 | 120 |
precision = number.precision() |
118 | 121 |
RF = RealField(precision) |
122 |
if number == 0: |
|
123 |
return (RF(0),RF(2^(emin)) - RF(2^(emin-precision))) |
|
119 | 124 |
# A more precise RealField is needed to avoid unwanted rounding effects |
120 | 125 |
# when computing number.log2(). |
121 | 126 |
RRF = RealField(max(2048, 2 * precision)) |
122 | 127 |
# number = 0 special case, the binade bounds are |
123 | 128 |
# [0, 2^emin - 2^(emin-precision)] |
124 |
if number == 0: |
|
125 |
return (RF(0),RF(2^(emin)) - RF(2^(emin-precision))) |
|
126 | 129 |
# Begin general case |
127 | 130 |
l2 = RRF(number).abs().log2() |
128 | 131 |
# Another special one: beyond largest representable -> "Fake" binade. |
129 | 132 |
if l2 >= emax + 1: |
130 | 133 |
if number > 0: |
131 |
return (RF(2^(emax+1)), RRR(+infinity) )
|
|
134 |
return (RF(2^(emax+1)), RF(+infinity) )
|
|
132 | 135 |
else: |
133 | 136 |
return (RF(-infinity), -RF(2^(emax+1))) |
134 | 137 |
offset = int(l2) |
... | ... | |
196 | 199 |
A list of bivariate integer polynomial obtained using the Coppersmith |
197 | 200 |
algorithm. The polynomials correspond to the rows of the LLL-reduce |
198 | 201 |
reduced base that comply with the Coppersmith condition. |
199 |
|
|
200 |
TODO:: |
|
201 |
Full rewrite, this is barely a draft. |
|
202 | 202 |
""" |
203 | 203 |
# Arguments check. |
204 | 204 |
if iBound == 0 or tBound == 0: |
... | ... | |
235 | 235 |
reducedMatrix = matrixToReduce.LLL(fp='fp') |
236 | 236 |
isLLLReduced = reducedMatrix.is_LLL_reduced() |
237 | 237 |
if not isLLLReduced: |
238 |
return () |
|
238 |
return set()
|
|
239 | 239 |
monomialsCount = len(knownMonomials) |
240 | 240 |
monomialsCountSqrt = sqrt(monomialsCount) |
241 | 241 |
#print "Monomials count:", monomialsCount, monomialsCountSqrt.n() |
... | ... | |
247 | 247 |
l2Norm = row.norm(2) |
248 | 248 |
if (l2Norm * monomialsCountSqrt) < nAtAlpha: |
249 | 249 |
#print (l2Norm * monomialsCountSqrt).n() |
250 |
print l2Norm.n() |
|
250 |
#print l2Norm.n()
|
|
251 | 251 |
ccReducedPolynomial = \ |
252 | 252 |
slz_compute_reduced_polynomial(row, |
253 | 253 |
knownMonomials, |
... | ... | |
258 | 258 |
if not ccReducedPolynomial is None: |
259 | 259 |
ccReducedPolynomialsList.append(ccReducedPolynomial) |
260 | 260 |
else: |
261 |
print l2Norm.n() , ">", nAtAlpha |
|
261 |
#print l2Norm.n() , ">", nAtAlpha
|
|
262 | 262 |
pass |
263 | 263 |
if len(ccReducedPolynomialsList) < 2: |
264 |
print "***Less than 2 Coppersmith condition compliant vectors.***"
|
|
264 |
print "Less than 2 Coppersmith condition compliant vectors."
|
|
265 | 265 |
return () |
266 |
|
|
267 |
#print ccReducedPolynomialsList |
|
266 | 268 |
return ccReducedPolynomialsList |
267 | 269 |
# End slz_compute_coppersmith_reduced_polynomials |
268 | 270 |
|
... | ... | |
286 | 288 |
# Whatever the 2 variables are actually called, we call them |
287 | 289 |
# 'i' and 't' in all the variable names. |
288 | 290 |
(iVariable, tVariable) = inputPolynomial.variables()[:2] |
289 |
#print polyVars[0], type(polyVars[0]) |
|
290 |
initialPolynomial = inputPolynomial.subs({iVariable:iVariable * iBound, |
|
291 |
tVariable:tVariable * tBound}) |
|
292 |
polynomialsList = \ |
|
293 |
spo_polynomial_to_polynomials_list_5(initialPolynomial, |
|
294 |
alpha, |
|
295 |
N, |
|
296 |
iBound, |
|
297 |
tBound, |
|
298 |
0) |
|
299 |
#print "Polynomials list:", polynomialsList |
|
300 |
## Building the proto matrix. |
|
301 |
knownMonomials = [] |
|
302 |
protoMatrix = [] |
|
303 |
for poly in polynomialsList: |
|
304 |
spo_add_polynomial_coeffs_to_matrix_row(poly, |
|
305 |
knownMonomials, |
|
306 |
protoMatrix, |
|
307 |
0) |
|
308 |
matrixToReduce = spo_proto_to_row_matrix(protoMatrix) |
|
309 |
#print matrixToReduce |
|
310 |
## Reduction and checking. |
|
311 |
reducedMatrix = matrixToReduce.LLL(fp='fp') |
|
312 |
isLLLReduced = reducedMatrix.is_LLL_reduced() |
|
313 |
if not isLLLReduced: |
|
314 |
return set() |
|
315 |
monomialsCount = len(knownMonomials) |
|
316 |
monomialsCountSqrt = sqrt(monomialsCount) |
|
317 |
#print "Monomials count:", monomialsCount, monomialsCountSqrt.n() |
|
318 |
#print reducedMatrix |
|
319 |
## Check the Coppersmith condition for each row and build the reduced |
|
320 |
# polynomials. |
|
321 |
ccReducedPolynomialsList = [] |
|
322 |
for row in reducedMatrix.rows(): |
|
323 |
l2Norm = row.norm(2) |
|
324 |
if (l2Norm * monomialsCountSqrt) < nAtAlpha: |
|
325 |
#print (l2Norm * monomialsCountSqrt).n() |
|
326 |
#print l2Norm.n() |
|
327 |
ccReducedPolynomial = \ |
|
328 |
slz_compute_reduced_polynomial(row, |
|
329 |
knownMonomials, |
|
330 |
iVariable, |
|
331 |
iBound, |
|
332 |
tVariable, |
|
333 |
tBound) |
|
334 |
if not ccReducedPolynomial is None: |
|
335 |
ccReducedPolynomialsList.append(ccReducedPolynomial) |
|
336 |
else: |
|
337 |
#print l2Norm.n() , ">", nAtAlpha |
|
338 |
pass |
|
339 |
if len(ccReducedPolynomialsList) < 2: |
|
340 |
print "Less than 2 Coppersmith condition compliant vectors." |
|
341 |
return set() |
|
342 |
#print ccReducedPolynomialsList |
|
291 |
ccReducedPolynomialsList = \ |
|
292 |
slz_compute_coppersmith_reduced_polynomials (inputPolynomial, |
|
293 |
alpha, |
|
294 |
N, |
|
295 |
iBound, |
|
296 |
tBound) |
|
297 |
if len(ccReducedPolynomialsList) == 0: |
|
298 |
return set() |
|
343 | 299 |
## Create the valid (poly1 and poly2 are algebraically independent) |
344 | 300 |
# resultant tuples (poly1, poly2, resultant(poly1, poly2)). |
345 | 301 |
# Try to mix and match all the polynomial pairs built from the |
... | ... | |
390 | 346 |
return polynomialRootsSet |
391 | 347 |
# End slz_compute_integer_polynomial_modular_roots. |
392 | 348 |
# |
349 |
def slz_compute_integer_polynomial_modular_roots_2(inputPolynomial, |
|
350 |
alpha, |
|
351 |
N, |
|
352 |
iBound, |
|
353 |
tBound): |
|
354 |
""" |
|
355 |
For a given set of arguments (see below), compute the polynomial modular |
|
356 |
roots, if any. |
|
357 |
This version differs in the way resultants are computed. |
|
358 |
""" |
|
359 |
# Arguments check. |
|
360 |
if iBound == 0 or tBound == 0: |
|
361 |
return set() |
|
362 |
# End arguments check. |
|
363 |
nAtAlpha = N^alpha |
|
364 |
## Building polynomials for matrix. |
|
365 |
polyRing = inputPolynomial.parent() |
|
366 |
# Whatever the 2 variables are actually called, we call them |
|
367 |
# 'i' and 't' in all the variable names. |
|
368 |
(iVariable, tVariable) = inputPolynomial.variables()[:2] |
|
369 |
#print polyVars[0], type(polyVars[0]) |
|
370 |
ccReducedPolynomialsList = \ |
|
371 |
slz_compute_coppersmith_reduced_polynomials (inputPolynomial, |
|
372 |
alpha, |
|
373 |
N, |
|
374 |
iBound, |
|
375 |
tBound) |
|
376 |
if len(ccReducedPolynomialsList) == 0: |
|
377 |
return set() |
|
378 |
## Create the valid (poly1 and poly2 are algebraically independent) |
|
379 |
# resultant tuples (poly1, poly2, resultant(poly1, poly2)). |
|
380 |
# Try to mix and match all the polynomial pairs built from the |
|
381 |
# ccReducedPolynomialsList to obtain non zero resultants. |
|
382 |
resultantsInTTuplesList = [] |
|
383 |
for polyOuterIndex in xrange(0, len(ccReducedPolynomialsList)-1): |
|
384 |
for polyInnerIndex in xrange(polyOuterIndex+1, |
|
385 |
len(ccReducedPolynomialsList)): |
|
386 |
# Compute the resultant in resultants in the |
|
387 |
# first variable (is it the optimal choice?). |
|
388 |
resultantInT = \ |
|
389 |
ccReducedPolynomialsList[polyOuterIndex].resultant(ccReducedPolynomialsList[polyInnerIndex], |
|
390 |
ccReducedPolynomialsList[0].parent(str(tVariable))) |
|
391 |
#print "Resultant", resultantInT |
|
392 |
# Test algebraic independence. |
|
393 |
if not resultantInT.is_zero(): |
|
394 |
resultantsInTTuplesList.append((ccReducedPolynomialsList[polyOuterIndex], |
|
395 |
ccReducedPolynomialsList[polyInnerIndex], |
|
396 |
resultantInT)) |
|
397 |
# If no non zero resultant was found: we can't get no algebraically |
|
398 |
# independent polynomials pair. Give up! |
|
399 |
if len(resultantsInTTuplesList) == 0: |
|
400 |
return set() |
|
401 |
#print resultantsInITuplesList |
|
402 |
# Compute the roots. |
|
403 |
Zi = ZZ[str(iVariable)] |
|
404 |
Zt = ZZ[str(tVariable)] |
|
405 |
polynomialRootsSet = set() |
|
406 |
# First, solve in the second variable since resultants are in the first |
|
407 |
# variable. |
|
408 |
for resultantInTTuple in resultantsInTTuplesList: |
|
409 |
iRootsList = Zi(resultantInTTuple[2]).roots() |
|
410 |
# For each iRoot, compute the corresponding tRoots and check |
|
411 |
# them in the input polynomial. |
|
412 |
for iRoot in iRootsList: |
|
413 |
#print "iRoot:", iRoot |
|
414 |
# Roots returned by root() are (value, multiplicity) tuples. |
|
415 |
tRootsList = \ |
|
416 |
Zt(resultantInTTuple[0].subs({resultantInTTuple[0].variables()[0]:iRoot[0]})).roots() |
|
417 |
print tRootsList |
|
418 |
# The tRootsList can be empty, hence the test. |
|
419 |
if len(tRootsList) != 0: |
|
420 |
for tRoot in tRootsList: |
|
421 |
polyEvalModN = inputPolynomial(iRoot[0],tRoot[0]) / N |
|
422 |
# polyEvalModN must be an integer. |
|
423 |
if polyEvalModN == int(polyEvalModN): |
|
424 |
polynomialRootsSet.add((iRoot[0],tRoot[0])) |
|
425 |
return polynomialRootsSet |
|
426 |
# End slz_compute_integer_polynomial_modular_roots_2. |
|
427 |
# |
|
393 | 428 |
def slz_compute_polynomial_and_interval(functionSo, degreeSo, lowerBoundSa, |
394 | 429 |
upperBoundSa, approxPrecSa, |
395 | 430 |
sollyaPrecSa=None): |
... | ... | |
482 | 517 |
var2, |
483 | 518 |
var2Bound): |
484 | 519 |
""" |
485 |
Compute a polynomial from a reduced matrix row. |
|
520 |
Compute a polynomial from a single reduced matrix row.
|
|
486 | 521 |
This function was introduced in order to avoid the computation of the |
487 |
polynomials (even those built from rows that do no verify the Coppersmith |
|
488 |
condition. |
|
522 |
all the polynomials from the full matrix (even those built from rows |
|
523 |
that do no verify the Coppersmith condition) as this may involves |
|
524 |
expensive operations over (large) integer. |
|
489 | 525 |
""" |
490 | 526 |
## Check arguments. |
491 | 527 |
if len(knownMonomials) == 0: |
Formats disponibles : Unified diff