蒙特卡洛测试的AES验证标准伪代码缺少什么? [英] What is missing from the AES Validation Standard Pseudocode for the Monte Carlo Tests?

查看:71
本文介绍了蒙特卡洛测试的AES验证标准伪代码缺少什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用CBC模式下针对AES-128的规定验证程序,如

I'm trying to use the prescribed validation procedure for AES-128 in CBC mode, as defined in the NIST AESAVS standard. One of the more important parts of the test suite is the Monte Carlo test, which provides an algorithm for generating many 10000 pseudorandom tests cases such that it is unlikely that a hardcoded circuit could fake AES. The algorithm pseudocode therein appears to be taking some liberties with variable scope and definition, so I am hoping someone could help me fill in the missing information to interpret this correctly.

128位密钥大小写的逐字算法如下:

The verbatim algorithm for the 128-bit key case is as follows:

Key[0] = Key
IV[0] = IV
PT[0] = PT
For i = 0 to 99
    Output Key[i]
    Output IV[i]
    Output PT[0]
    For j = 0 to 999
        If ( j=0 )
            CT[j] = AES(Key[i], IV[i], PT[j])
            PT[j+1] = IV[i]
        Else
            CT[j] = AES(Key[i], PT[j])
            PT[j+1] = CT[j-1]
    Output CT[j]
    Key[i+1] = Key[i] xor CT[j]
    IV[i+1] = CT[j]
    PT[0] = CT[j-1]

对于上述伪代码,从以下初始值开始:

For the above pseudocode, starting with these initial values:

Key = 9dc2c84a37850c11699818605f47958c
IV = 256953b2feab2a04ae0180d8335bbed6
PT = 2e586692e647f5028ec6fa47a55a2aab

外循环的前三个迭代应该输出:

The first three iterations of the outer loop should output:

KEY = 9dc2c84a37850c11699818605f47958c
IV = 256953b2feab2a04ae0180d8335bbed6
PLAINTEXT = 2e586692e647f5028ec6fa47a55a2aab
CIPHERTEXT = 1b1ebd1fc45ec43037fd4844241a437f

KEY = 86dc7555f3dbc8215e6550247b5dd6f3
IV = 1b1ebd1fc45ec43037fd4844241a437f
PLAINTEXT = c1b77ed52521525f0a4ba341bdaf51d9
CIPHERTEXT = bf43583a665fa45fdee831243a16ea8f

KEY = 399f2d6f95846c7e808d6100414b3c7c
IV = bf43583a665fa45fdee831243a16ea8f
PLAINTEXT = 7cbeea19157ec7bbf6289e2dff5e8ee4
CIPHERTEXT = 5464e1900f81e06f67139456da25fc09

似乎我们在内部循环之外使用了 j ,我认为这是造成混乱的原因.我原本以为这意味着密文 CT 的最终值是( CT [999] ),这会让我相信下一个外部的明文循环 PT [0] 初始化为 CT [998] .但是,这种解释与给定的预期输出不匹配.

It looks like we are using j outside of the inner loop, which I believe is the source of the confusion. I had originally assumed that this meant whatever the final value of the ciphertext CT was (CT[999]), which would lead me to believe that the plaintext for the next outer loop PT[0] is initialized to CT[998]. However, this interpretation doesn't match the expected outputs given.

我还认为也许括号不是在这里表示值的数组,而是表示相对于现在的时间步长.但是,这也会使在循环外部引用 j 造成混淆.如果循环已过期,那么 i j 是当前时间?

I also thought that maybe brackets are not indicating an array of values here, but rather they represent the time steps relative to now. However, this also makes referencing j outside of the loop confusing. If the loop has expired, then is i or j the current time?

我在这里错过了一些关键步骤吗?是否有错字(文档中没有勘误)?

Am I missing some crucial step here? Is there a typo (there is no errata in the document)?

任何对此事有经验的人都可以对适当的解释发表评论吗?

Could anyone with some experience on the matter comment on the appropriate interpretation?

推荐答案

几个月前,我试图使AES CBC MonteCarlo在Java上运行.我遇到了同样的问题,但最终我可以找到一个符合NIST官方矢量结果的完整且可运行的解决方案.

Some months ago I tried to get the AES CBC MonteCarlo running on Java. I encountered the same problems but in the end I could find a complete and running solution that meets the official NIST vector results.

开始之前-您的初始测试向量似乎是一个自己的向量,但不是NIST提供的向量-这是带有所有AES测试向量的官方NIST网站的链接:

Before I start - your inital test vector seems to be an own vector but not the one provided by NIST - here is the link to the official NIST-website with all AES testvectors:

NIST网站: https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers 蒙特卡洛测试向量:

NIST-Website: https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers Montecarlo testvectors: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/aesmct.zip

我的测试将从这些数据开始:

