1

如果我想加密 26 个字符的字母集,希尔密码中使用的密钥与加密 35 个字母集的密钥是否不同?

4

1 回答 1

2

这个想法没有改变,只是计算略有不同。我记得您在 Hill Cipher 上的最后一个问题是您实际上想为其实现 CBC 模式。我建议您选择计算 mod 256,而不是计算 mod 26 - 这样您就可以轻松地来回映射到密钥、IV 和生成的密文的字节表示。此外,它还允许您使用空格和其他标点符号,您甚至可以为您的消息使用 UTF-8 或类似编码。

密钥的想法不会改变 mod 256,但它的计算方式会有所不同。您必须选择在 Z^n/256 中可逆的矩阵,而不是选择在 Z^n/26 中可逆的矩阵。假设您选择了一个 3 x 3 矩阵,它仍然很容易可逆,然后您可以通过检查非零行列式模 256 来检查您选择的键(矩阵)是否可逆,如Wikipedia 文章中所述。然后,您的键的字节数组表示将只是一个长度为 9 的数组,从矩阵到数组的直接映射:元素 (1,2)(假设从零开始索引)将是数组的第五个元素( 1*3 + 2) 等

然后,您会将消息拆分为 3 字节块(如果最后一个块未与三个字节对齐,则使用某种形式的填充),这些块表示要与键矩阵相乘的向量,再次产生 3 字节输出块。

如您所见,使用 mod 256 表示非常简洁,因为这种方式加密/解密可以与相同的接口一起使用,该接口也可用于最先进的分组密码(如 AES),即加密消息通过对消息应用基于字节数组密钥的加密/解密函数,该消息被划分为适当大小的块/块。

在 Z^n/256 中生成 3x3 加密和解密矩阵

生成加密矩阵只需要创建一个随机 3x3 矩阵,其元素来自 Z256,直到找到具有非零行列式(模 256)和模逆元素模 256(我们将使用扩展欧几里得算法计算)的矩阵。然后,计算逆矩阵遵循与计算常规 3x3 矩阵逆相同的规则,除了所有计算都需要在 Z256 中进行。有一个用于计算 3x3 矩阵逆的封闭公式,如在此处找到。我们可以使用 Z256 中的模运算来计算完全相同的东西,以获得 Z^n/256 中的倒数。

这是一些生成键矩阵及其逆矩阵的 Ruby 代码:

require 'matrix'

class Integer
  def modinv(modulus)
    a, b = modulus, self
    q, r = a / b, a % b
    t0, t1 = 0, 1

    while r > 0
      t0, t1 = t1, (t0 - q * t1) % modulus
      a, b = b, r
      q, r = a / b, a % b
    end

    raise RuntimeError.new("#{self} has no inverse modulo #{modulus}") unless b == 1
    t1
  end
end

while true
  m = Matrix.build(3) { rand(0..256) }
  mod_det = m.determinant % 256
  next if mod_det == 0
  begin
    det_inv = mod_det.modinv(256)
    break
  rescue RuntimeError => e
    next
  end
end

inv = Matrix[
  [ (m[2,2]*m[1,1] - m[2,1]*m[1,2]), -(m[2,2]*m[0,1] - m[2,1]*m[0,2]),  (m[1,2]*m[0,1] - m[1,1]*m[0,2])],
  [-(m[2,2]*m[1,0] - m[2,0]*m[1,2]),  (m[2,2]*m[0,0] - m[2,0]*m[0,2]), -(m[1,2]*m[0,0] - m[1,0]*m[0,2])],
  [ (m[2,1]*m[1,0] - m[2,0]*m[1,1]), -(m[2,1]*m[0,0] - m[2,0]*m[0,1]),  (m[1,1]*m[0,0] - m[1,0]*m[0,1])]
].map { |e| e * det_inv % 256 }

p m #=> encryption matrix
p inv #=> decryption matrix
identity = (inv * m).map { |e| e % 256 }
p identity #=> living proof that m * inv is the identity matrix

示例输出:

m   = Matrix[[167, 8, 48], [54, 107, 25], [170, 184, 107]]
inv = Matrix[[119, 152, 136], [184, 235, 231], [174, 120, 59]]
于 2012-05-22T21:42:04.403 回答