Ticket #6139: sbox_call_and_rest.patch

File sbox_call_and_rest.patch, 20.7 KB (added by malb, 10 years ago)
  • doc/en/reference/cryptography.rst

    # HG changeset patch
    # User Martin Albrecht <malb@informatik.uni-bremen.de>
    # Date 1243428493 -3600
    # Node ID cecc283f3ecd027b767257222cf3c995997c20a9
    # Parent  16d22ab7b4abea2a1cae69fea26f9da684ad610c
    fixed calling an Sbox with m != n and ReST-ified SBox docs
    
    diff -r 16d22ab7b4ab -r cecc283f3ecd doc/en/reference/cryptography.rst
    a b  
    1717   sage/crypto/lfsr
    1818
    1919   sage/crypto/mq/sr
    20    sage/crypto/mq/mpolynomialsystem
    21  No newline at end of file
     20   sage/crypto/mq/mpolynomialsystem
     21   sage/crypto/mq/sbox
     22 No newline at end of file
  • sage/crypto/mq/sbox.py

    diff -r 16d22ab7b4ab -r cecc283f3ecd sage/crypto/mq/sbox.py
    a b  
    11r"""
    2 S-Boxes
    3 
    4 A substitution box or S-box is one of the basic components of
    5 symmetric key cryptography. In general, an S-box takes $m$ input bits
    6 and transforms them into some $n$ output bits. This is then called an
    7 $mxn$ S-box and is often implemented as a lookup table. These S-boxes
    8 are carefully chosen to resist linear and differential cryptanalysis.
    9 
    10 This module implements an S-box class which allows an algebraic
    11 treatment.
    12 
    13 EXAMPLE:
    14 
    15 We consider  the S-box of the block cipher PRESENT:
    16 
    17     sage: S = mq.SBox(12,5,6,11,9,0,10,13,3,14,15,8,4,7,1,2); S
    18     (12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2)
    19     sage: S(1)
    20     5
    21 
    22 Note that by default bits are interpreted in big endian order. This is
    23 not consistent with the rest of \SAGE, which has a strong bias towards
    24 little endian, but is consistent with most cryptographic literature.
    25 
    26     sage: S([0,0,0,1])
    27     [0, 1, 0, 1]
    28 
    29     sage: S = mq.SBox(12,5,6,11,9,0,10,13,3,14,15,8,4,7,1,2, big_endian=False)
    30     sage: S(1)
    31     5
    32     sage: S([0,0,0,1])
    33     [1, 1, 0, 0]
     2S-Boxes and Their Algebraic Representations.
    343"""
    354
    365from sage.combinat.integer_vector import IntegerVectors
     
    4615from sage.structure.sage_object import SageObject
    4716
    4817class SBox(SageObject):
     18    r"""
     19    A substitution box or S-box is one of the basic components of
     20    symmetric key cryptography. In general, an S-box takes ``m`` input
     21    bits and transforms them into ``n`` output bits. This is called an
     22    ``mxn`` S-box and is often implemented as a lookup table. These
     23    S-boxes are carefully chosen to resist linear and differential
     24    cryptanalysis [Heys02]_.
     25
     26    This module implements an S-box class which allows an algebraic
     27    treatment.
     28
     29    EXAMPLE:
     30
     31    We consider the S-box of the block cipher PRESENT [PRESENT07]_::
     32
     33        sage: S = mq.SBox(12,5,6,11,9,0,10,13,3,14,15,8,4,7,1,2); S
     34        (12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2)
     35        sage: S(1)
     36        5
     37
     38    Note that by default bits are interpreted in big endian
     39    order. This is not consistent with the rest of Sage, which has a
     40    strong bias towards little endian, but is consistent with most
     41    cryptographic literature.::
     42
     43        sage: S([0,0,0,1])
     44        [0, 1, 0, 1]
     45
     46        sage: S = mq.SBox(12,5,6,11,9,0,10,13,3,14,15,8,4,7,1,2, big_endian=False)
     47        sage: S(1)
     48        5
     49        sage: S([0,0,0,1])
     50        [1, 1, 0, 0]
     51
     52
     53    Now we construct an ``SBox`` object for the 4-bit small scale AES
     54    S-Box (cf. :mod:`sage.crypto.mq.sr`)::
     55
     56        sage: sr = mq.SR(1,1,1,4, allow_zero_inversions=True)
     57        sage: S = mq.SBox([sr.sub_byte(e) for e in list(sr.k)])
     58        sage: S
     59        (6, 5, 2, 9, 4, 7, 3, 12, 14, 15, 10, 0, 8, 1, 13, 11)
     60
     61    REFERENCES:
     62
     63    .. [Heys02] H. Heys *A Tutorial on Linear and Differential
     64      Cryptanalysis* ; 2002' available at
     65      http://www.engr.mun.ca/~howard/PAPERS/ldc_tutorial.pdf
     66
     67    .. [PRESENT07] A. Bogdanov, L. Knudsen, G. Leander, C. Paar,
     68      A. Poschmann, M. Robshaw, Y. Seurin, C. Vikkelsoe *PRESENT: An
     69      Ultra-Lightweight Block Cipher*; in Proceedings of CHES 2007;
     70      LNCS 7427; pp. 450-466; Springer Verlag 2007; available at
     71      http://www.crypto.rub.de/imperia/md/content/texte/publications/conferences/present_ches2007.pdf
     72    """
     73
    4974    def __init__(self, *args,  **kwargs):
    5075        """
    5176        Construct a substitution box (S-box) for a given lookup table
    52         $S$.
     77        `S`.
    5378
    5479        INPUT:
    55             S -- a finite iterable defining the S-box with integer or
    56                   finite field elements
    57             big_endian -- controls whether bits shall be ordered in
    58                           big endian order (default: True)
     80
     81        - ``S`` - a finite iterable defining the S-box with integer or
     82          finite field elements
     83
     84        - ``big_endian`` - controls whether bits shall be ordered in
     85          big endian order (default: ``True``)
    5986
    6087        EXAMPLE:
    6188       
    6289        We construct a 3-bit S-box where e.g. the bits (0,0,1) are
    63         mapped to (1,1,1).
     90        mapped to (1,1,1).::
    6491       
    6592            sage: S = mq.SBox(7,6,0,4,2,5,1,3); S
    6693            (7, 6, 0, 4, 2, 5, 1, 3)
    6794
    6895            sage: S(0)
    6996            7
    70 
    71         Now we construct an SBox object for the 4-bit small scale AES
    72         S-Box.
    73 
    74             sage: sr = mq.SR(1,1,1,4, allow_zero_inversions=True)
    75             sage: S = mq.SBox([sr.sub_byte(e) for e in list(sr.k)])
    76             sage: S
    77             (6, 5, 2, 9, 4, 7, 3, 12, 14, 15, 10, 0, 8, 1, 13, 11)
    78 
    7997        """
    8098        if "S" in kwargs:
    8199            S = kwargs["S"]
     
    106124
    107125    def _repr_(self):
    108126        """
    109         EXAMPLE:
     127        EXAMPLE::
     128
    110129            sage: mq.SBox(7,6,0,4,2,5,1,3) #indirect doctest
    111130            (7, 6, 0, 4, 2, 5, 1, 3)
    112131        """
     
    116135        """
    117136        Return the length of input bit strings.
    118137
    119         EXAMPLE:
     138        EXAMPLE::
     139
    120140            sage: len(mq.SBox(7,6,0,4,2,5,1,3))
    121141            3
    122142        """
     
    127147        S-boxes are considered to be equal if all construction
    128148        parameters match.
    129149
    130         EXAMPLE:
     150        EXAMPLE::
     151
    131152            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    132153            sage: loads(dumps(S)) == S
    133154            True
     
    135156        return cmp((self._S,self._big_endian), (other._S,self._big_endian))
    136157
    137158    def to_bits(self, x, n=None):
    138         r"""
    139         Return bitstring of length $n$ for integer $x$. The returned
    140         bitstring is guaranteed to have length \code{n}.
     159        """
     160        Return bitstring of length ``n`` for integer ``x``. The
     161        returned bitstring is guaranteed to have length ``n``.
    141162
    142163        INPUT:
    143             x -- an integer
    144             n -- bit length (optional)
    145164
    146         EXAMPLE:
     165        - ``x`` - an integer
     166
     167        - ``n`` - bit length (optional)
     168
     169        EXAMPLE::
     170
    147171            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    148172            sage: S.to_bits(6)
    149173            [1, 1, 0]
     
    164188        return swp(self._rpad( map(self._F,ZZ(x).digits(2)), n ))
    165189
    166190    def from_bits(self, x, n=None):
    167         r"""
    168         Return integer for bitstring $x$ of length $n$.
     191        """
     192        Return integer for bitstring ``x`` of length ``n``.
    169193
    170194        INPUT:
    171             x -- a bitstring
    172             n -- bit length (optional)
    173195
    174         EXAMPLE:
     196        - ``x`` - a bitstring
     197
     198        - ``n`` - bit length (optional)
     199
     200        EXAMPLE::
     201
    175202            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    176203            sage: S.from_bits( [1,1,0])
    177204            6
     
    192219        return ZZ( map(ZZ, self._rpad(swp(x), n)), 2)
    193220
    194221    def _rpad(self,x, n=None):
    195         r"""
    196         Right pads x such that \code{len(x)} is $n$.
     222        """
     223        Right pads ``x`` such that ``len(x) == n``.
    197224
    198         EXAMPLE:
     225        EXAMPLE::
     226
    199227            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    200228            sage: S._rpad([1,1])
    201229            [1, 1, 0]
     
    205233        return  x + [self._F(0)]*(n-len(x))
    206234
    207235    def __call__(self, X):
    208         r"""
    209         Apply substitution to X.
     236        """
     237        Apply substitution to ``X``.
    210238
    211         If X is a list, it is interpreted as a sequence of bits depending
    212         on the bit order of this S-box.
     239        If X is a list, it is interpreted as a sequence of bits
     240        depending on the bit order of this S-box.
    213241
    214         INPUT:
    215             X -- either an integer, a tuple of GF(2) elements of
    216                  length \code{len(self)} or a finite field element in
    217                  GF($2^n$). As a last resort this function tries to
    218                  convert X to an integer.
     242        INPUT::
    219243
    220         EXAMPLE:
     244        - ``X`` - either an integer, a tuple of `\GF{2}` elements of
     245          length ``len(self)`` or a finite field element in
     246          `\GF{2^n}`. As a last resort this function tries to convert
     247          ``X`` to an integer.
     248
     249        EXAMPLE::
     250
    221251            sage: S = mq.SBox([7,6,0,4,2,5,1,3])
    222252            sage: S(7)
    223253            3
     
    247277            Traceback (most recent call last):
    248278            ...
    249279            TypeError: Cannot apply SBox to 1/2.
     280
     281            sage: S = mq.SBox(3, 0, 1, 3, 1, 0, 2, 2)
     282            sage: S(0)
     283            3
     284            sage: S([0,0,0])
     285            [1, 1]
    250286        """
    251287        if isinstance(X, (int, long, Integer)):
    252288            return self._S[ZZ(X)]
     
    263299            else:
    264300                X = list(X)
    265301            X = ZZ(map(ZZ,X),2)
    266             out =  self.to_bits(self._S[X])
     302            out =  self.to_bits(self._S[X], self.n)
    267303            if self._big_endian:
    268304                out = list(reversed(out))
    269305            return K(vector(GF(2),out))
     
    271307            pass
    272308
    273309        try:
    274             if len(X) == self.n:
     310            if len(X) == self.m:
    275311                if self._big_endian:
    276312                    X = list(reversed(X))
    277313                X = ZZ(map(ZZ,X),2)
    278314                out =  self._S[X]
    279                 return self.to_bits(out)
     315                return self.to_bits(out,self.n)
    280316        except TypeError:
    281317            pass
    282318
     
    288324        if len(str(X)) > 50:
    289325            raise TypeError, "Cannot apply SBox to provided element."
    290326        else:
    291             raise TypeError, "Cannot apply SBox to %s."%X
     327            raise TypeError, "Cannot apply SBox to %s."%(X,)
    292328
    293329    def __getitem__(self, X):
    294         r"""
    295         See as \code{self.__call__}.
     330        """
     331        See  :meth:`SBox.__call__`.
    296332
    297         EXAMPLE:
     333        EXAMPLE::
     334
    298335            sage: S = mq.SBox([7,6,0,4,2,5,1,3])
    299336            sage: S[7]
    300337            3
     
    302339        return self(X)
    303340
    304341    def is_permutation(self):
    305         r"""
    306         Return \code{True} if this S-Box is a permutation.
     342        """
     343        Return ``True`` if this S-Box is a permutation.
    307344
    308         EXAMPLE:
     345        EXAMPLE::
     346
    309347             sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    310348             sage: S.is_permutation()
    311349             True
     
    320358
    321359    def __iter__(self):
    322360        """
    323         EXAMPLE:
     361        EXAMPLE::
     362
    324363            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    325364            sage: [e for e in S]
    326365            [7, 6, 0, 4, 2, 5, 1, 3]
     
    330369
    331370    def difference_distribution_matrix(self):
    332371        """
    333         Return difference distribution matrix $A$ for this S-box.
     372        Return difference distribution matrix ``A`` for this S-box.
    334373
    335         The rows of $A$ encode the differences $\Delta I$ of the input
    336         and the columns encode the difference $\Delta O$ for the
    337         output. The bits are ordered according to the endianess of
    338         this S-box. The value at $A[\Delta I,\Delta O]$ encoded how
    339         often $\Delta O$ is the actual output difference given $\Delta
    340         I$ as input difference.
     374        The rows of ``A`` encode the differences ``Delta I`` of the
     375        input and the columns encode the difference ``Delta O`` for
     376        the output. The bits are ordered according to the endianess of
     377        this S-box. The value at ``A[Delta I,Delta O]`` encoded how
     378        often ``Delta O`` is the actual output difference given
     379        ``Delta I`` as input difference.
    341380
    342         EXAMPLE:
     381        See [Heys02]_ for an introduction to differential
     382        cryptanalysis.
     383
     384        EXAMPLE::
     385
    343386           sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    344387           sage: S.difference_distribution_matrix()
    345388           [8 0 0 0 0 0 0 0]
     
    350393           [0 0 2 2 2 2 0 0]
    351394           [0 2 2 0 0 2 2 0]
    352395           [0 0 0 0 2 2 2 2]
    353        
    354         REFERENCES: Howard M. Heys, A Tutorial on Linear and
    355         Differential Cryptanalysis, Cryptologia, v.XXVI n.3,
    356         p.189-221, July 2002
    357396        """
    358397        m = self.m
    359398        n = self.n
     
    376415        highest probability in absolute terms, i.e. how often it
    377416        occurs in total.
    378417
    379         EXAMPLE:
     418        EXAMPLE::
     419
    380420            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    381421            sage: S.maximal_difference_probability_absolute()
    382422            2
    383423
    384         NOTE: This code is called internally.
     424        .. note::
     425       
     426          This code is mainly called internally.
    385427        """
    386428        A = self.difference_distribution_matrix().copy()
    387429        A[0,0] = 0
     
    393435        highest probability in the range between 0.0 and 1.0
    394436        indicating 0\% or 100\% respectively.
    395437
    396         EXAMPLE:
     438        EXAMPLE::
     439
    397440            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    398441            sage: S.maximal_difference_probability()
    399442            0.25
     
    402445
    403446    def linear_approximation_matrix(self):
    404447        """
    405         Return linear approximation matrix $A$ for this S-box.
     448        Return linear approximation matrix ``A`` for this S-box.
    406449
    407         Let $i_b$ be the $b$-th bit of $i$ and $o_b$ the $b$-th bit of
    408         $o$. Then $v = A[i,o]$ encodes the bias of the equation
    409         #\Sigma i_b * x_i == \Sigma o_b * y_i$ if $x_i$ and $y_i$
    410         represent the input and output variables of the S-box.
     450        Let ``i_b`` be the ``b``-th bit of ``i`` and ``o_b`` the
     451        ``b``-th bit of ``o``. Then ``v = A[i,o]`` encodes the bias of
     452        the equation ``sum( i_b * x_i ) = sum( o_b * y_i )`` if
     453        ``x_i`` and ``y_i`` represent the input and output variables
     454        of the S-box.
    411455
    412         EXAMPLE:
     456        See [Heys02]_ for an introduction to linear cryptanalysis.
     457
     458        EXAMPLE::
     459
    413460            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    414461            sage: S.linear_approximation_matrix()
    415462            [ 4  0  0  0  0  0  0  0]
     
    421468            [ 0 -2 -2  0  0 -2  2  0]
    422469            [ 0 -2  2  0 -2  0  0 -2]
    423470
    424             According to this matrix the first bit of the input is
    425             equal to the third bit of the output 6 out of 8 times.
     471        According to this matrix the first bit of the input is equal
     472        to the third bit of the output 6 out of 8 times.::
    426473
    427474            sage: for i in srange(8): print S.to_bits(i)[0] == S.to_bits(S(i))[2]
    428475            False
     
    433480            True
    434481            True
    435482            True
    436 
    437         REFERENCES: Howard M. Heys, A Tutorial on Linear and
    438         Differential Cryptanalysis, Cryptologia, v.XXVI n.3,
    439         p.189-221, July 2002
    440483        """
    441484        try:
    442485            return self._linear_approximation_matrix
     
    469512        return A
    470513
    471514    def maximal_linear_bias_absolute(self):
    472         r"""
     515        """
    473516        Return maximal linear bias, i.e. how often the linear
    474517        approximation with the highest bias is true or false minus
    475         $2^{n-1}$.
     518        `2^{n-1}`.
    476519
    477         EXAMPLE:
     520        EXAMPLE::
     521
    478522            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    479523            sage: S.maximal_linear_bias_absolute()
    480524            2
     
    488532        Return maximal bias of all linear approximations of this
    489533        S-box.
    490534
    491         EXAMPLE:
     535        EXAMPLE::
     536
    492537            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    493538            sage: S.maximal_linear_bias_relative()
    494539            0.25
     
    500545        Create, return and cache a polynomial ring for S-box
    501546        polynomials.
    502547
    503         EXAMPLE:
     548        EXAMPLE::
     549
    504550            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    505551            sage: S.ring()
    506552            Multivariate Polynomial Ring in x0, x1, x2, y0, y1, y2 over Finite Field of size 2
     
    523569        Return a dictionary of solutions to this S-box.
    524570
    525571        INPUT:
    526             X -- input variables (default: None)
    527             Y -- output variables (default: None)
    528572
    529         EXAMPLE:
     573        - ``X`` - input variables (default: ``None``)
     574
     575        - ``Y`` - output variables (default: ``None``)
     576
     577        EXAMPLE::
     578
    530579            sage: S = mq.SBox([7,6,0,4,2,5,1,3])
    531580            sage: F = S.polynomials()
    532581            sage: s = S.solutions()
     
    551600        return solutions
    552601
    553602    def polynomials(self, X=None, Y=None, degree=2, groebner=False):
    554         r"""
     603        """
    555604        Return a list of polynomials satisfying this S-box.
    556605
    557         If \code{groebner=False} these polynomials are at most of
    558         degree \code{degree}. Otherwise the highest degree equals the
    559         highest degree of the reduced Groebner basis.
     606        First, a simple linear fitting is performed for the given
     607        ``degree`` (cf. for example [BC03]_). If ``groebner=True`` a
     608        Groebner basis is also computed for the result of that
     609        process.
    560610
    561611        INPUT:
    562             X -- input variables
    563             Y -- output variables
    564             degree -- integer > 0 (default: 2)
    565             groebner -- calculate a reduced Groebner basis of the
    566                         spanning polynomials to obtain more
    567                         polynomials (default: False)
    568612
    569         EXAMPLES:
     613        - ``X`` - input variables
     614   
     615        - ``Y`` - output variables
     616
     617        - ``degree`` - integer > 0 (default: ``2``)
     618       
     619        - ``groebner`` - calculate a reduced Groebner basis of the
     620          spanning polynomials to obtain more polynomials (default:
     621          ``False``)
     622
     623        EXAMPLES::
     624
    570625            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    571626            sage: P = S.ring()
    572627
    573         By default, this method returns an indirect representation.
     628        By default, this method returns an indirect representation::
    574629
    575630            sage: S.polynomials()
    576631            [x0*x2 + x1 + y1 + 1,
     
    591646        We can get a direct representation by computing a
    592647        lexicographical Groebner basis with respect to the right
    593648        variable ordering, i.e. a variable orderings where the output
    594         bits are greater than the input bits.
     649        bits are greater than the input bits::
    595650
    596651            sage: P.<y0,y1,y2,x0,x1,x2> = PolynomialRing(GF(2),6,order='lex')
    597652            sage: S.polynomials([x0,x1,x2],[y0,y1,y2], groebner=True)
     
    599654             y1 + x0*x2 + x1 + 1,
    600655             y2 + x0 + x1*x2 + x1 + x2 + 1]
    601656
    602         REFERENCES: A. Biryukov and C. D. Canniere, Block Ciphers and
    603         Systems of Quadratic Equations, Fast Software Encryption 2003, LNCS
    604         2887, pp. 274-289, Springer-Verlag, 2003.
     657        REFERENCES:
     658
     659        .. [BC03] A. Biryukov and C. D. Canniere *Block Ciphers and
     660          Systems of Quadratic Equations*; in Proceedings of Fast
     661          Software Encryption 2003; LNCS 2887; pp. 274-289,
     662          Springer-Verlag 2003.
    605663        """
    606664        def nterms(nvars, deg):
    607665            """
    608             Return the number of monomials possible up to a given degree.
     666            Return the number of monomials possible up to a given
     667            degree.
    609668
    610669            INPUT:
    611                 nvars -- number of variables
    612                 deg -- degree
     670           
     671            - ``nvars`` - number of variables
    613672
    614             TESTS:
     673            - ``deg`` - degree
     674
     675            TESTS::
     676
    615677                sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    616678                sage: F = S.polynomials(degree=3) # indirect doctest
    617679            """
     
    683745        Return a univariate polynomial over an extension field
    684746        representing this S-box.
    685747
    686         If $m$ is the input length of this S-box then the extension
    687         field is of degree $m$.
     748        If ``m`` is the input length of this S-box then the extension
     749        field is of degree ``m``.
    688750
    689751        If the output length does not match the input length then a
    690         \code{TypeError} is raised.
     752        ``TypeError`` is raised.
    691753
    692754        INPUT:
    693             k -- an instance of GF($2^m$) (default: None)
    694755
    695         EXAMPLE:
     756        - ``k`` - an instance of `\GF{2^m}` (default: ``None``)
     757
     758        EXAMPLE::
     759
    696760            sage: S = mq.SBox(7,6,0,4,2,5,1,3)
    697761            sage: f = S.interpolation_polynomial()
    698762            sage: f
     
    714778            k = GF(2**self.m,'a')
    715779        l = []
    716780        for i in xrange(2**self.m):
    717             i = self.to_bits(i)
     781            i = self.to_bits(i, self.m)
    718782            o = self(i)
    719783            if self._big_endian:
    720784                i = reversed(i)