Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speck implemententation not matching test vector from wiki #932

Closed
dercdev opened this issue Feb 9, 2020 · 4 comments
Closed

Speck implemententation not matching test vector from wiki #932

dercdev opened this issue Feb 9, 2020 · 4 comments
Labels

Comments

@dercdev
Copy link

dercdev commented Feb 9, 2020

Hello,

i am new to cryptopp and currently getting familiar with the lib. I am testing with the speck cipher and want to reproduce the example from the wiki shown here:

https://www.cryptopp.com/wiki/SPECK

I am refering to the following lines on the wiki:

Key: F36D4289293A07A0C1E3D8EAFBF83C6F
IV: 50650B834D62457D3D5CBFE9708EC927
plain text: CBC Mode Test
Cipher text: 952FB25AF03C17F972BEB9357AA48719
recovered text: CBC Mode Test

I started implementing with the code shown in the wiki and wanted to repoduce the test vector shown above. So see my example program:

CryptoPP::AutoSeededRandomPool prng;

//CryptoPP::SecByteBlock key(CryptoPP::SPECK128::DEFAULT_KEYLENGTH);
//prng.GenerateBlock(key, key.size());

const string ivstr = "50650B834D62457D3D5CBFE9708EC927";
     
string ivdecoded;
CryptoPP::StringSource ss(ivstr, true,
    new CryptoPP::HexDecoder(
        new CryptoPP::StringSink(ivdecoded)
    )
);

CryptoPP::SecByteBlock iv(reinterpret_cast<const CryptoPP::byte*>(&ivdecoded[0]), ivdecoded.size());     

const string k = "F36D4289293A07A0C1E3D8EAFBF83C6F";

string decoded;
CryptoPP::StringSource ss2(k, true,
                          new CryptoPP::HexDecoder(
	                          new CryptoPP::StringSink(decoded)
                          ) // HexDecoder
); // StringSource
CryptoPP::SecByteBlock key(reinterpret_cast<const CryptoPP::byte*>(&decoded[0]), decoded.size());

std::cout << "Key: ";
CryptoPP::StringSource(key, key.size(), true, new CryptoPP::HexEncoder(new CryptoPP::FileSink(std::cout)));
std::cout << std::endl;

std::cout << "IV: ";
CryptoPP::StringSource(iv, sizeof(iv), true, new CryptoPP::HexEncoder(new CryptoPP::FileSink(std::cout)));
std::cout << std::endl;

string plain = "CBC Mode Test";
string cipher, encoded, recovered;

/*********************************\
\*********************************/

try
{
    std::cout << "plain text: " << plain << std::endl;

    CryptoPP::CBC_Mode<CryptoPP::SPECK128 >::Encryption e;
    e.SetKeyWithIV(key, key.size(), iv);

    // The StreamTransformationFilter adds padding
    //  as required. ECB and CBC Mode must be padded
    //  to the block size of the cipher.
    CryptoPP::StringSource(plain, true,
                           new CryptoPP::StreamTransformationFilter(e, new CryptoPP::StringSink(cipher), CryptoPP::BlockPaddingSchemeDef::DEFAULT_PADDING) // StreamTransformationFilter
    ); // StringSource

}
catch (const CryptoPP::Exception & e)
{
    std::cerr << e.what() << std::endl;
    //exit(1);
}

/*********************************\
\*********************************/

// Pretty print
std::cout << "Cipher text: ";
CryptoPP::StringSource(cipher, true, new CryptoPP::HexEncoder(new CryptoPP::FileSink(std::cout)));
std::cout << std::endl;

/*********************************\
\*********************************/

try
{
    CryptoPP::CBC_Mode<CryptoPP::SPECK128 >::Decryption d;
    d.SetKeyWithIV(key, key.size(), iv);

    // The StreamTransformationFilter removes
    //  padding as required.
    CryptoPP::StringSource s(cipher, true,
                             new CryptoPP::StreamTransformationFilter(d,
                                                                      new CryptoPP::StringSink(recovered), CryptoPP::BlockPaddingSchemeDef::DEFAULT_PADDING
                             ) // StreamTransformationFilter
    ); // StringSource

    std::cout << "recovered text: " << recovered << std::endl;
}
catch (const CryptoPP::Exception & e)
{
    cerr << e.what() << std::endl;
    //exit(1);
}

As a summary what my program does:
I am using a fixed IV and key (with the values from the wiki) instead of randomly generated values. My expectation is, that the program produces as cipher text "952FB25AF03C17F972BEB9357AA48719" (value from the wiki). But it generetes the following cipher text instead: "D3937748C4A9D3B215E930F41C6AD76B" which differs from the value of the wiki. In my opinion there is an error in my implementation or the test vector is wrong. May be someone can help?

OS: Windows 10 x64 with VS 2019
Crypto++ library: 8.2 Release from the website

@noloader
Copy link
Collaborator

noloader commented Feb 9, 2020

In my opinion there is an error in my implementation or the test vector is wrong. May be someone can help?

It is probably your implementation. The specification for SIMON and SPECK caused a lot of confusion when first released because the authors were a bit vague about endianess and presentation of test vectors. The kernel and Crypto++ had to change their implementations to align with what the authors stated in their paper (and not what they showed in their test vectors).

The NSA folks published an implementation guide at SIMON and SPECK Implementation Guide. It removed confusion for the implementors. You can find it at the NSA's GitHub.

You can also test the library's implementation using:

$ ./cryptest.exe tv simon
Using seed: 1581266323      

Testing SymmetricCipher algorithm SIMON-64/ECB.
................
Testing SymmetricCipher algorithm SIMON-64/CBC.
..............
Testing SymmetricCipher algorithm SIMON-64/CTR.
..............
Testing SymmetricCipher algorithm SIMON-128/ECB.
........................
Testing SymmetricCipher algorithm SIMON-128/CBC.
.....................
Testing SymmetricCipher algorithm SIMON-128/CTR.
.....................
Tests complete. Total tests = 110. Failed tests = 0.

$ ./cryptest.exe tv speck
Using seed: 1581266328      

Testing SymmetricCipher algorithm SPECK-64/ECB.
................
Testing SymmetricCipher algorithm SPECK-64/CBC.
..............
Testing SymmetricCipher algorithm SPECK-64/CTR.
..............
Testing SymmetricCipher algorithm SPECK-128/ECB.
........................
Testing SymmetricCipher algorithm SPECK-128/CBC.
.....................
Testing SymmetricCipher algorithm SPECK-128/CTR.
.....................
Tests complete. Total tests = 110. Failed tests = 0.

@dercdev
Copy link
Author

dercdev commented Feb 9, 2020

I am familiar with the problem of endianness with speck. But in my opinion should my usage produce the exact same value shown in the wiki, but it does not.

@dercdev
Copy link
Author

dercdev commented Feb 17, 2020

any ideas?

@noloader
Copy link
Collaborator

noloader commented Jul 7, 2020

I think this was cleared under Issue #945

@noloader noloader closed this as completed Jul 7, 2020
@noloader noloader added the Bug label Dec 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants