VectorTest.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace Tests\RNCryptor;
  3. use PHPUnit\Framework\TestCase;
  4. use RNCryptor\RNCryptor\Cryptor;
  5. use RNCryptor\RNCryptor\Encryptor;
  6. class VectorBase extends TestCase
  7. {
  8. /**
  9. * Base directory for the test vector files,
  10. * relative to __DIR__
  11. */
  12. const PARALLEL_VECTOR_DIR = '/../../../spec/vectors/CURRENT';
  13. const SUBPACKAGE_VECTOR_DIR = '/../../vendor/rncryptor/spec/vectors/CURRENT';
  14. public function testKdfVectorAllFieldsEmptyOrZero()
  15. {
  16. $vector = $this->getVectors('kdf')[0];
  17. $cryptor = new Cryptor;
  18. $key = $cryptor->generateKey(
  19. $this->prettyHexToBin($vector['salt_hex']),
  20. $vector['password'],
  21. $vector['version']
  22. );
  23. $this->assertEquals($this->prettyHexToBin($vector['key_hex']), $key);
  24. }
  25. public function testKdfVectorOneByte()
  26. {
  27. $vector = $this->getVectors('kdf')[1];
  28. $cryptor = new Cryptor;
  29. $key = $cryptor->generateKey(
  30. $this->prettyHexToBin($vector['salt_hex']),
  31. $vector['password'],
  32. $vector['version']
  33. );
  34. $this->assertEquals($this->prettyHexToBin($vector['key_hex']), $key);
  35. }
  36. public function testKdfVectorExactlyOneBlock()
  37. {
  38. $vector = $this->getVectors('kdf')[2];
  39. $cryptor = new Cryptor;
  40. $key = $cryptor->generateKey(
  41. $this->prettyHexToBin($vector['salt_hex']),
  42. $vector['password'],
  43. $vector['version']
  44. );
  45. $this->assertEquals($this->prettyHexToBin($vector['key_hex']), $key);
  46. }
  47. public function testKdfVectorMoreThanOneBlock()
  48. {
  49. $vector = $this->getVectors('kdf')[3];
  50. $cryptor = new Cryptor;
  51. $key = $cryptor->generateKey(
  52. $this->prettyHexToBin($vector['salt_hex']),
  53. $vector['password'],
  54. $vector['version']
  55. );
  56. $this->assertEquals($this->prettyHexToBin($vector['key_hex']), $key);
  57. }
  58. public function testKeyVectorAllFieldsEmptyOrZero()
  59. {
  60. $vector = $this->getVectors('key')[0];
  61. $encryptor = new Encryptor;
  62. $encryptedB64 = $encryptor->encryptWithArbitraryKeys(
  63. $this->prettyHexToBin($vector['plaintext_hex']),
  64. $this->prettyHexToBin($vector['enc_key_hex']),
  65. $this->prettyHexToBin($vector['hmac_key_hex']),
  66. $this->prettyHexToBin($vector['iv_hex']),
  67. $vector['version']
  68. );
  69. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  70. }
  71. public function testKeyVectorOneByte()
  72. {
  73. $vector = $this->getVectors('key')[1];
  74. $encryptor = new Encryptor;
  75. $encryptedB64 = $encryptor->encryptWithArbitraryKeys(
  76. $this->prettyHexToBin($vector['plaintext_hex']),
  77. $this->prettyHexToBin($vector['enc_key_hex']),
  78. $this->prettyHexToBin($vector['hmac_key_hex']),
  79. $this->prettyHexToBin($vector['iv_hex']),
  80. $vector['version']
  81. );
  82. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  83. }
  84. public function testKeyVectorExactlyOneBlock()
  85. {
  86. $vector = $this->getVectors('key')[2];
  87. $encryptor = new Encryptor;
  88. $encryptedB64 = $encryptor->encryptWithArbitraryKeys(
  89. $this->prettyHexToBin($vector['plaintext_hex']),
  90. $this->prettyHexToBin($vector['enc_key_hex']),
  91. $this->prettyHexToBin($vector['hmac_key_hex']),
  92. $this->prettyHexToBin($vector['iv_hex']),
  93. $vector['version']
  94. );
  95. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  96. }
  97. public function testKeyVectorMoreThanOneBlock()
  98. {
  99. $vector = $this->getVectors('key')[3];
  100. $encryptor = new Encryptor;
  101. $encryptedB64 = $encryptor->encryptWithArbitraryKeys(
  102. $this->prettyHexToBin($vector['plaintext_hex']),
  103. $this->prettyHexToBin($vector['enc_key_hex']),
  104. $this->prettyHexToBin($vector['hmac_key_hex']),
  105. $this->prettyHexToBin($vector['iv_hex']),
  106. $vector['version']
  107. );
  108. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  109. }
  110. public function testPasswordVectorAllFieldsEmptyOrZero()
  111. {
  112. $vector = $this->getVectors('password')[0];
  113. $encryptor = new Encryptor;
  114. $encryptedB64 = $encryptor->encryptWithArbitrarySalts(
  115. $this->prettyHexToBin($vector['plaintext_hex']),
  116. $vector['password'],
  117. $this->prettyHexToBin($vector['enc_salt_hex']),
  118. $this->prettyHexToBin($vector['hmac_salt_hex']),
  119. $this->prettyHexToBin($vector['iv_hex']),
  120. $vector['version']
  121. );
  122. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  123. }
  124. public function testPasswordVectorOneByte()
  125. {
  126. $vector = $this->getVectors('password')[1];
  127. $encryptor = new Encryptor;
  128. $encryptedB64 = $encryptor->encryptWithArbitrarySalts(
  129. $this->prettyHexToBin($vector['plaintext_hex']),
  130. $vector['password'],
  131. $this->prettyHexToBin($vector['enc_salt_hex']),
  132. $this->prettyHexToBin($vector['hmac_salt_hex']),
  133. $this->prettyHexToBin($vector['iv_hex']),
  134. $vector['version']
  135. );
  136. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  137. }
  138. public function testPasswordVectorExactlyOneBlock()
  139. {
  140. $vector = $this->getVectors('password')[2];
  141. $encryptor = new Encryptor;
  142. $encryptedB64 = $encryptor->encryptWithArbitrarySalts(
  143. $this->prettyHexToBin($vector['plaintext_hex']),
  144. $vector['password'],
  145. $this->prettyHexToBin($vector['enc_salt_hex']),
  146. $this->prettyHexToBin($vector['hmac_salt_hex']),
  147. $this->prettyHexToBin($vector['iv_hex']),
  148. $vector['version']
  149. );
  150. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  151. }
  152. public function testPasswordVectorMoreThanOneBlock()
  153. {
  154. $vector = $this->getVectors('password')[3];
  155. $encryptor = new Encryptor;
  156. $encryptedB64 = $encryptor->encryptWithArbitrarySalts(
  157. $this->prettyHexToBin($vector['plaintext_hex']),
  158. $vector['password'],
  159. $this->prettyHexToBin($vector['enc_salt_hex']),
  160. $this->prettyHexToBin($vector['hmac_salt_hex']),
  161. $this->prettyHexToBin($vector['iv_hex']),
  162. $vector['version']
  163. );
  164. $this->assertEquals($vector['ciphertext_hex'], $this->binToPrettyHex(base64_decode($encryptedB64)));
  165. }
  166. private function prettyHexToBin($data)
  167. {
  168. return hex2bin(preg_replace("/[^a-z0-9]/i", '', $data));
  169. }
  170. private function binToPrettyHex($data)
  171. {
  172. $hex = bin2hex($data);
  173. $prettyHex = '';
  174. foreach (str_split($hex, 8) as $index => $part) {
  175. $prettyHex .= ($index != 0 ? ' ' : '') . $part;
  176. }
  177. return $prettyHex;
  178. }
  179. private function getVectors($filename)
  180. {
  181. $absolutePath = __DIR__ . '/' . self::PARALLEL_VECTOR_DIR . '/' . $filename;
  182. if (!file_exists($absolutePath)) {
  183. $absolutePath = __DIR__ . '/' . self::SUBPACKAGE_VECTOR_DIR . '/' . $filename;
  184. if (!file_exists($absolutePath)) {
  185. throw new \Exception('No such file: ' . $absolutePath);
  186. }
  187. }
  188. $index = -1;
  189. $tests = array();
  190. $fd = fopen($absolutePath, 'r');
  191. while (!feof($fd)) {
  192. $line = trim(fgets($fd));
  193. if (preg_match("/^\s*(\w+)\s*\:\s*(.*)/", $line, $match)) {
  194. $key = strtolower($match[1]);
  195. $value = trim($match[2]);
  196. if ($key == 'title') {
  197. $index++;
  198. }
  199. $tests[$index][$key] = $value;
  200. }
  201. }
  202. fclose($fd);
  203. return $tests;
  204. }
  205. }