Monte Carlo 测试的 AES CBC 解密验证
AES CBC decryption validation for Monte Carlo Tests
我正在尝试在 AES CBC 上执行 MCT。伪代码记录在此处:https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/AESAVS.pdf section 6.4.2
注意伪代码有错误,这里揭示:
通过结合这两个参考资料,我能够为 MCT 提出一个有效的加密测试。以下代码显示了工作加密模块(给定初始密钥 iv 和明文作为十六进制字符串):
def monte_carlo_encrypt(key_len, initial_key, initial_iv, initial_pt):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
pt_array.append(bytes.fromhex(initial_pt))
for j in range(0, 1000):
if j == 0:
ct = encrypt(key_array[0], iv_array[0], pt_array[j])
ct_array.append(ct)
pt_array.append(iv_array[0])
else:
ct = encrypt(key_array[0], ct_array[j - 1], pt_array[j])
ct_array.append(ct)
pt_array.append(ct_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], ct_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], ct_array[j - 1] + ct_array[j])))
iv_array.append(ct_array[-1])
pt_array.clear()
pt_array.append(ct_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_encrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_pt.hex().upper())
key = next_key
iv = next_iv
given_pt = next_pt
以上测试产生了正确的结果,可以使用上面链接的 Whosebug 问题中概述的标准进行测试。
现在,当我尝试将其改编为解密时,问题出现了。根据 NIST 参考资料,“
的伪代码
解密可以通过将所有 PT 替换为 CT 并将所有 CT 替换为 PT 来获得。 “
所以,我试过了,想出了这个:
def monte_carlo_decrypt(key_len, initial_key, initial_iv, initial_ct):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
ct_array.append(bytes.fromhex(initial_ct))
for j in range(0, 1000):
if j == 0:
pt = decrypt(key_array[0], iv_array[0], ct_array[j])
pt_array.append(pt)
ct_array.append(iv_array[0])
else:
pt = decrypt(key_array[0], pt_array[j - 1], ct_array[j])
pt_array.append(pt)
ct_array.append(pt_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j - 1] + pt_array[j])))
iv_array.append(pt_array[-1])
ct_array.clear()
ct_array.append(pt_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_decrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_ct.hex().upper())
key = next_key
iv = next_iv
given_ct = next_ct
但是这个解密模块在第一次迭代时就把解密弄错了。给定:
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"key": "A58C28340553879F488E161CF815D104",
"ct": "349F129B75B99E845D99090B26801D12"
它应该产生:
"key": "A58C28340553879F488E161CF815D104",
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"pt": "9B2F1D63DE3809F47E40EFB885F01277",
"ct": "349F129B75B99E845D99090B26801D12"
但我的产生:
"key": "A58C28340553879F488E161CF815D104",
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"pt": "23119C0130042FDA973D171E9E9E4921",
"ct": "349F129B75B99E845D99090B26801D12"
有人看到我的解密实施哪里出了问题吗?
我找到了答案。我找到了这个参考,它在伪代码方面比 NIST 参考更有帮助:https://www.ipa.go.jp/security/jcmvp/jcmvp_e/documents/atr/atr01b_en.pdf section 3.4.3.2.2
这是有效的解密代码:
def monte_carlo_decrypt(key_len, initial_key, initial_iv, initial_ct):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
ct_array.append(bytes.fromhex(initial_ct))
for j in range(0, 1000):
pt = decrypt(key_array[0], iv_array[j], ct_array[j])
pt_array.append(pt)
if j == 0:
tmp = ct_array[j]
ct_array.append(iv_array[j])
iv_array.append(tmp)
else:
iv_array.append(ct_array[j])
ct_array.append(pt_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j - 1] + pt_array[j])))
iv_array.append(pt_array[-1])
ct_array.clear()
ct_array.append(pt_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_encrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_pt.hex().upper())
key = next_key
iv = next_iv
given_pt = next_pt
我正在尝试在 AES CBC 上执行 MCT。伪代码记录在此处:https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/AESAVS.pdf section 6.4.2
注意伪代码有错误,这里揭示:
通过结合这两个参考资料,我能够为 MCT 提出一个有效的加密测试。以下代码显示了工作加密模块(给定初始密钥 iv 和明文作为十六进制字符串):
def monte_carlo_encrypt(key_len, initial_key, initial_iv, initial_pt):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
pt_array.append(bytes.fromhex(initial_pt))
for j in range(0, 1000):
if j == 0:
ct = encrypt(key_array[0], iv_array[0], pt_array[j])
ct_array.append(ct)
pt_array.append(iv_array[0])
else:
ct = encrypt(key_array[0], ct_array[j - 1], pt_array[j])
ct_array.append(ct)
pt_array.append(ct_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], ct_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], ct_array[j - 1] + ct_array[j])))
iv_array.append(ct_array[-1])
pt_array.clear()
pt_array.append(ct_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_encrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_pt.hex().upper())
key = next_key
iv = next_iv
given_pt = next_pt
以上测试产生了正确的结果,可以使用上面链接的 Whosebug 问题中概述的标准进行测试。
现在,当我尝试将其改编为解密时,问题出现了。根据 NIST 参考资料,“
的伪代码
解密可以通过将所有 PT 替换为 CT 并将所有 CT 替换为 PT 来获得。 “
所以,我试过了,想出了这个:
def monte_carlo_decrypt(key_len, initial_key, initial_iv, initial_ct):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
ct_array.append(bytes.fromhex(initial_ct))
for j in range(0, 1000):
if j == 0:
pt = decrypt(key_array[0], iv_array[0], ct_array[j])
pt_array.append(pt)
ct_array.append(iv_array[0])
else:
pt = decrypt(key_array[0], pt_array[j - 1], ct_array[j])
pt_array.append(pt)
ct_array.append(pt_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j - 1] + pt_array[j])))
iv_array.append(pt_array[-1])
ct_array.clear()
ct_array.append(pt_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_decrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_ct.hex().upper())
key = next_key
iv = next_iv
given_ct = next_ct
但是这个解密模块在第一次迭代时就把解密弄错了。给定:
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"key": "A58C28340553879F488E161CF815D104",
"ct": "349F129B75B99E845D99090B26801D12"
它应该产生:
"key": "A58C28340553879F488E161CF815D104",
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"pt": "9B2F1D63DE3809F47E40EFB885F01277",
"ct": "349F129B75B99E845D99090B26801D12"
但我的产生:
"key": "A58C28340553879F488E161CF815D104",
"iv": "9982F2D532BC341791ECC30A1FEA9A3F",
"pt": "23119C0130042FDA973D171E9E9E4921",
"ct": "349F129B75B99E845D99090B26801D12"
有人看到我的解密实施哪里出了问题吗?
我找到了答案。我找到了这个参考,它在伪代码方面比 NIST 参考更有帮助:https://www.ipa.go.jp/security/jcmvp/jcmvp_e/documents/atr/atr01b_en.pdf section 3.4.3.2.2
这是有效的解密代码:
def monte_carlo_decrypt(key_len, initial_key, initial_iv, initial_ct):
key_array = []
iv_array = []
pt_array = []
ct_array = []
key_array.append(bytes.fromhex(initial_key))
iv_array.append(bytes.fromhex(initial_iv))
ct_array.append(bytes.fromhex(initial_ct))
for j in range(0, 1000):
pt = decrypt(key_array[0], iv_array[j], ct_array[j])
pt_array.append(pt)
if j == 0:
tmp = ct_array[j]
ct_array.append(iv_array[j])
iv_array.append(tmp)
else:
iv_array.append(ct_array[j])
ct_array.append(pt_array[j - 1])
if key_len == 128:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j])))
elif key_len == 256:
key_array.append(bytes(a ^ b for a, b in zip(key_array[0], pt_array[j - 1] + pt_array[j])))
iv_array.append(pt_array[-1])
ct_array.clear()
ct_array.append(pt_array[-2])
return key_array[-1], iv_array[-1], pt_array[-1], ct_array[-1]
for k in range(0, 100):
(next_key, next_iv, next_pt, next_ct) = monte_carlo_encrypt(key_len * 8,
key.hex().upper(),
iv.hex().upper(),
given_pt.hex().upper())
key = next_key
iv = next_iv
given_pt = next_pt