MCPcopy Create free account
hub / github.com/ElementsProject/elements / rec_split

Function rec_split

src/minisketch/tests/pyminisketch.py:278–307  ·  view source on GitHub ↗

Recursively split poly using the Berlekamp trace algorithm.

(poly, randv)

Source from the content-addressed store, hash-verified

276 return []
277
278 def rec_split(poly, randv):
279 """Recursively split poly using the Berlekamp trace algorithm."""
280 # See https://hal.archives-ouvertes.fr/hal-00626997/document.
281 assert len(poly) > 1 and poly[-1] == 1 # Require a monic poly.
282 # If poly is of the form x+a, its root is a.
283 if len(poly) == 2:
284 return [poly[0]]
285 # Try consecutive randomization factors randv, until one is found that factors poly.
286 while True:
287 # Compute the trace of (randv*x) mod poly. This is a polynomial that maps half of the
288 # domain to 0, and the other half to 1. Which half that is is controlled by randv.
289 # By taking it modulo poly, we only add a multiple of poly. Thus the result has at least
290 # the shared roots of the trace polynomial and poly still, but may have others.
291 trace = poly_tracemod(poly, randv, gf)
292 # Using the set {2^i*a for i=0..fieldsize-1} gives optimally independent randv values
293 # (no more than fieldsize are ever needed).
294 randv = gf.mul2(randv)
295 # Now take the GCD of this trace polynomial with poly. The result is a polynomial
296 # that only has the shared roots of the trace polynomial and poly as roots.
297 gcd = poly_gcd(trace, poly, gf)
298 # If the result has a degree higher than 1, and lower than that of poly, we found a
299 # useful factorization.
300 if len(gcd) != len(poly) and len(gcd) > 1:
301 break
302 # Otherwise, continue with another randv.
303 # Find the actual factors: the monic version of the GCD above, and poly divided by it.
304 factor1 = poly_monic(gcd, gf)
305 factor2, _ = poly_divmod(poly, gcd, gf)
306 # Recurse.
307 return rec_split(factor1, randv) + rec_split(factor2, randv)
308
309 # Invoke the recursive splitting with a random initial factor, and sort the results.
310 return sorted(rec_split(poly, random.randrange(1, 1 << gf.field_size)))

Callers 1

poly_find_rootsFunction · 0.85

Calls 5

poly_tracemodFunction · 0.85
poly_gcdFunction · 0.85
poly_monicFunction · 0.85
poly_divmodFunction · 0.85
mul2Method · 0.80

Tested by

no test coverage detected