Ticket #6454: trac_6454_sbox.patch

File trac_6454_sbox.patch, 2.8 KB (added by ylchapuy, 9 months 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