| 777 | - d - an integer; |
| 778 | - dim - a Boolean (default: False), if True, returns also the dimension of the annihilator vector space. |
| 779 | |
| 780 | EXAMPLES:: |
| 781 | |
| 782 | sage: from sage.crypto.boolean_function import BooleanFunction |
| 783 | sage: f = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") |
| 784 | sage: f.annihilator(1) is None |
| 785 | True |
| 786 | sage: g = BooleanFunction( f.annihilator(3) ) |
| 787 | sage: set([ fi*g(i) for i,fi in enumerate(f) ]) |
| 788 | set([0]) |
| 789 | """ |
| 790 | # NOTE: this is a toy implementation |
| 791 | from sage.rings.polynomial.pbori import BooleanPolynomialRing |
| 792 | R = BooleanPolynomialRing(self._nvariables,'x') |
| 793 | G = R.gens() |
| 794 | r = [R(1)] |
| 795 | |
| 796 | from sage.modules.all import vector |
| 797 | s = vector(self.truth_table()).support() |
| 798 | |
| 799 | from sage.combinat.combination import Combinations |
| 800 | from sage.misc.misc import prod |
| 801 | |
| 802 | from sage.matrix.constructor import Matrix |
| 803 | from sage.rings.arith import binomial |
| 804 | M = Matrix(GF(2),sum([binomial(self._nvariables,i) for i in xrange(d+1)]),len(s)) |
| 805 | |
| 806 | for i in xrange(1,d+1): |
| 807 | C = Combinations(self._nvariables,i) |
| 808 | for c in C: |
| 809 | r.append(prod([G[i] for i in c])) |
| 810 | |
| 811 | cdef BooleanFunction t |
| 812 | |
| 813 | for i,m in enumerate(r): |
| 814 | t = BooleanFunction(m) |
| 815 | for j,v in enumerate(s): |
| 816 | M[i,j] = bitset_in(t._truth_table,v) |
| 817 | |
| 818 | kg = M.kernel().gens() |
| 819 | |
| 820 | if len(kg)>0: |
| 821 | res = sum([kg[0][i]*ri for i,ri in enumerate(r)]) |
| 822 | else: |
| 823 | res = None |
| 824 | |
| 825 | if dim: |
| 826 | return res,len(kg) |
| 827 | else: |
| 828 | return res |
| 829 | |
| 830 | def algebraic_immunity(self, annihilator = False): |
| 831 | """ |
| 832 | Returns the algebraic immunity of the Boolean function. This is the smallest |
| 833 | integer `i` such that there exists a non trivial annihilator. |
| 834 | |
| 835 | INPUT: |
| 836 | |
| 837 | - annihilator - a Boolean (default: False), if True, returns also an annihilator of minimal degree. |
| 838 | |
| 839 | EXAMPLES:: |
| 840 | |
| 841 | sage: from sage.crypto.boolean_function import BooleanFunction |
| 842 | sage: R.<x0,x1,x2,x3,x4,x5> = BooleanPolynomialRing(6) |
| 843 | sage: B = BooleanFunction(x0*x1 + x1*x2 + x2*x3 + x3*x4 + x4*x5) |
| 844 | sage: B.algebraic_immunity(annihilator=True) |
| 845 | (2, x0*x1 + x1*x2 + x2*x3 + x3*x4 + x4*x5 + 1) |
| 846 | sage: B[0] +=1 |
| 847 | sage: B.algebraic_immunity() |
| 848 | 3 |
| 849 | |
| 850 | sage: R.<x> = GF(2^8,'a')[] |
| 851 | sage: B = BooleanFunction(x^31) |
| 852 | sage: B.algebraic_immunity() |
| 853 | 4 |
| 854 | """ |
| 855 | for i in xrange(self._nvariables): |
| 856 | A = self.annihilator(i) |
| 857 | if A is not None: |
| 858 | if annihilator: |
| 859 | return i,A |
| 860 | else: |
| 861 | return i |
| 862 | raise ValueError, "you just found a bug!" |
| 863 | |
| 996 | ########################################## |
| 997 | # Below we provide some constructions of # |
| 998 | # cryptographic Boolean function. # |
| 999 | ########################################## |
| 1000 | |
| 1001 | def random_boolean_function(n): |
| 1002 | """ |
| 1003 | Returns a random Boolean function with `n` variables. |
| 1004 | |
| 1005 | EXAMPLE:: |
| 1006 | |
| 1007 | sage: from sage.crypto.boolean_function import random_boolean_function |
| 1008 | sage: B = random_boolean_function(9) |
| 1009 | sage: B.nvariables() |
| 1010 | 9 |
| 1011 | sage: B.nonlinearity() |
| 1012 | 222 |
| 1013 | """ |
| 1014 | from sage.misc.randstate import current_randstate |
| 1015 | r = current_randstate().python_random() |
| 1016 | cdef BooleanFunction B = BooleanFunction(n) |
| 1017 | cdef bitset_t T |
| 1018 | T[0] = B._truth_table[0] |
| 1019 | for 0 <= i < T.limbs: |
| 1020 | T.bits[i] = r.randrange(0,Integer(1)<<(sizeof(unsigned long)*8)) |
| 1021 | return B |