decode-berkle.sage 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import itertools
  2. q = 11
  3. n = 10
  4. k = 4
  5. d = n - k + 1
  6. K = GF(q)
  7. R.<x> = K[]
  8. α = K(2)
  9. assert set(α^i for i in range(q - 1)) | {0} == set(K)
  10. # Pick a random codeword
  11. m = (3, 0, 7, 9)
  12. f = m[0] + m[1]*x + m[2]*x^2 + m[3]*x^3
  13. print(f"m = {m}")
  14. c = vector(f(α^i) for i in range(q - 1))
  15. assert len(c) == q - 1
  16. print(f"c = {c}")
  17. e = int((n - k)/2)
  18. assert e == 3
  19. # We can tolerate <= (n-k)/2 = 3 errors
  20. c[2] = 0
  21. c[4] = 6
  22. c[7] = 7
  23. # Naive and very slow
  24. freqs = {}
  25. for (i0, i1, i2, i3) in itertools.permutations(range(n), int(4)):
  26. g = R.lagrange_polynomial([
  27. (α^i0, c[i0]),
  28. (α^i1, c[i1]),
  29. (α^i2, c[i2]),
  30. (α^i3, c[i3]),
  31. ])
  32. if not g in freqs:
  33. freqs[g] = 0
  34. freqs[g] += 1
  35. max_key = max(freqs.keys(), key=lambda k: freqs[k])
  36. assert max_key == f
  37. E0 = (x - α^2)*(x - α^4)*(x - α^7)
  38. assert E0.degree() <= n - k - 1
  39. N0 = E0*f
  40. print(f"E = {E0}")
  41. print(f"N = {N0}")
  42. S = []
  43. for i in range(n):
  44. row = []
  45. αi = α^i
  46. # deg N = e + (k - 1)
  47. for j in range(e + k):
  48. row.append(αi^j)
  49. r_i = c[i]
  50. # deg E = e
  51. # We don't need x^e here
  52. for j in range(e):
  53. row.append(-r_i * αi^j)
  54. assert n == 2*e + k
  55. assert len(row) == n
  56. S.append(row)
  57. assert len(S) == n
  58. A = matrix(S)
  59. s = vector(r * α^(i*e) for (i, r) in enumerate(c))
  60. print(f"s = {s}")
  61. v = A.solve_right(s)
  62. print(f"A = {A}")
  63. print(f"v = {v}")
  64. Nv, Ev = v[:e + k], v[e + k:]
  65. print(Nv)
  66. print(Ev)
  67. N = sum(Ni * x^i for (i, Ni) in enumerate(Nv))
  68. E = sum(Ei * x^i for (i, Ei) in enumerate(Ev)) + x^e
  69. print(f"N = {N}")
  70. print(f"E = {E}")
  71. assert N == N0
  72. assert E == E0
  73. f, rem = N.quo_rem(E)
  74. assert rem == 0
  75. print(f"f = {f} =", list(f))