At Python Homework Help, we are the top choice for students seeking help for Python programming . We offer fast, high-quality, and reliable homework assistance. If your Python Homework Solution is due then don’t delay. Contact us, and get started on your programming homework
To hire an expert, Mail us at support@pythonhomeworkhelp.com or visit our website pythonhomeworkhelp.com for assistance. You can also Call/WhatsApp us at +1 (315)557-6473
Difference Between Search & Browse Methods in Odoo 17
Python Homework Solution
1. For any help regarding Python Homework Help
visit : - https://www.pythonhomeworkhelp.com/,
Email :- support@pythonhomeworkhelp.com or
call us at :- +1 (315) 557-6473
2. Problem 1. Kalns
Ben Bitdiddle has designed a new cryptosystem called Kalns, but we suspect it might not be as strong
as we would like to be. Therefore we ask your help to break it.
In this problem we will be working with a finite field GF16. The elements of our field are all 4-bit strings.
The field addition is computed as xor: GF16(x) + GF16(y) = GF16(x ⊕
y). We provide the two tables describing addition and multiplication laws on the course web page.
If you are curious, these tables are obtained by interpreting 4-bit field elements as degree≤
4 polynomials over GF2 and performing addition and multiplication modulo the irreducible polynomial
x4 + x + 1.
However, for the purposes of this problem you do not need to understand how our GF16 is constructed;
the solutions we know assume black-box access to GF16. We have provided a GF16 implementation for
you.
Kalns is a 64-bit block cipher. The secret key consists of three parts:
•an invertible 16-by-16 matrix A over GF16;
•a 16-element vector b over GF16; and
•a permutation (bijection) S that maps GF16 one-to-one and onto GF16.
https://www.pythonhomeworkhelp.com/
3. To encrypt a 64-bit block B we first break it up in sixteen 4-bit chunks and interpret each of them as a
GF16 element. So block B corresponds to length 16 vector x = (x0, . . . , x15) over GF16.
The encryptions consists of the following: y = S(Ax + b), where the permutation S is individually applied
to each of 16 elements of v = Ax + b. The 16-element vector y is later re-interpreted as 64-bit integer to
obtain the encrypted block B'.
(a) Ben suspects that his cryptosystem is very secure. After all it has around 16162 1616 16! 21132.25
possible keys. However, we suspect that there are many equivalent keys. These keys have different
values for (A, b, S), but produce the same ciphertext for any given plaintext. Is our suspicion well-
founded?
(b) Describe a chosen-ciphertext attack on Kalns that recovers the unknown key (A, b, S) or an
equivalent key.
https://www.pythonhomeworkhelp.com/
4. Solution:
class GF16(object):
"""Implementation of GF(2^4) as degree 4 polynomials over GF(2) modulo
x^4 + x + 1.
"""
def __init__(self, val):
if not (isinstance(val, int) or isinstance(val, long)) or val < 0 or val > 15:
raise ValueError("GF16 elements must be constructed from integers from 0 to 15.")
self.val = val
def __repr__(self):
return "GF16(%d)" % self.val
def __add__(self, other):
if not isinstance(other, GF16):
raise ValueError("Addition is only defined between a GF16 element and GF16 element")
return GF16(self.val ^ other.val)
def __sub__(self, other):
if not isinstance(other, GF16):
raise ValueError("Subtraction is only defined between a GF16 element and GF16 element")
# +1 equals -1 (mod 2), so both operations are XOR
return GF16(self.val ^ other.val)
https://www.pythonhomeworkhelp.com/
5. def __neg__(self):
# +1 equals -1 (mod 2), so negation is the same element
return GF16(self.val)
def __mul__(self, other):
if not isinstance(other, GF16):
raise ValueError("Multiplication is only defined between a GF16 element and GF16 element")
a, b = self.val, other.val
r = 0
for c in xrange(4):
if b & 1:
r = r^a
a <<= 1
if a & 16 == 16:
a ^= (16 + 2 + 1) # subtract x^4 + x + 1
b >>= 1
return GF16(r)
def __div__(self, other):
if not isinstance(other, GF16):
raise ValueError("Division is only defined between a GF16 element and GF16 element")
return self * other.inverse()
__truediv__ = __div__
https://www.pythonhomeworkhelp.com/
6. def __eq__(self, other):
if isinstance(other, GF16):
return self.val == other.val
else:
return False
def __ne__(self, other):
if isinstance(other, GF16):
return self.val != other.val
else:
return True
def inverse(self):
if self.val == 0:
raise ValueError("Zero is not invertible.")
# We know that x^15 = x^14 * x = 1, so x^14 = x^{-1}
s2 = self * self
s4 = s2 * s2
s7 = self * s2 * s4
s14 = s7 * s7
return s14
def test_GF16():
# associativity
https://www.pythonhomeworkhelp.com/
7. for a in xrange(16):
for b in xrange(16):
for c in xrange(16):
assert GF16(a) * (GF16(b) * GF16(c)) == (GF16(a) * GF16(b)) * GF16(c)
assert GF16(a) + (GF16(b) + GF16(c)) == (GF16(a) + GF16(b)) + GF16(c)
# commutativity
for a in xrange(16):
for b in xrange(16):
assert GF16(a) * GF16(b) == GF16(b) * GF16(a)
assert GF16(a) + GF16(b) == GF16(b) + GF16(a)
# distributivity
for a in xrange(16):
for b in xrange(16):
for c in xrange(16):
assert GF16(a) * (GF16(b) + GF16(c)) == GF16(a) * GF16(b) + GF16(a) * GF16(c)
# inverses
for a in xrange(16):
assert GF16(a) + (-GF16(a)) == GF16(0)
for a in xrange(1, 16):
assert GF16(a) * (GF16(a).inverse()) == GF16(1)
https://www.pythonhomeworkhelp.com/
8. def matrix_by_vector(A, x):
zero = type(x[0])(0)
result = []
for row in A:
assert len(row) == len(x)
c = sum((rowi * xi for rowi, xi in zip(row, x)), zero)
result.append(c)
return result
def matrix_by_matrix(A, B):
zero = type(A[0][0])(0)
C = []
for i in xrange(len(A)):
Ci = []
for j in xrange(len(A[i])):
Cij = sum((A[i][k] * B[k][j] for k in xrange(len(A[i]))), zero)
Ci.append(Cij)
C.append(Ci)
return C
def matrix_inverse(A):
# O(n^3) inversion using Gauss-Jordan algorithm
https://www.pythonhomeworkhelp.com/
9. zero = type(A[0][0])(0)
one = type(A[0][0])(1)
n = len(A)
M = [A[i] + [zero] * i + [one] + [zero] * (n-1-i) for i in xrange(n)] # augment with identity matrix
# first make the matrix in upper-triangular form
for i in xrange(n):
pivot = None
for j in xrange(i, n):
if M[j][i] != zero:
pivot = j
break
if pivot is None:
raise ValueError, "Matrix is not invertible?"
# swap rows i and pivot
if pivot != i:
M[pivot], M[i] = M[i], M[pivot]
# divide out the row itself by the diagonal element
multiple = M[i][i]
for k in xrange(2*n):
M[i][k] /= multiple
https://www.pythonhomeworkhelp.com/
10. # subtract this row appropriate number of times for every row below it
for j in xrange(i+1, n):
multiple = M[j][i]
for k in xrange(2*n):
M[j][k] -= M[i][k] * multiple
# then work our way back up
for i in xrange(n-1, -1, -1):
for j in xrange(i-1, -1, -1):
multiple = M[j][i]
for k in xrange(2*n):
M[j][k] -= M[i][k] * multiple
# return the augmented part
return [M[i][n:] for i in xrange(n)]
def test_matrix_inverse(n):
r = range(n)
random.shuffle(r)
P = [[GF16(0)] * n for i in xrange(n)]
L = [[GF16(0)] * n for i in xrange(n)]
U = [[GF16(0)] * n for i in xrange(n)]
for i in xrange(n):
https://www.pythonhomeworkhelp.com/
11. P[i][r[i]] = GF16(1)
L[i][i] = GF16(random.randint(1, 15))
U[i][i] = GF16(random.randint(1, 15))
for j in xrange(i):
L[i][j] = GF16(random.randint(0, 15))
for j in xrange(i+1, n):
U[i][j] = GF16(random.randint(0, 15))
M = matrix_by_matrix(matrix_by_matrix(L, U), P)
Minv = matrix_inverse(M)
MMinv = matrix_by_matrix(M, Minv)
for i in xrange(n):
for j in xrange(n):
assert MMinv[i][j] == (GF16(1) if i == j else GF16(0))
def vector_add(u, v):
assert len(u) == len(v)
return [ui + vi for ui, vi in zip(u, v)]
def vector_sub(u, v):
assert len(u) == len(v)
return [ui - vi for ui, vi in zip(u, v)]
def random_GF16_vector(n):
return [GF16(random.randint(0, 15)) for i in xrange(n)]
https://www.pythonhomeworkhelp.com/
12. def random_GF16_matrix(n):
return [random_GF16_vector(n) for i in xrange(n)]
def random_invertible_GF16_matrix(n):
while True:
M = random_GF16_matrix(n)
try:
Minv = matrix_inverse(M)
except ValueError, e:
continue
return M
def int64_to_GF16_vec(x):
v = [None] * 16
for i in xrange(16):
v[15-i] = GF16(x & 15)
x >>= 4
assert x == 0
return v
def GF16_vec_to_int64(v):
assert len(v) == 16
x = 0
for el in v:
x = (x << 4) | el.val
return x
https://www.pythonhomeworkhelp.com/