# 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
|
|
| 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**(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() |
| 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 | |