Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
22144 views
U

�Ul_},�@s`dZddlmZddlmZddlmZddlmZddl	m
Z
ddlmZ
Gdd	�d	e
�ZdS)
a�
Bent Boolean functions
======================

The ``bent_function`` module defines
the ``BentFunction`` class,
which represents a bent Boolean function and some of its properties.

AUTHORS:

- Paul Leopardi (2016-09-25): initial version

EXAMPLES:

::

    sage: from sage.crypto.boolean_function import BooleanFunction
    sage: bf = BooleanFunction([0,1,0,0])
    sage: bf.algebraic_normal_form()
    x0*x1 + x0
    sage: from boolean_cayley_graphs.bent_function import BentFunction
    sage: bentf = BentFunction(bf)
    sage: type(bentf)
    <class 'boolean_cayley_graphs.bent_function.BentFunction'>
    sage: bentf.algebraic_normal_form()
    x0*x1 + x0

REFERENCES:

.. Dillon [Dil1974]_, Rothaus [Rot1976]_, Tokareva [Tok2015]_.

�)�Graph)�%strongly_regular_from_two_weight_code��require_version)�matrix)�BooleanFunctionImprovedNc@s:eZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)�BentFunctiona
    A bent Boolean function, with methods corresponding to some of its properties.

    The class inherits from BooleanFunctionImproved and is initialized
    in the same way as BooleanFunction.
    Since BooleanFunctionImproved inherits from Saveable, so does BentFunction.

    EXAMPLES:

    ::

        sage: import os
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: bentf = BentFunction([0,0,0,1])
        sage: bentf.algebraic_normal_form()
        x0*x1
        sage: d = tmp_dir()
        sage: bentf.save_mangled('example', dir=d)
        sage: ex = BentFunction.load_mangled('example', dir=d)
        sage: type(ex)
        <class 'boolean_cayley_graphs.bent_function.BentFunction'>
        sage: ex is bentf
        False
        sage: ex == bentf
        True
        sage: BentFunction.remove_mangled('example', dir=d)
        sage: os.rmdir(d)

    TESTS:

    ::

        sage: from sage.crypto.boolean_function import BooleanFunction
        sage: bf = BentFunction([0,1,0,0])
        sage: print(bf)
        Boolean function with 2 variables

        sage: from sage.crypto.boolean_function import BooleanFunction
        sage: bf = BentFunction([0,1,0,0])
        sage: latex(bf)
        \text{\texttt{Boolean{ }function{ }with{ }2{ }variables}}
    Fc
sV|��}d|d�|��}|�d�}�fdd�|D��t��}|dkrX|rTdgfSdSt|�}t|�D]J}t|d|�D]6}�|�|@dhkr�dnd|||f<|||f<qzqht|�}	|	��}
t|
��dkr�|r�fdd�|
D�}d|fSdSnZ|�rNg}t|�D]:}t|d|�D]$}|�||f�|�|@f��q�q
d|fSdSd	S)
aw
        Determine if a bent function is in the partial spread (-) class.

        Partial spread (-) is Dillon's :math:`\mathcal{PS}^{(-)}` class [Dil1974]_.

        INPUT:

        - ``self`` -- the current object.
        - ``certify`` -- boolean (default: False):

        OUTPUT:

        If certify is False, then return True if the bent function
        represented by ``self`` is in :math:`\mathcal{PS}^{(-)}`,
        otherwise return False.
        If certify is True then return two values,
        where the first is True or False as above,
        and if the first value is True, the second value is
        a list of intersections between maximal cliques,
        otherwie the second value is an empty list.

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.bent_function import BentFunction
            sage: bentf = BentFunction([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0])
            sage: bentf.is_bent()
            True
            sage: bentf.is_partial_spread_minus()
            True
            sage: bentf.is_partial_spread_minus(certify=True)
            (True, [{7, 11, 12}, {3, 13, 14}])
        �rcs g|]}t|��krt|��qS�)�len�set)�.0�clique)�reqd_clique_sizer
�G/home/user/Boolean-Cayley-graphs/boolean_cayley_graphs/bent_function.py�
<listcomp>�s�z8BentFunction.is_partial_spread_minus.<locals>.<listcomp>F�csg|]}�|dh�qS�rr
)r
�j)�reqd_cliquesr
rr�s�TN)	�
nvariables�cayley_graph�cliques_containing_vertexrr�ranger�clique_maximum�append)
�selfZcertify�dim�cayleyZ	cliques_0Znbr_cliquesZ
clique_matrixr�kZclique_graphZ
clique_max�part�
intersectionsr
)rrr�is_partial_spread_minusasJ#

���
��z$BentFunction.is_partial_spread_minuscCs|��}t|�S)aY
        Return the graph of the linear code corresponding to the bent function.

        INPUT:

        - ``self`` -- the current object.

        OUTPUT:

        The graph of the linear code corresponding to ``self``.
        This is a strongly regular graph [Car2010]_, [Del1972]_, [Din2015].

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.bent_function import BentFunction
            sage: bentf = BentFunction([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0])
            sage: lcg = bentf.linear_code_graph()
            sage: type(lcg)
            <class 'sage.graphs.graph.Graph'>
            sage: lcg.is_strongly_regular(parameters=True)
            (16, 6, 2, 2)

        REFERENCES:

        .. Carlet [Car2010]_ Section 8.6 Proposition 8.29.

        .. Delsarte [Del1972]_.

        .. Ding [Din2015]_ Corollary 10.

        )Zlinear_coder)r�Lr
r
r�linear_code_graph�s"zBentFunction.linear_code_graphcsf���}d|}t||�}���}|���t|�D].�t���fdd�t|�D��|�dd�f<q2|S)a�
        Return the incidence matrix of the SDP design of the bent function.

        This method returns the incidence matrix of the design of type
        :math:`R(\mathtt{self})`, as described by Dillon and Schatz [DS1987]_.
        This is a design with the symmetric difference property [Kan1975]_.

        INPUT:

        - ``self`` -- the current object.

        OUTPUT:

        The incidence matrix of the SDP design corresponding to ``self``.

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.bent_function import BentFunction
            sage: bentf = BentFunction([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0])
            sage: sdp = bentf.sdp_design_matrix()
            sage: print(sdp)
            [0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 0]
            [0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 1]
            [0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 1]
            [1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1]
            [0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 1]
            [0 1 0 0 1 0 1 1 0 1 0 0 0 1 0 0]
            [0 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0]
            [1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0]
            [0 0 0 1 0 0 0 1 1 1 1 0 0 0 0 1]
            [0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0]
            [0 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0]
            [1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0]
            [1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 1]
            [1 0 1 1 0 1 0 0 0 1 0 0 0 1 0 0]
            [1 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0]
            [0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0]
            sage: from sage.combinat.designs.incidence_structures import IncidenceStructure
            sage: sdp_design = IncidenceStructure(sdp)
            sage: sdp_design.is_t_design(return_parameters=True)
            (True, (2, 16, 6, 2))

        REFERENCES:

        .. Dillon and Schatz [DS1987]_, Kantor [Kan1975]_.

        r	cs"g|]}��d�����|��qSr)�extended_translate�r
�x��cZdual_frr
rrs�z2BentFunction.sdp_design_matrix.<locals>.<listcomp>N)rr�walsh_hadamard_dualr%r)rr�v�resultZ	dual_selfr
r(r�sdp_design_matrix�s2
�zBentFunction.sdp_design_matrixcs:|��}d|d��fdd��t�fdd�|��D��S)a
        Return the Walsh Hadamard dual of the bent function.

        This method returns a ``BentFunction`` based on the Walsh Hadamard
        transform of ``self``. Since ``self`` is a bent function, the returned
        ``BentFunction` is well-defined and is bent, being the *dual*
        bent function [Hou1999]_ or *Fourier transform* of ``self`` [Rot1976]_.

        INPUT:

        - ``self`` -- the current object.

        OUTPUT:

        An object of class ``BentFunction``, being the dual of ``self``.

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.bent_function import BentFunction
            sage: bentf = BentFunction([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0])
            sage: dual_bentf = bentf.walsh_hadamard_dual()
            sage: type(dual_bentf)
            <class 'boolean_cayley_graphs.bent_function.BentFunction'>
            sage: dual_bentf.is_bent()
            True
            sage: dual_bentf.algebraic_normal_form()
            x0*x1 + x2*x3

        .. NOTE::

            Versions of Sage before 8.2 had an incorrect sign in
            ``BooleanFunction.walsh_hadamard_transform(self)``.
            See [Sage trac ticket #23931](https://trac.sagemath.org/ticket/23931)
            Previous versions of this method had ``1 + x // scale`` to compensate for
            an incorrect sign in ``BooleanFunction.walsh_hadamard_transform(self)``.
            [Since this has now been fixed in Sage 8.2](https://trac.sagemath.org/ticket/23931)
            this is now changed to ``1 - x // scale``.
        r	cs,tddd�rd|�dSd|�dS)N�r	rrr)r')�scaler
r�<lambda>>s
�z2BentFunction.walsh_hadamard_dual.<locals>.<lambda>csg|]}�|��qSr
r
r&)�coefficientr
rrCsz4BentFunction.walsh_hadamard_dual.<locals>.<listcomp>)rr�walsh_hadamard_transform)rrr
)r1r/rr*s)z BentFunction.walsh_hadamard_dualcCst|�}|��}t�||�S)a�
        Return the weight class of the bent function.

        INPUT:

        - ``self`` -- the current object.

        OUTPUT:

        The value 0 or 1, being the weight class of ``self``.

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.bent_function import BentFunction
            sage: bentf = BentFunction([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0])
            sage: bentf.weight_class()
            0
        )r�weight�wc�weight_class)r�lengthr3r
r
rr5FszBentFunction.weight_classN)F)	�__name__�
__module__�__qualname__�__doc__r"r$r-r*r5r
r
r
rr4s,
O&=3r)r:�sage.graphs.graphrZsage.graphs.strongly_regular_dbrZsage.misc.bannerr�sage.matrix.constructorrZ/boolean_cayley_graphs.boolean_function_improvedrZ"boolean_cayley_graphs.weight_classr5r4rr
r
r
r�<module>s)