Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- """ Boolean functions
Those functions are used for example in LFSR based ciphers like the filter generator or the combination generator.
This module allows to study properties linked to spectral analysis, and also algebraic immunity.
EXAMPLES::
sage: R.<x>=GF(2^8,'a')[] sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction( x^254 ) # the Boolean function Tr(x^254) sage: B Boolean function with 8 variables sage: B.nonlinearity() 112 sage: B.algebraic_immunity() 4
AUTHOR:
- Rusydi H. Makarim (2016-10-13): add functions related to linear structures - Rusydi H. Makarim (2016-07-09): add is_plateaued() - Yann Laigle-Chapuy (2010-02-26): add basic arithmetic - Yann Laigle-Chapuy (2009-08-28): first implementation
""" from __future__ import absolute_import
from libc.string cimport memcpy
from sage.structure.sage_object cimport SageObject from sage.structure.richcmp cimport rich_to_bool from sage.rings.integer_ring import ZZ from sage.rings.integer cimport Integer from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.polynomial.pbori import BooleanPolynomial from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro from sage.rings.polynomial.polynomial_element import is_Polynomial
include "sage/data_structures/bitset.pxi"
# for details about the implementation of hamming_weight_int, # walsh_hadamard transform, reed_muller transform, and a lot # more, see 'Matters computational' available on www.jjj.de.
cdef inline unsigned int hamming_weight_int(unsigned int x): # valid for 32bits
cdef walsh_hadamard(long *f, int ldn): r""" The Walsh Hadamard transform is an orthogonal transform equivalent to a multidimensional discrete Fourier transform of size 2x2x...x2. It can be defined by the following formula:
.. MATH:: W(j) = \sum_{i\in\{0,1\}^n} (-1)^{f(i)\oplus i \cdot j}
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([1,0,0,1]) sage: B.walsh_hadamard_transform() # indirect doctest (0, 0, 0, -4) """ cdef long n, ldm, m, mh, t1, t2, r
cdef long yellow_code(unsigned long a): """ The yellow-code is just a Reed Muller transform applied to a word.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x,y,z> = BooleanPolynomialRing(3) sage: P = x*y sage: B = BooleanFunction( P ) sage: B.truth_table() # indirect doctest (False, False, False, True, False, False, False, True) """
cdef reed_muller(mp_limb_t* f, int ldn): r""" The Reed Muller transform (also known as binary Möbius transform) is an orthogonal transform. For a function `f` defined by
.. MATH:: f(x) = \bigoplus_{I\subset\{1,\ldots,n\}} \left(a_I \prod_{i\in I} x_i\right)
it allows to compute efficiently the ANF from the truth table and vice versa, using the formulae:
.. MATH:: f(x) = \bigoplus_{support(x)\subset I} a_I .. MATH:: a_i = \bigoplus_{I\subset support(x)} f(x)
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x,y,z> = BooleanPolynomialRing(3) sage: P = x*y sage: B = BooleanFunction( P ) sage: B.truth_table() # indirect doctest (False, False, False, True, False, False, False, True) """ cdef long n, ldm, m, mh, t1, t2, r # intra word transform # inter word transform
cdef class BooleanFunction(SageObject): r""" This module implements Boolean functions represented as a truth table.
We can construct a Boolean Function from either:
- an integer - the result is the zero function with ``x`` variables; - a list - it is expected to be the truth table of the result. Therefore it must be of length a power of 2, and its elements are interpreted as Booleans; - a string - representing the truth table in hexadecimal; - a Boolean polynomial - the result is the corresponding Boolean function; - a polynomial P over an extension of GF(2) - the result is the Boolean function with truth table ``( Tr(P(x)) for x in GF(2^k) )``
EXAMPLES:
from the number of variables::
sage: from sage.crypto.boolean_function import BooleanFunction sage: BooleanFunction(5) Boolean function with 5 variables
from a truth table::
sage: BooleanFunction([1,0,0,1]) Boolean function with 2 variables
note that elements can be of different types::
sage: B = BooleanFunction([False, sqrt(2)]) sage: B Boolean function with 1 variable sage: [b for b in B] [False, True]
from a string::
sage: BooleanFunction("111e") Boolean function with 4 variables
from a :class:`sage.rings.polynomial.pbori.BooleanPolynomial`::
sage: R.<x,y,z> = BooleanPolynomialRing(3) sage: P = x*y sage: BooleanFunction( P ) Boolean function with 3 variables
from a polynomial over a binary field::
sage: R.<x> = GF(2^8,'a')[] sage: B = BooleanFunction( x^7 ) sage: B Boolean function with 8 variables
two failure cases::
sage: BooleanFunction(sqrt(2)) Traceback (most recent call last): ... TypeError: unable to init the Boolean function
sage: BooleanFunction([1, 0, 1]) Traceback (most recent call last): ... ValueError: the length of the truth table must be a power of 2 """
cdef bitset_t _truth_table cdef object _walsh_hadamard_transform cdef object _nvariables cdef object _nonlinearity cdef object _correlation_immunity cdef object _autocorrelation cdef object _absolut_indicator cdef object _sum_of_square_indicator
def __cinit__(self, x): r""" Construct a Boolean Function. The input ``x`` can be either:
- an integer - the result is the zero function with ``x`` variables; - a list - it is expected to be the truth table of the result. Therefore it must be of length a power of 2, and its elements are interpreted as Booleans; - a Boolean polynomial - the result is the corresponding Boolean function; - a polynomial P over an extension of GF(2) - the result is the Boolean function with truth table ``( Tr(P(x)) for x in GF(2^k) )``
EXAMPLES:
from the number of variables::
sage: from sage.crypto.boolean_function import BooleanFunction sage: BooleanFunction(5) Boolean function with 5 variables
from a truth table::
sage: BooleanFunction([1,0,0,1]) Boolean function with 2 variables
note that elements can be of different types::
sage: B = BooleanFunction([False, sqrt(2)]) sage: B Boolean function with 1 variable sage: [b for b in B] [False, True]
from a :class:`sage.rings.polynomial.pbori.BooleanPolynomial`::
sage: R.<x,y,z> = BooleanPolynomialRing(3) sage: P = x*y sage: BooleanFunction( P ) Boolean function with 3 variables
from a polynomial over a binary field::
sage: R.<x> = GF(2^8,'a')[] sage: B = BooleanFunction( x^7 ) sage: B Boolean function with 8 variables
two failure cases::
sage: BooleanFunction(sqrt(2)) Traceback (most recent call last): ... TypeError: unable to init the Boolean function
sage: BooleanFunction([1, 0, 1]) Traceback (most recent call last): ... ValueError: the length of the truth table must be a power of 2 """ else: raise ValueError("the length of the truth table must be a power of 2") # initialisation from a truth table
# first, check the length else:
# then, initialize our bitset
# initialisation from a Boolean polynomial
# initialisation to the zero function
else: for i,u in enumerate(K): bitset_set_to(self._truth_table, i , (x(u)).trace()) else:
def __dealloc__(self):
def _repr_(self): """ EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: BooleanFunction(4) #indirect doctest Boolean function with 4 variables """
def __invert__(self): """ Return the complement Boolean function of `self`.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) sage: (~B).truth_table(format='int') (1, 0, 0, 1, 0, 1, 1, 1) """
def __add__(self, BooleanFunction other): """ Return the element wise sum of `self`and `other` which must have the same number of variables.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) sage: (A+B).truth_table(format='int') (0, 0, 1, 1, 0, 0, 0, 1)
it also corresponds to the addition of algebraic normal forms::
sage: S = A.algebraic_normal_form() + B.algebraic_normal_form() sage: (A+B).algebraic_normal_form() == S True
TESTS::
sage: A+BooleanFunction([0,1]) Traceback (most recent call last): ... ValueError: the two Boolean functions must have the same number of variables """
def __mul__(self, BooleanFunction other): """ Return the elementwise multiplication of `self`and `other` which must have the same number of variables.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) sage: (A*B).truth_table(format='int') (0, 1, 0, 0, 1, 0, 0, 0)
it also corresponds to the multiplication of algebraic normal forms::
sage: P = A.algebraic_normal_form() * B.algebraic_normal_form() sage: (A*B).algebraic_normal_form() == P True
TESTS::
sage: A*BooleanFunction([0,1]) Traceback (most recent call last): ... ValueError: the two Boolean functions must have the same number of variables """
def __or__(BooleanFunction self, BooleanFunction other): """ Return the concatenation of `self` and `other` which must have the same number of variables.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: A=BooleanFunction([0, 1, 0, 1]) sage: B=BooleanFunction([0, 1, 1, 0]) sage: (A|B).truth_table(format='int') (0, 1, 0, 1, 0, 1, 1, 0)
sage: C = A.truth_table() + B.truth_table() sage: (A|B).truth_table(format='int') == C True
TESTS::
sage: A|BooleanFunction([0,1]) Traceback (most recent call last): ... ValueError: the two Boolean functions must have the same number of variables """
memcpy(res._truth_table.bits , self._truth_table.bits, nb_limbs * sizeof(unsigned long)) memcpy(&(res._truth_table.bits[nb_limbs]),other._truth_table.bits, nb_limbs * sizeof(unsigned long))
return res
def algebraic_normal_form(self): """ Return the :class:`sage.rings.polynomial.pbori.BooleanPolynomial` corresponding to the algebraic normal form.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,1,0,1,0,1,1]) sage: P = B.algebraic_normal_form() sage: P x0*x1*x2 + x0 + x1*x2 + x1 + x2 sage: [ P(*ZZ(i).digits(base=2,padto=3)) for i in range(8) ] [0, 1, 1, 0, 1, 0, 1, 1] """ cdef bitset_t anf
def nvariables(self): """ The number of variables of this function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: BooleanFunction(4).nvariables() 4 """
def truth_table(self,format='bin'): """ The truth table of the Boolean function.
INPUT: a string representing the desired format, can be either
- 'bin' (default) : we return a tuple of Boolean values - 'int' : we return a tuple of 0 or 1 values - 'hex' : we return a string representing the truth_table in hexadecimal
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x,y,z> = BooleanPolynomialRing(3) sage: B = BooleanFunction( x*y*z + z + y + 1 ) sage: B.truth_table() (True, True, False, False, False, False, True, False) sage: B.truth_table(format='int') (1, 1, 0, 0, 0, 0, 1, 0) sage: B.truth_table(format='hex') '43'
sage: BooleanFunction('00ab').truth_table(format='hex') '00ab'
sage: H = '0abbacadabbacad0' sage: len(H) 16 sage: T = BooleanFunction(H).truth_table(format='hex') sage: T == H True sage: H = H * 4 sage: T = BooleanFunction(H).truth_table(format='hex') sage: T == H True sage: H = H * 4 sage: T = BooleanFunction(H).truth_table(format='hex') sage: T == H True sage: len(T) 256 sage: B.truth_table(format='oct') Traceback (most recent call last): ... ValueError: unknown output format """
def __len__(self): """ Return the number of different input values.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: len(BooleanFunction(4)) 16 """
def __richcmp__(BooleanFunction self, other, int op): """ Boolean functions are considered to be equal if the number of input variables is the same, and all the values are equal.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: b1 = BooleanFunction([0,1,1,0]) sage: b2 = BooleanFunction([0,1,1,0]) sage: b3 = BooleanFunction([0,1,1,1]) sage: b4 = BooleanFunction([0,1]) sage: b1 == b2 True sage: b1 == b3 False sage: b1 == b4 False """ return NotImplemented
def __call__(self, x): """ Return the value of the function for the given input.
INPUT: either
- a list - then all elements are evaluated as Booleans - an integer - then we consider its binary representation
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,0,0]) sage: B(1) 1 sage: B([1,0]) 1 sage: B(4) Traceback (most recent call last): ... IndexError: index out of bound
""" raise ValueError("bad number of inputs") else: raise TypeError("cannot apply Boolean function to provided element")
def __iter__(self): """ Iterate through the value of the function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,1,0,1,0,1,0]) sage: [int(b) for b in B] [0, 1, 1, 0, 1, 0, 1, 0]
"""
def _walsh_hadamard_transform_cached(self): """ Return the cached Walsh Hadamard transform. *Unsafe*, no check.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(3) sage: W = B.walsh_hadamard_transform() sage: B._walsh_hadamard_transform_cached() is W True """
def walsh_hadamard_transform(self): r""" Compute the Walsh Hadamard transform `W` of the function `f`.
.. MATH:: W(j) = \sum_{i\in\{0,1\}^n} (-1)^{f(i)\oplus i \cdot j}
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x> = GF(2^3,'a')[] sage: B = BooleanFunction( x^3 ) sage: B.walsh_hadamard_transform() (0, -4, 0, 4, 0, 4, 0, 4) """ cdef long *temp
def absolute_walsh_spectrum(self): """ Return the absolute Walsh spectrum fo the function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: sorted(B.absolute_walsh_spectrum().items()) [(0, 64), (16, 64)]
sage: B = BooleanFunction("0113077C165E76A8") sage: B.absolute_walsh_spectrum() {8: 64} """ else:
def is_balanced(self): """ Return True if the function takes the value True half of the time.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(1) sage: B.is_balanced() False sage: B[0] = True sage: B.is_balanced() True """
def is_symmetric(self): """ Return True if the function is symmetric, i.e. invariant under permutation of its input bits. Another way to see it is that the output depends only on the Hamming weight of the input.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(5) sage: B[3] = 1 sage: B.is_symmetric() False sage: V_B = [0, 1, 1, 0, 1, 0] sage: for i in srange(32): B[i] = V_B[i.popcount()] sage: B.is_symmetric() True """
def nonlinearity(self): """ Return the nonlinearity of the function. This is the distance to the linear functions, or the number of output ones need to change to obtain a linear function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(5) sage: B[1] = B[3] = 1 sage: B.nonlinearity() 2 sage: B = BooleanFunction("0113077C165E76A8") sage: B.nonlinearity() 28 """
def is_bent(self): """ Return True if the function is bent.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("0113077C165E76A8") sage: B.is_bent() True """ return False
def correlation_immunity(self): """ Return the maximum value `m` such that the function is correlation immune of order `m`.
A Boolean function is said to be correlation immune of order `m` , if the output of the function is statistically independent of the combination of any m of its inputs.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: B.correlation_immunity() 2 """ cdef int c
def resiliency_order(self): """ Return the maximum value `m` such that the function is resilient of order `m`.
A Boolean function is said to be resilient of order `m` if it is balanced and correlation immune of order `m`.
If the function is not balanced, we return -1.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("077CE5A2F8831A5DF8831A5D077CE5A26996699669699696669999665AA5A55A") sage: B.resiliency_order() 3 """ return -1
def autocorrelation(self): r""" Return the autocorrelation of the function, defined by
.. MATH:: \Delta_f(j) = \sum_{i\in\{0,1\}^n} (-1)^{f(i)\oplus f(i\oplus j)}.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("03") sage: B.autocorrelation() (8, 8, 0, 0, 0, 0, 0, 0) """ cdef long *temp
def absolute_autocorrelation(self): """ Return the absolute autocorrelation of the function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: sorted(B.absolute_autocorrelation().items()) [(0, 33), (8, 58), (16, 28), (24, 6), (32, 2), (128, 1)] """ else:
def absolut_indicator(self): """ Return the absolut indicator of the function. Ths is the maximal absolut value of the autocorrelation.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: B.absolut_indicator() 32 """
def sum_of_square_indicator(self): """ Return the sum of square indicator of the function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: B.sum_of_square_indicator() 32768 """
def annihilator(self,d, dim = False): r""" Return (if it exists) an annihilator of the boolean function of degree at most `d`, that is a Boolean polynomial `g` such that
.. MATH::
f(x)g(x) = 0 \forall x.
INPUT:
- ``d`` -- an integer; - ``dim`` -- a Boolean (default: False), if True, return also the dimension of the annihilator vector space.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: f = BooleanFunction("7969817CC5893BA6AC326E47619F5AD0") sage: f.annihilator(1) is None True sage: g = BooleanFunction( f.annihilator(3) ) sage: set([ fi*g(i) for i,fi in enumerate(f) ]) {0} """ # NOTE: this is a toy implementation
cdef BooleanFunction t
else:
return res,len(kg) else:
def algebraic_immunity(self, annihilator = False): """ Returns the algebraic immunity of the Boolean function. This is the smallest integer `i` such that there exists a non trivial annihilator for `self` or `~self`.
INPUT:
- annihilator -- a Boolean (default: False), if True, returns also an annihilator of minimal degree.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x0,x1,x2,x3,x4,x5> = BooleanPolynomialRing(6) sage: B = BooleanFunction(x0*x1 + x1*x2 + x2*x3 + x3*x4 + x4*x5) sage: B.algebraic_immunity(annihilator=True) (2, x0*x1 + x1*x2 + x2*x3 + x3*x4 + x4*x5 + 1) sage: B[0] +=1 sage: B.algebraic_immunity() 2
sage: R.<x> = GF(2^8,'a')[] sage: B = BooleanFunction(x^31) sage: B.algebraic_immunity() 4 """ else: raise ValueError("you just found a bug!")
def is_plateaued(self): r""" Return ``True`` if this function is plateaued, i.e. its Walsh transform takes at most three values `0` and `\pm \lambda`, where `\lambda` is some positive integer.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: R.<x0, x1, x2, x3> = BooleanPolynomialRing() sage: f = BooleanFunction(x0*x1 + x2 + x3) sage: f.walsh_hadamard_transform() (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, -8) sage: f.is_plateaued() True """
def is_linear_structure(self, val): """ Return ``True`` if ``val`` is a linear structure of this Boolean function.
INPUT:
- ``val`` -- either an integer or a tuple/list of `\GF{2}` elements of length equal to the number of variables
.. SEEALSO::
:meth:`has_linear_structure`, :meth:`linear_structures`.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: f = BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0]) sage: f.is_linear_structure(1) True sage: l = [1, 0, 0, 1] sage: f.is_linear_structure(l) True sage: v = vector(GF(2), l) sage: f.is_linear_structure(v) True sage: f.is_linear_structure(7) False sage: f.is_linear_structure(20) #parameter is out of range Traceback (most recent call last): ... IndexError: index out of range sage: v = vector(GF(3), [1, 0, 1, 1]) sage: f.is_linear_structure(v) Traceback (most recent call last): ... TypeError: base ring of input vector must be GF(2) sage: v = vector(GF(2), [1, 0, 1, 1, 1]) sage: f.is_linear_structure(v) Traceback (most recent call last): ... TypeError: input vector must be an element of a vector space with dimension 4 sage: f.is_linear_structure('X') #failure case Traceback (most recent call last): ... TypeError: cannot compute is_linear_structure() using parameter X """
else:
def has_linear_structure(self): """ Return ``True`` if this function has a linear structure.
An `n`-variable Boolean function `f` has a linear structure if there exists a nonzero `a \in \GF{2}^n` such that `f(x \oplus a) \oplus f(x)` is a constant function.
.. SEEALSO::
:meth:`is_linear_structure`, :meth:`linear_structures`.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: f = BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0]) sage: f.has_linear_structure() True sage: f.autocorrelation() (16, -16, 0, 0, 0, 0, 0, 0, -16, 16, 0, 0, 0, 0, 0, 0) sage: g = BooleanFunction([0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1]) sage: g.has_linear_structure() False sage: g.autocorrelation() (16, 4, 4, 4, 4, -4, -4, -4, -4, 4, -4, -4, -4, 4, -4, -4) """
def linear_structures(self): """ Return all linear structures of this Boolean function as a vector subspace of `\GF{2}^n`.
.. SEEALSO::
:meth:`is_linear_structure`, :meth:`has_linear_structure`.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: f = BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0]) sage: LS = f.linear_structures() sage: LS.dimension() 2 sage: LS.basis_matrix() [1 0 0 0] [0 0 0 1] sage: LS.list() [(0, 0, 0, 0), (1, 0, 0, 0), (0, 0, 0, 1), (1, 0, 0, 1)] """
def __setitem__(self, i, y): """ Set a value of the function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B=BooleanFunction([0,0,1,1]) sage: B[0]=1 sage: B[2]=(3**17 == 9) sage: [b for b in B] [True, False, False, True]
We take care to clear cached values::
sage: W = B.walsh_hadamard_transform() sage: B[2] = 1 sage: B._walsh_hadamard_transform_cached() is None True """
def __getitem__(self, i): """ Return the value of the function for the given input.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B=BooleanFunction([0,1,1,1]) sage: [ int(B[i]) for i in range(len(B)) ] [0, 1, 1, 1] """
def _clear_cache(self): """ Clear cached values.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,1,0]) sage: W = B.walsh_hadamard_transform() sage: B._walsh_hadamard_transform_cached() is None False sage: B._clear_cache() sage: B._walsh_hadamard_transform_cached() is None True """
def __reduce__(self): """ EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,1,0]) sage: loads(dumps(B)) == B True """
def unpickle_BooleanFunction(bool_list): """ Specific function to unpickle Boolean functions.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction([0,1,1,0]) sage: loads(dumps(B)) == B # indirect doctest True """
cdef class BooleanFunctionIterator: cdef long index, last cdef BooleanFunction f
def __init__(self, f): """ Iterator through the values of a Boolean function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(3) sage: type(B.__iter__()) <type 'sage.crypto.boolean_function.BooleanFunctionIterator'> """
def __iter__(self): """ Iterator through the values of a Boolean function.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(1) sage: [b for b in B] # indirect doctest [False, False] """ return self
def __next__(self): """ Next value.
EXAMPLES::
sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction(1) sage: I = B.__iter__() sage: next(I) False """
########################################## # Below we provide some constructions of # # cryptographic Boolean function. # ##########################################
def random_boolean_function(n): """ Returns a random Boolean function with `n` variables.
EXAMPLES::
sage: from sage.crypto.boolean_function import random_boolean_function sage: B = random_boolean_function(9) sage: B.nvariables() 9 sage: B.nonlinearity() 217 # 32-bit 222 # 64-bit """ cdef bitset_t T |