def test_ratsimpmodprime(): a = y**5 + x + y b = x - y F = [x * y**5 - x - y] assert ratsimpmodprime(a/b, F, x, y, order='lex') == \ (x**2 + x*y + x + y) / (x**2 - x*y) a = x + y**2 - 2 b = x + y**2 - y - 1 F = [x * y - 1] assert ratsimpmodprime(a/b, F, x, y, order='lex') == \ (1 + y - x)/(y - x) a = 5 * x**3 + 21 * x**2 + 4 * x * y + 23 * x + 12 * y + 15 b = 7 * x**3 - y * x**2 + 31 * x**2 + 2 * x * y + 15 * y + 37 * x + 21 F = [x**2 + y**2 - 1] assert ratsimpmodprime(a/b, F, x, y, order='lex') == \ (1 + 5*y - 5*x)/(8*y - 6*x) a = x * y - x - 2 * y + 4 b = x + y**2 - 2 * y F = [x - 2, y - 3] assert ratsimpmodprime(a/b, F, x, y, order='lex') == \ Rational(2, 5) # Test a bug where denominators would be dropped assert ratsimpmodprime(x, [y - 2*x], order='lex') == \ y/2 a = (x**5 + 2 * x**4 + 2 * x**3 + 2 * x**2 + x + 2 / x + x**(-2)) assert ratsimpmodprime(a, [x + 1], domain=GF(2)) == 1 assert ratsimpmodprime(a, [x + 1], domain=GF(3)) == -1
def invert_poly(f_poly, R_poly, p): inv_poly = None if is_prime(p): inv_poly = invert(f_poly, R_poly, domain=GF(p)) elif is_2_power(p): inv_poly = invert(f_poly, R_poly, domain=GF(2)) e = int(math.log(p, 2)) for i in range(1, e): inv_poly = ((2 * inv_poly - f_poly * inv_poly**2) % R_poly).trunc(p) else: raise Exception("Cannot invert polynomial in Z_{}".format(p)) return inv_poly
def invert_poly(f_poly, N, p): R_poly = MOD inv_poly = None if is_prime(p): log.debug("Inverting as p={} is prime".format(p)) inv_poly = invert(f_poly, R_poly, domain=GF(p)) elif is_2_power(p): log.debug("Inverting as p={} is 2 power".format(p)) inv_poly = invert(f_poly, R_poly, domain=GF(2)) e = int(math.log(p, 2)) for i in range(1, e): log.debug("Inversion({}): {}".format(i, inv_poly)) inv_poly = ((2 * inv_poly - f_poly * inv_poly**2) % R_poly).trunc(p)
def calc_gen(): """ Calculate generator polynomial based on a given primitive polynomial. """ # Initialize primitive polynomial in GF(q). prim_poly = Poly(alpha**m + alpha**4 + 1, alpha).set_domain(GF(q)) print('Primitive poly: %s' % prim_poly) gen_poly = None for i in range(1, t * 2): # No need to calculate for even i. if i % 2 is not 0: print('Current i: %d' % i) # On first loop, calculate only minimal polynomial. if gen_poly is None: gen_poly = min_poly(i, prim_poly) # Otherwise calculate lowest common multiplier using current value # of generator polynomial and minimal polynomial with current i. else: gen_poly = lcm(gen_poly, min_poly(i, prim_poly)) # Truncate to GF(q). gen_poly = gen_poly.trunc(q) print('Generator poly: %s' % gen_poly) return prim_poly, gen_poly
def test_5x5(self): field = GF(2) matrix = array([[0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0]]) correct_result = array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) self.gaussian_comparer(matrix, field, correct_result, 2)
def reduce_mod(self, modulus): """ Returns the reduction modulo modulus Defined only for field == QQ """ if self.field != QQ: raise ValueError(f"Reducion can be done only for a vector over rationals but the field is {self.field}") mod_field = GF(modulus) result = SparseVector(self.dim, mod_field) for i in self._nonzero: entry = self._data[i] if mod_field.convert(entry.denominator) == 0: raise ZeroDivisionError(f"Division by zero while taking modulo {modulus}") entry_mod = mod_field.convert(entry.numerator) / mod_field.convert(entry.denominator) if entry_mod: result.__append__(i, entry_mod) return result
def invert_poly(f_poly, R_poly, p): inv_poly = None if is_prime(p): log.debug("Inverting as p={} is prime".format(p)) inv_poly = invert(f_poly, R_poly, domain=GF(p)) elif is_2_power(p): log.debug("Inverting as p={} is 2 power".format(p)) inv_poly = invert(f_poly, R_poly, domain=GF(2)) e = int(math.log(p, 2)) for i in range(1, e): log.debug("Inversion({}): {}".format(i, inv_poly)) inv_poly = ((2 * inv_poly - f_poly * inv_poly**2) % R_poly).trunc(p) else: raise Exception("Cannot invert polynomial in Z_{}".format(p)) log.debug("Inversion: {}".format(inv_poly)) return inv_poly
def __init__(self, universe: Set, rank: int): self.universe: frozenset = frozenset(universe) self._rank: int = rank self.field: GF = GF(nextprime(self.size)) self.mapping: bidict = bidict( {value: i for i, value in enumerate(universe)}) self._matrix: ndarray = UniformMatroid._create_matrix( self.size, rank, self.field)
def invertmodprime(F, N, p): Fp = Zx([]) f = F.coeffs[::-1] f_poly = make_poly(f) x = sym.Symbol('x') t = sym.polys.polytools.invert(f_poly, x**N - 1, domain=GF(p, symmetric=False)) Fp.coeffs = t.all_coeffs()[::-1] return Fp
def power_dict(n, irr, p): result = {(1, ): 0} test_poly = Poly(1, alpha) for i in range(1, n - 1): test_poly = (Poly(Poly(alpha, alpha) * test_poly, alpha) % irr).set_domain(GF(p)) if tuple(test_poly.all_coeffs()) in result: return result result[tuple(test_poly.all_coeffs())] = i return result
def reduce_mod(self, modulus): """ Reduction modulo prime modulus. Works only for field == QQ """ if self.field != QQ: raise ValueError(f"Reducion can be done only for a vector over rationals but the field is {self.field}") result = Subspace(GF(modulus)) for piv, vec in self._echelon_form.items(): vec_red = vec.reduce_mod(modulus) if not vec_red.is_zero(): result._echelon_form[piv] = vec_red return result
def reduce_mod(self, modulus): """ Returns the reduction modulo modulus Works only if field == QQ """ if self.field != QQ: raise ValueError(f"Reducion can be done only for a vector over rationals but the field is {self.field}") result = SparseRowMatrix(self.dim, GF(modulus)) for i in self._nonzero: row_reduced = self._data[i].reduce_mod(modulus) if not row_reduced.is_zero(): result._nonzero.append(i) result._data[i] = row_reduced return result
def first_alpha_power_root(poly, irr_poly, p, elements_to_check=None): poly = Poly([(Poly(coeff, alpha) % irr_poly).trunc(p).as_expr() for coeff in poly.all_coeffs()], x) test_poly = Poly(1, alpha) log.debug(f"testing f:{poly}") for i in range(1, p**irr_poly.degree()): test_poly = (Poly(Poly(alpha, alpha) * test_poly, alpha) % irr_poly).set_domain(GF(p)) if elements_to_check is not None and i not in elements_to_check: continue value = Poly((Poly(poly.eval(test_poly.as_expr()), alpha) % irr_poly), alpha).trunc(p) log.debug(f"testing alpha^{i} f({test_poly})={value}") if value.is_zero: return i return -1
def flatten_frac(muls, m, p, pow_dict): if len(muls.args) == 0: return (Poly(muls, alpha) % m).set_domain(GF(p)) log.debug("Dividing: {}".format(muls)) if len(muls.args) != 2: raise Exception("Wrong case") inv = muls.args[0] add = muls.args[1] if type(add) == Pow: inv, add = add, inv log.debug("num: {}; denum: {}".format(add, inv)) if type(add) != Add and type(add) != Symbol and type(add) != Pow: log.debug(type(add)) add = int(add) if add < 0: inv_poly = (Poly(muls.args[0]**-add) % m).set_domain(GF(p)) if inv_poly.is_zero: raise Exception("Dividing by 0") result_pow = pow_dict[tuple(inv_poly.all_coeffs())] if result_pow < 0: result_pow += len(pow_dict) result = Poly(alpha**result_pow, alpha).set_domain(GF(p)) log.debug("Dividing result: {}".format(result)) return (result % m).set_domain(GF(p)) if (inv.args[1] > 0): print(inv.args) raise Exception("Wrong case") add_poly = (Poly(add) % m).set_domain(GF(p)) if add_poly.is_zero: return add_poly i = pow_dict[tuple(add_poly.all_coeffs())] inv_poly = (Poly(inv.args[0]**-inv.args[1]) % m).set_domain(GF(p)) if inv_poly.is_zero: raise Exception("Dividing by 0") j = pow_dict[tuple(inv_poly.all_coeffs())] result_pow = i - j if result_pow < 0: result_pow += len(pow_dict) result = Poly(alpha**result_pow, alpha).set_domain(GF(p)) log.debug("Dividing result: {}".format(result)) return (result % m).set_domain(GF(p))
def test_1x2(self): field = GF(5) matrix = array([[1, 3]]) with self.assertRaises(ValueError): self.determinant_comparer(matrix, field, 3)
def test_dependent_row(self): field = GF(5) matrix = array([[3, 4], [1, 3]]) self.determinant_comparer(matrix, field, 0)
import sympy as sym from sympy import GF def make_poly(coeffs): """Create a polynomial in x.""" x = sym.Symbol('x') N = len(coeffs) coeffs = list(reversed(coeffs)) y = 0 for i in range(N): y += (x**i)*coeffs[i] y = sym.poly(y) return y N = 7 p = 3 q = 41 #-x^4 + x^3 + x^2 - x + 1 f = [-1,1,1,-1,1] f_poly = make_poly(f) x = sym.Symbol('x') Fp = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(p, symmetric=False)) Fq = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(q, symmetric=False)) print('\nf =',f_poly) print('\nFp =',Fp) print('\nFq =',Fq)
def test_copy(self): field = GF(5) matrix = array([[1, 2], [2, 3]]) matrix_copy = matrix.copy() gaussian_elimination(matrix, field) assert_array_equal(matrix, matrix_copy, "Matrix hasn't been copied")
return int(hashlib.sha256(data).hexdigest(), 16) def get_targets(): target_vals = [] for filename in os.listdir("target_files"): target_vals.append(fhash("target_files/" + filename)) return target_vals target_vals = get_targets() pp = gen_prime(256, max(target_vals)) x = Symbol('x') domain = range(10000) random.shuffle(domain) pl = simplify(interpolate_lagrange(x, domain[:len(target_vals)], target_vals)) pl = poly(pl, domain=GF(pp)) print "PRNG polynomial: ", pl print "The initial values of the PRNG:" for i in range(10): tmp = pl.eval(i) % pp tmp = base58.b58encode_int(tmp) print "Qm" + tmp, base58.b58decode_int(tmp) print "The target values are:", target_vals print "Sanity check..." for i in domain[:len(target_vals)]: print i, pl.eval(i) % pp
def test_dependent_column(self): field = GF(5) matrix = array([[1, 2], [4, 3]]) self.determinant_comparer(matrix, field, 0)
def test_2x2(self): field = GF(11) matrix = array([[1, 2], [3, 4]]) self.determinant_comparer(matrix, field, 9)
def invert_polynomial(f_polynomial, N, p): modulus_polynomial = MOD return invert(f_polynomial, modulus_polynomial, domain=GF(p))
def runDomain(a, b, m): if m == 'rat': EuclidsAlgorithm(a, b, m, 'QQ') else: EuclidsAlgorithm(a, b, m, GF(m))
def test_2x2(self): field = GF(7) matrix = array([[1, 2], [4, 5]]) correct_result = array([[4, 5], [0, 6]]) self.gaussian_comparer(matrix, field, correct_result, 1)
def test_1x1(self): field = GF(2) matrix = array([[1]]) self.determinant_comparer(matrix, field, 1)
def test_3x3(self): field = GF(7) matrix = array([[6, 2, 3], [1, 4, 1], [2, 2, 5]]) correct_result = array([[6, 2, 3], [0, 6, 4], [0, 0, 0]]) self.gaussian_comparer(matrix, field, correct_result, 0)
def power_dict(n, irr, p): result = dict() for i in range(1, n + 1): test_poly = (Poly(alpha**i, alpha) % irr).set_domain(GF(p)) result[tuple(test_poly.all_coeffs())] = i return result
def test_3x4(self): field = GF(11) matrix = array([[1, 2, 3, 4], [3, 6, 9, 1], [2, 5, 4, 8]]) correct_result = array([[3, 6, 9, 1], [0, 1, 9, 0], [0, 0, 0, 0]]) self.gaussian_comparer(matrix, field, correct_result, 2)
print('--------------------------------------------------') """ extgcd """ def gen_poly(coeffs, N): """Create a polynomial in x.""" x = sym.Symbol('x') coeffs = list(coeffs) y = 0 for i in range(N): y += (x**i) * coeffs[i] y = sym.poly(y) return y f_poly = gen_poly(f, len(f)) x = sym.Symbol('x') t1 = time.time() fp = sym.polys.polytools.invert(f_poly, x**N - 1, domain=GF(3, symmetric=False)) t2 = time.time() ans2 = fp.all_coeffs() ans2.reverse() print(ans2) print('exgcd time \t\t\t:', t2 - t1) print(f'\n{ans1 == ans2}')
def test_3x3(self): field = GF(11) matrix = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) self.determinant_comparer(matrix, field, 0)