My test will start with these data:

[ENCRYPT]
COUNT = 0
KEY = 8809e7dd3a959ee5d8dbb13f501f2274
IV = e5c0bb535d7d54572ad06d170a0e58ae
PLAINTEXT = 1fd4ee65603e6130cfc2a82ab3d56c24
CIPHERTEXT = b127a5b4c4692d87483db0c3b0d11e64

,并且该函数使用"double"内部和外部循环的字节数组.我没有在此处显示完整的源代码,但是完整的代码可在我的GitHub存储库中找到 https://github.com/java-crypto/Known_Answer_Tests 以及许多其他测试和测试矢量文件.加密/解密必须通过 NoPadding 完成-请勿像大多数情况下那样在默认模式下使用AES在这种情况下,它将使用PKCS#5/#7填充.

and the function uses a "double" byte array for the inner and outer loop. I do not present the complete sourcode here on SO but the complete code is available in my GitHub repository https://github.com/java-crypto/Known_Answer_Tests with many other tests and test vector files. The encryption/decryption has to be done with NoPadding - don't use AES in default mode as in most cases it would run with PKCS#5/#7 padding.

如果愿意,可以在此处在线运行代码(简化为AES CBC 128 MonteCarlo): https://repl.it/@javacrypto/AesCbcMonteCarloTest#Main.java

If you like you can run the code online (reduced to AES CBC 128 MonteCarlo) here: https://repl.it/@javacrypto/AesCbcMonteCarloTest#Main.java

该程序将运行完整的加密和解密测试,并进行其他交叉检查(表示已检查加密结果通过解密,反之亦然).

The program will run the complete encryption and decryption test and does an additional cross-check (means the encryption result is checked by a decryption and vice versa).

就像几个月前我照顾的那样,我只是用Java代码提供我的解决方案-希望它可以帮助您您对NIST测试程序的了解.

As it is some months ago that I took care of this I'm just offering my solution in Java code - hopefully it helps you in your understanding of the NIST test procedure.

public static byte[] aes_cbc_mct_encrypt(byte[] PLAINTEXT, byte[] KEYinit, byte[] IVinit) throws Exception {
    int i = 0; // outer loop
    int j = 0; // inner loop
    byte[][] KEY = new byte[101][128];
    byte[][] IV = new byte[1001][128];
    byte[][] PT = new byte[1001][128]; // plaintext
    byte[][] CT = new byte[1001][128]; // ciphertext
    byte[] CTsave = new byte[256]; // nimmt den letzten ct fuer nutzung als neuen iv auf
    // init
    int KEYLENGTH = KEYinit.length * 8;
    KEY[0] = KEYinit;
    IV[0] = IVinit;
    PT[0] = PLAINTEXT;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++) {
            if (j == 0) {
                CT[j] = aes_cbc_encrypt(PT[j], KEY[i], IV[i]);
                CTsave = CT[j]; // sicherung fuer naechsten iv
                PT[j + 1] = IV[i];
            } else {
                IV[i] = CTsave;
                CT[j] = aes_cbc_encrypt(PT[j], KEY[i], IV[i]);
                CTsave = CT[j];
                PT[j + 1] = CT[j - 1];
            }
        }
        j = j - 1; // correction of loop counter
        if (KEYLENGTH == 128) {
            KEY[i + 1] = xor(KEY[i], CT[j]);
        }
        if (KEYLENGTH == 192) {
            KEY[i + 1] = xor192(KEY[i], CT[j - 1], CT[j]);
        }
        if (KEYLENGTH == 256) {
            KEY[i + 1] = xor256(KEY[i], CT[j - 1], CT[j]);
        }
        IV[i + 1] = CT[j];
        PT[0] = CT[j - 1];
        ctCalculated[i] = CT[j].clone();
    }
    return CT[j];
}

public static byte[] xor(byte[] a, byte[] b) {
    // nutzung in der mctCbcEncrypt und mctCbcDecrypt methode
    byte[] result = new byte[Math.min(a.length, b.length)];
    for (int i = 0; i < result.length; i++) {
        result[i] = (byte) (((int) a[i]) ^ ((int) b[i]));
    }
    return result;
}

public static byte[] aes_cbc_encrypt(byte[] plaintextByte, byte[] keyByte, byte[] initvectorByte) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
    byte[] ciphertextByte = null;
    SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
    IvParameterSpec ivKeySpec = new IvParameterSpec(initvectorByte);
    Cipher aesCipherEnc = Cipher.getInstance("AES/CBC/NOPADDING");
    aesCipherEnc.init(Cipher.ENCRYPT_MODE, keySpec, ivKeySpec);
    ciphertextByte = aesCipherEnc.doFinal(plaintextByte);
    return ciphertextByte;
}

这篇关于蒙特卡洛测试的AES验证标准伪代码缺少什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