Ticket #6454: trac_6454_sbox.patch

File trac_6454_sbox.patch, 2.8 KB (added by ylchapuy, 14 years ago)
  • sage/crypto/mq/sbox.py

    # HG changeset patch
    # User Yann Laigle-Chapuy <yannlaiglechapuy@gmail.com>
    # Date 1246440597 -7200
    # Node ID 7c5c8a61a57b7720828b7dbfa87fff3b9d6444b1
    # Parent  f689362aedea169030751d5c0b4d97d90f938815
    improve sbox linear and differences matrices computation
    
    diff -r f689362aedea -r 7c5c8a61a57b sage/crypto/mq/sbox.py
    a b  
    402402       
    403403        A = Matrix(ZZ, nrows, ncols)
    404404       
    405         for di in range(nrows):
    406             for do in range(ncols):
    407                 for i in range(nrows):
    408                     if self(i) ^ self(i ^ di) == do:
    409                         A[di, do] += 1
     405        for i in range(nrows):
     406            si = self(i)
     407            for di in range(nrows):
     408                A[ di , si^self(i^di)] += 1
    410409        return A
    411410
    412411    def maximal_difference_probability_absolute(self):
     
    492491        nrows = 1<<m
    493492        ncols = 1<<n
    494493
    495         inp = [self.to_bits(e,m) for e in range(nrows)]
    496         out = [self.to_bits(self(e),n) for e in range(nrows)]
     494        def _walsh_transform(f):
     495            for ldk in xrange(1,m+1):
     496                k  = 1<<ldk
     497                kh = k//2
     498                for r in xrange(0,nrows,k):
     499                    t1 = r
     500                    t2 = r+kh
     501                    for j in xrange(kh):
     502                        u = f[t1]
     503                        v = f[t2]
     504                        f[t1] = u + v
     505                        f[t2] = u - v
     506                        t1 += 1
     507                        t2 += 1
     508            return f
    497509
    498         A = Matrix(ZZ, nrows, ncols)
    499         for i in range(nrows): #input variable configurations
    500             iconf = self.to_bits(i,m)
    501             for o in range(ncols): # output variable configurations
    502                 oconf = self.to_bits(o,n)
    503                 counter = 0
    504                 for j in range(nrows): # sbox value pairs
    505                     isum = sum( map( mul, zip(inp[j], iconf) ) )
    506                     osum = sum( map( mul, zip(out[j], oconf) ) )
    507                     if isum == osum:
    508                         counter += 1
    509                 A[i,o] = counter - 2**(m-1)
     510        A = Matrix(ZZ, ncols, nrows, [ _walsh_transform([sum((self(i)&j).bits())%2 for i in range(nrows)])
     511                                       for j in range(ncols) ] )
     512        A = -A.transpose()
    510513
    511         self._linear_approximation_matrix = A
     514        for i in range(ncols):
     515            A[0,i] += (nrows//2)
    512516        return A
    513517
    514518    def maximal_linear_bias_absolute(self):
     
    559563        m = self.m
    560564        n = self.n
    561565
    562         X = list(range(m))
    563         Y = list(range(n))
     566        X = range(m)
     567        Y = range(n)
    564568        self._ring = PolynomialRing(self._F, m+n, ["x%d"%i for i in X] + ["y%d"%i for i in Y])
    565569        return self._ring
    566570