| 131 | } |
| 132 | |
| 133 | static void TestChaCha20(const std::string &hex_message, const std::string &hexkey, uint64_t nonce, uint64_t seek, const std::string& hexout) |
| 134 | { |
| 135 | std::vector<unsigned char> key = ParseHex(hexkey); |
| 136 | std::vector<unsigned char> m = ParseHex(hex_message); |
| 137 | ChaCha20 rng(key.data(), key.size()); |
| 138 | rng.SetIV(nonce); |
| 139 | rng.Seek(seek); |
| 140 | std::vector<unsigned char> out = ParseHex(hexout); |
| 141 | std::vector<unsigned char> outres; |
| 142 | outres.resize(out.size()); |
| 143 | assert(hex_message.empty() || m.size() == out.size()); |
| 144 | |
| 145 | // perform the ChaCha20 round(s), if message is provided it will output the encrypted ciphertext otherwise the keystream |
| 146 | if (!hex_message.empty()) { |
| 147 | rng.Crypt(m.data(), outres.data(), outres.size()); |
| 148 | } else { |
| 149 | rng.Keystream(outres.data(), outres.size()); |
| 150 | } |
| 151 | BOOST_CHECK(out == outres); |
| 152 | if (!hex_message.empty()) { |
| 153 | // Manually XOR with the keystream and compare the output |
| 154 | rng.SetIV(nonce); |
| 155 | rng.Seek(seek); |
| 156 | std::vector<unsigned char> only_keystream(outres.size()); |
| 157 | rng.Keystream(only_keystream.data(), only_keystream.size()); |
| 158 | for (size_t i = 0; i != m.size(); i++) { |
| 159 | outres[i] = m[i] ^ only_keystream[i]; |
| 160 | } |
| 161 | BOOST_CHECK(out == outres); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | static void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, const std::string& hextag) |
| 166 | { |