def intersect(i, j, **gb_opts): """ This functions intersects two ideals. The first ring variable is used as helper variable for this intersection. It is assumed, that it doesn't occur in the ideals, and that we have an elimination ordering for this variables. Both assumptions are checked. >>> from polybori.frontend import declare_ring >>> from polybori import Block >>> r=declare_ring(Block("x", 1000), globals()) >>> x = r.variable >>> intersect([x(1),x(2)+1],[x(1),x(2)]) [x(1)] """ if not i or not j: return [] uv = used_vars_set(i) * used_vars_set(j) t = iter(i).next().ring().variable(0) if uv.reducible_by(t): raise ValueError, \ "First ring variable has to be reserved as helper variable t" if not t > uv: raise ValueError, "need elimination ordering for first ring variable" gb = groebner_basis( list(chain((t * p for p in i), ((1 + t) * p for p in j))), **gb_opts) return [p for p in gb if p.navigation().value() > t.index()]
def intersect(i, j, **gb_opts): """ This functions intersects two ideals. The first ring variable is used as helper variable for this intersection. It is assumed, that it doesn't occur in the ideals, and that we have an elimination ordering for this variables. Both assumptions are checked. >>> from polybori.frontend import declare_ring >>> from polybori import Block >>> r=declare_ring(Block("x", 1000), globals()) >>> x = r.variable >>> intersect([x(1),x(2)+1],[x(1),x(2)]) [x(1)] """ if not i or not j: return [] uv = used_vars_set(i) * used_vars_set(j) t = iter(i).next().ring().variable(0) if uv.reducible_by(t): raise ValueError, \ "First ring variable has to be reserved as helper variable t" if not t > uv: raise ValueError, "need elimination ordering for first ring variable" gb = groebner_basis(list(chain((t * p for p in i), ((1 + t) * p for p in j ))), **gb_opts) return [p for p in gb if p.navigation().value() > t.index()]
def ideals(self): def sort_key(p): return p.navigation().value() def my_sort(l): return sorted(l, key=sort_key) #self.intermediate_equations = self.gauss(self.intermediate_equations) tail_variables = set(used_vars_set([e.mapped_to for e in chain(self.next_state_equations, self.intermediate_equations)]).variables()) to_delete=[] for v in self.deletion_candidates: if not v in tail_variables: to_delete.append(v) to_delete=set(to_delete) self.intermediate_equations=[e for e in self.intermediate_equations if not e.variable in to_delete] #we don't delete the variable itself, as we will confuse gluemultipliers,that looks on the lengths of self.intermediate... def equations(determining_equations): return [e.equation for e in determining_equations] ideal_state=[] ideal_next_state = equations(self.next_state_equations) ideal_intermediate = equations(self.intermediate_equations) if self.initialize!="noinit": if self.initialize=="zero": initializer = zero_fun else: initializer = random_bit for v in variables: if str(v)[:1]=="s": ideal_state.append(v+initializer()) return [ my_sort(self.apply_map(i)) for i in (ideal_state,ideal_intermediate, ideal_next_state)]
def add_polynomial_to_cluster(self, p): self.cluster.add(p) self.used_variables_cluster = set( used_vars_set(self.cluster).variables()) self.number_of_used_variables_in_cluster = len( self.used_variables_cluster) self.adjust_variables_introduction_mapping( self.used_variables_of_polynomial[p])
def eliminate_ll_ranked(ll_system, to_reduce, reduction_function=ll_red_nf_noredsb, reduce_ll_system=False, prot=False): assert ll_system from_ring = ll_system[0].ring() ll_ranks = rank(ll_system) add_vars = set(used_vars_set(to_reduce).variables()).difference(ll_ranks.keys()) for v in add_vars: ll_ranks[v] = -1 # pushing variables ignored by ll to the front means, # that the routines will quickly eliminate them # and they won't give any overhead def sort_key(v): return (ll_ranks[v], v.index()) sorted_vars = sorted(ll_ranks.keys(), key=sort_key) def var_index(v): return iter(Monomial(v).variables()).next().index() # sorted_var_indices=[var_index(v) for v in sorted_vars] to_ring = Ring(len(sorted_vars)) map_back_indices = dict([(i, var_index(v)) for (i, v) in enumerate(sorted_vars)]) map_from_indices = dict([(var_index(v), i) for (i, v) in enumerate(sorted_vars)]) # dict([(v,k) for (k,v) in enumerate(sorted_var_indices)]) var_names = [str(v) for v in sorted_vars] try: for (i, v) in enumerate(sorted_vars): assert var_names[i] == str(v), (var_names[i], v, var_index(v), i) # _set_variable_name(to_ring, i, var_names[i] + "TO") finally: pass try: map_from_vec = construct_map_by_indices(to_ring, map_from_indices) finally: pass map_back_vec = construct_map_by_indices(from_ring, map_back_indices) def map_from(p): res = substitute_variables(to_ring, map_from_vec, p) # assert str(p)==str(res), (str(p), str(res), list(map_from_vec), list(map_back_vec)) return res def map_back(p): return substitute_variables(from_ring, map_back_vec, p) try: ll_opt_encoded = ll_encode([map_from(p) for p in ll_system], prot=False, reduce=reduce_ll_system) def llnf(p): return map_back(reduction_function(map_from(p), ll_opt_encoded)) opt_eliminated = [llnf(p) for p in to_reduce] finally: pass return (llnf, opt_eliminated)
def want_la(): if not I: return False n_used_vars = None bound = None if iter(I).next().ring().has_degree_order(): new_bound = 200 n_used_vars = used_vars_set(I, bound=new_bound).deg() if n_used_vars < new_bound: return True bound = new_bound if dense_system(I): new_bound = 100 if not (bound and new_bound < bound): n_used_vars = used_vars_set(I, bound=new_bound).deg() bound = new_bound if n_used_vars < bound: return True return False
def ll_is_good(I): lex_lead = set() for p in I: if not p.is_zero(): m = p.lex_lead() if m.deg() == 1: lex_lead.add(iter(m.variables()).next().index()) if len(lex_lead) >= 0.8 * len(I): uv = used_vars_set(I).deg() # don't use len here, which will yield 1 if len(lex_lead) > 0.9 * uv: if uv - len(lex_lead) > 16: return "llfirstonthefly" else: return "llfirst" return False
def variety_size_from_gb(I): """ >>> r=Ring(100) >>> x = r.variable >>> variety_size_from_gb([]) 1 >>> variety_size_from_gb([Polynomial(0, r)]) 1 >>> variety_size_from_gb([Polynomial(1, r)]) 0.0 >>> variety_size_from_gb([x(1)]) 1.0 >>> variety_size_from_gb([x(1), x(2)]) 1.0 >>> variety_size_from_gb([x(1), x(2)*x(3)]) 3.0 >>> variety_size_from_gb([x(1), x(1)*x(4), x(2)*x(3)]) 6.0 >>> variety_size_from_gb([x(1)*x(2), x(2)*x(3)]) 5.0 >>> mons = [Monomial([r.variable(i) for i in xrange(100) if i!=j])\ for j in xrange(100)] >>> variety_size_from_gb(mons) 1.2676506002282294e+30 """ I = [Polynomial(p) for p in I] I = [p for p in I if not p.is_zero()] if len(I) == 0: return 1 ## # TODO Here's something wrong! See the example with 5 solutions. ## # (reverting for now) ## number_of_used_vars = used_vars_set(I).deg() ## leads = set([p.lead() for p in I]) ## minimal_leads = BooleSet(leads).minimal_elements() ## number_of_used_vars_minimal_leads =\ ## minimal_leads.vars().deg() ## standard_monomials =\ ## minimal_leads.include_divisors().diff(minimal_leads) ## return standard_monomials.size_double()*\ ## 2**(number_of_used_vars-number_of_used_vars_minimal_leads) sm = Monomial(used_vars_set(I)).divisors() for p in I: m = p.lead() sm = sm.diff(sm.multiples_of(m)) return sm.size_double()
def dimacs_cnf(self, polynomial_system): r""" >>> from polybori import * >>> r = declare_ring(["x", "y", "z"], dict()) >>> e = CryptoMiniSatEncoder(r) >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2)]) 'c cnf generated by PolyBoRi\np cnf 3 1\n-1 -2 -3 0\nc g 1 x*y*z\nc v 1 x\nc v 2 y\nc v 3 z' >>> e.dimacs_cnf([r.variable(1)+r.variable(0)]) 'c cnf generated by PolyBoRi\np cnf 3 1\nx1 2 0\nc g 2 x + y\nc v 1 x\nc v 2 y' >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2), r.variable(1)+r.variable(0)]) 'c cnf generated by PolyBoRi\np cnf 3 2\n-1 -2 -3 0\nc g 3 x*y*z\nx1 2 0\nc g 4 x + y\nc v 1 x\nc v 2 y\nc v 3 z' """ uv=list(used_vars_set(polynomial_system).variables()) res=super(CryptoMiniSatEncoder, self).dimacs_cnf(polynomial_system) res=res+"\n"+"\n".join(["c v %s %s"% (self.to_dimacs_index(v), v) for v in uv]) return res
def dimacs_cnf(self, polynomial_system): r""" >>> from polybori import * >>> r = declare_ring(["x", "y", "z"], dict()) >>> e = CryptoMiniSatEncoder(r) >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2)]) 'c cnf generated by PolyBoRi\np cnf 3 1\n-1 -2 -3 0\nc g 1 x*y*z\nc v 1 x\nc v 2 y\nc v 3 z' >>> e.dimacs_cnf([r.variable(1)+r.variable(0)]) 'c cnf generated by PolyBoRi\np cnf 3 1\nx1 2 0\nc g 2 x + y\nc v 1 x\nc v 2 y' >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2), r.variable(1)+r.variable(0)]) 'c cnf generated by PolyBoRi\np cnf 3 2\n-1 -2 -3 0\nc g 3 x*y*z\nx1 2 0\nc g 4 x + y\nc v 1 x\nc v 2 y\nc v 3 z' """ uv = list(used_vars_set(polynomial_system).variables()) res = super(CryptoMiniSatEncoder, self).dimacs_cnf(polynomial_system) res = res + "\n" + "\n".join(["c v %s %s" % (self.to_dimacs_index(v), v) for v in uv]) return res
def ideals(self): def sort_key(p): return p.navigation().value() def my_sort(l): return sorted(l, key=sort_key) #self.intermediate_equations = self.gauss(self.intermediate_equations) tail_variables = set( used_vars_set([ e.mapped_to for e in chain(self.next_state_equations, self.intermediate_equations) ]).variables()) to_delete = [] for v in self.deletion_candidates: if not v in tail_variables: to_delete.append(v) to_delete = set(to_delete) self.intermediate_equations = [ e for e in self.intermediate_equations if not e.variable in to_delete ] # we don't delete the variable itself, as we will confuse # gluemultipliers,that looks on the lengths of self.intermediate... def equations(determining_equations): return [e.equation for e in determining_equations] ideal_state = [] ideal_next_state = equations(self.next_state_equations) ideal_intermediate = equations(self.intermediate_equations) if self.initialize != "noinit": if self.initialize == "zero": initializer = zero_fun else: initializer = random_bit for v in variables: if str(v)[:1] == "s": ideal_state.append(v + initializer()) return [ my_sort(self.apply_map(i)) for i in (ideal_state, ideal_intermediate, ideal_next_state) ]
def __init__(self, ideal, determination_modifier=1): if len(ideal) == 0: raise ValueError, 'ideal generators list should be non empty' self.ideal = ideal self.determination_modifier = determination_modifier self.used_variables_ideal = used_vars_set(ideal) self.number_of_used_variables_in_ideal = len(self.used_variables_ideal) self.used_variables_of_polynomial = dict([ (p, set(p.vars_as_monomial().variables())) for p in ideal ]) self.variables_introduction_mapping = dict() self.cluster = set() self.used_variables_cluster = set() self.build_variables_usage() self.initialize_variables_introduction_mapping()
def __init__(self, ideal, determination_modifier=1): if len(ideal) == 0: raise ValueError, 'ideal generators list should be non empty' self.ideal = ideal self.determination_modifier = determination_modifier self.used_variables_ideal = used_vars_set(ideal) self.number_of_used_variables_in_ideal = len(self.used_variables_ideal) self.used_variables_of_polynomial = dict( [(p, set(p.vars_as_monomial().variables())) for p in ideal]) self.variables_introduction_mapping = dict() self.cluster = set() self.used_variables_cluster = set() self.build_variables_usage() self.initialize_variables_introduction_mapping()
def branch(strat,trace): print "branching" index=strat.suggestPluginVariable(); if index<0: uv=set(used_vars_set(strat)) lv=set([iter(p.lead()).next().index() for p in strat if p.lead_deg()==1]) candidates=uv.difference(lv) if len(candidates)>0: index=iter(candidates).next().index() if index>=0: print "chosen index:", index step(strat, trace, Polynomial(Monomial(Variable(index))),0) step(strat, trace, Polynomial(Monomial(Variable(index))),1) else: print "FINAL!!!", index strat=symmGB_F2_python(strat, prot=True) if not strat.containsOne(): print "TRACE", trace print "SOLUTION" for p in strat.minimalize_and_tail_reduce(): print p raise Exception
def branch(strat, trace): print "branching" index = strat.suggestPluginVariable() if index < 0: uv = set(used_vars_set(strat)) lv = set([iter(p.lead()).next().index() for p in strat if p. lead_deg() == 1]) candidates = uv.difference(lv) if len(candidates) > 0: index = iter(candidates).next().index() if index >= 0: print "chosen index:", index step(strat, trace, Polynomial(Monomial(Variable(index))), 0) step(strat, trace, Polynomial(Monomial(Variable(index))), 1) else: print "FINAL!!!", index strat = symmGB_F2_python(strat, prot=True) if not strat.containsOne(): print "TRACE", trace print "SOLUTION" for p in strat.minimalize_and_tail_reduce(): print p raise Exception
def eliminate_ll_ranked(ll_system, to_reduce, reduction_function=ll_red_nf_noredsb, reduce_ll_system=False, prot=False): assert (ll_system) from_ring = ll_system[0].ring() ll_ranks = rank(ll_system) add_vars = set(used_vars_set(to_reduce).variables()).difference( ll_ranks.keys()) for v in add_vars: ll_ranks[v] = -1 #pushing variables ignored by ll to the front means, #that the routines will quickly eliminate them #and they won't give any overhead def sort_key(v): return (ll_ranks[v], v.index()) sorted_vars = sorted(ll_ranks.keys(), key=sort_key) def var_index(v): return iter(Monomial(v).variables()).next().index() #sorted_var_indices=[var_index(v) for v in sorted_vars] to_ring = Ring(len(sorted_vars)) map_back_indices = dict([(i, var_index(v)) for (i, v) in enumerate(sorted_vars)]) map_from_indices = dict([(var_index(v), i) for (i, v) in enumerate(sorted_vars)]) #dict([(v,k) for (k,v) in enumerate(sorted_var_indices)]) var_names = [str(v) for v in sorted_vars] try: for (i, v) in enumerate(sorted_vars): assert var_names[i] == str(v), (var_names[i], v, var_index(v), i) # _set_variable_name(to_ring, i, var_names[i] + "TO") finally: pass try: map_from_vec = construct_map_by_indices(to_ring, map_from_indices) finally: pass map_back_vec = construct_map_by_indices(from_ring, map_back_indices) def map_from(p): res = substitute_variables(to_ring, map_from_vec, p) # assert str(p)==str(res), (str(p), str(res), list(map_from_vec), # list(map_back_vec)) return res def map_back(p): return substitute_variables(from_ring, map_back_vec, p) try: ll_opt_encoded = ll_encode([map_from(p) for p in ll_system], prot=False, reduce=reduce_ll_system) def llnf(p): return map_back(reduction_function(map_from(p), ll_opt_encoded)) opt_eliminated = [llnf(p) for p in to_reduce] finally: pass return (llnf, opt_eliminated)
], kwd_args) manager = VariableManager(ring=ring, include_outputs=options.include_outputs, initialize=options.initialize, **kwd_args) from sys import argv f = args[0] parse(f, manager) (ideal_state, ideal_intermediate, ideal_next_state) = manager.ideals() ideal = ideal_state + ideal_intermediate + ideal_next_state variables = [] used_vars = set(used_vars_set(ideal).variables()) if not options.forward: variables = list( chain(reversed(manager.next), reversed(manager.output), reversed(manager.intermediate), reversed(manager.input), reversed(manager.state))) else: variables = list( chain(reversed(manager.output), reversed(manager.intermediate), reversed(manager.input), reversed(manager.state), reversed(manager.next))) variables = ["t"] + variables beginnings = [str(v)[:1] for v in variables] block_starts = [] last = beginnings[0]
def evaluates_to_variables(self, signal): ands = self.ands[signal] return list( used_vars_set(ands).variables())
def evaluates_to_variables(self, signal): ands = self.ands[signal] return list(used_vars_set(ands).variables())
def add_polynomial_to_cluster(self, p): self.cluster.add(p) self.used_variables_cluster = set(used_vars_set(self.cluster).variables()) self.number_of_used_variables_in_cluster = len(self.used_variables_cluster) self.adjust_variables_introduction_mapping(self.used_variables_of_polynomial[p])
Block("xinter", inter_max, reverse=True), Block("xinput", input_max, reverse=True), Block("xstate", state_max, reverse=True)], kwd_args) manager = VariableManager(ring=ring, include_outputs=options. include_outputs, initialize=options.initialize, **kwd_args) from sys import argv f = args[0] parse(f, manager) (ideal_state, ideal_intermediate, ideal_next_state) = manager.ideals() ideal = ideal_state + ideal_intermediate + ideal_next_state variables = [] used_vars = set(used_vars_set(ideal).variables()) if not options.forward: variables = list(chain(reversed(manager.next), reversed(manager.output ), reversed(manager.intermediate), reversed(manager.input), reversed(manager.state))) else: variables = list( chain(reversed(manager.output), reversed(manager.intermediate), reversed(manager.input), reversed(manager.state), reversed(manager.next))) variables = ["t"] + variables beginnings = [str(v)[:1] for v in variables] block_starts = [] last = beginnings[0]