# HG changeset patch
# User Yann LaigleChapuy <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


402  402  
403  403  A = Matrix(ZZ, nrows, ncols) 
404  404  
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 
410  409  return A 
411  410  
412  411  def maximal_difference_probability_absolute(self): 
… 
… 

492  491  nrows = 1<<m 
493  492  ncols = 1<<n 
494  493  
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 
497  509  
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**(m1) 
 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() 
510  513  
511   self._linear_approximation_matrix = A 
 514  for i in range(ncols): 
 515  A[0,i] += (nrows//2) 
512  516  return A 
513  517  
514  518  def maximal_linear_bias_absolute(self): 
… 
… 

559  563  m = self.m 
560  564  n = self.n 
561  565  
562   X = list(range(m)) 
563   Y = list(range(n)) 
 566  X = range(m) 
 567  Y = range(n) 
564  568  self._ring = PolynomialRing(self._F, m+n, ["x%d"%i for i in X] + ["y%d"%i for i in Y]) 
565  569  return self._ring 
566  570  