ChaCha20Tests.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // CipherChaCha20Tests.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 27/12/14.
  6. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. import XCTest
  9. import Foundation
  10. @testable import CryptoSwift
  11. final class ChaCha20Tests: XCTestCase {
  12. func testChaCha20() {
  13. let keys:[Array<UInt8>] = [
  14. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  15. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],
  16. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  17. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  18. [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F]
  19. ]
  20. let ivs:[Array<UInt8>] = [
  21. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  22. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  23. [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],
  24. [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
  25. [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07]
  26. ]
  27. let expectedHexes = [
  28. "76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669B2EE6586",
  29. "4540F05A9F1FB296D7736E7B208E3C96EB4FE1834688D2604F450952ED432D41BBE2A0B6EA7566D2A5D1E7E20D42AF2C53D792B1C43FEA817E9AD275AE546963",
  30. "DE9CBA7BF3D69EF5E786DC63973F653A0B49E015ADBFF7134FCB7DF137821031E85A050278A7084527214F73EFC7FA5B5277062EB7A0433E445F41E3",
  31. "EF3FDFD6C61578FBF5CF35BD3DD33B8009631634D21E42AC33960BD138E50D32111E4CAF237EE53CA8AD6426194A88545DDC497A0B466E7D6BBDB0041B2F586B",
  32. "F798A189F195E66982105FFB640BB7757F579DA31602FC93EC01AC56F85AC3C134A4547B733B46413042C9440049176905D3BE59EA1C53F15916155C2BE8241A38008B9A26BC35941E2444177C8ADE6689DE95264986D95889FB60E84629C9BD9A5ACB1CC118BE563EB9B3A4A472F82E09A7E778492B562EF7130E88DFE031C79DB9D4F7C7A899151B9A475032B63FC385245FE054E3DD5A97A5F576FE064025D3CE042C566AB2C507B138DB853E3D6959660996546CC9C4A6EAFDC777C040D70EAF46F76DAD3979E5C5360C3317166A1C894C94A371876A94DF7628FE4EAAF2CCB27D5AAAE0AD7AD0F9D4B6AD3B54098746D4524D38407A6DEB3AB78FAB78C9"
  33. ]
  34. for idx in 0..<keys.count {
  35. let expectedHex = expectedHexes[idx]
  36. let message = Array<UInt8>(repeating: 0, count: (expectedHex.characters.count / 2))
  37. do {
  38. let encrypted = try ChaCha20(key: keys[idx], iv: ivs[idx]).encrypt(message)
  39. let decrypted = try ChaCha20(key: keys[idx], iv: ivs[idx]).decrypt(encrypted)
  40. XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
  41. // check extension
  42. let messageData = Data(bytes: message);
  43. let encrypted2 = try messageData.encrypt(cipher: ChaCha20(key: keys[idx], iv: ivs[idx]))
  44. XCTAssertNotNil(encrypted2, "")
  45. XCTAssertEqual(Data(bytes: encrypted), encrypted2, "ChaCha20 extension failed")
  46. } catch CipherError.encrypt {
  47. XCTAssert(false, "Encryption failed")
  48. } catch CipherError.decrypt {
  49. XCTAssert(false, "Decryption failed")
  50. } catch {
  51. XCTAssert(false, "Failed")
  52. }
  53. }
  54. }
  55. func testVector1Py() {
  56. let key:Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
  57. let iv:Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
  58. let expected:Array<UInt8> = [0x76,0xB8,0xE0,0xAD,0xA0,0xF1,0x3D,0x90,0x40,0x5D,0x6A,0xE5,0x53,0x86,0xBD,0x28,0xBD,0xD2,0x19,0xB8,0xA0,0x8D,0xED,0x1A,0xA8,0x36,0xEF,0xCC,0x8B,0x77,0x0D,0xC7,0xDA,0x41,0x59,0x7C,0x51,0x57,0x48,0x8D,0x77,0x24,0xE0,0x3F,0xB8,0xD8,0x4A,0x37,0x6A,0x43,0xB8,0xF4,0x15,0x18,0xA1,0x1C,0xC3,0x87,0xB6,0x69,0xB2,0xEE,0x65,0x86]
  59. let message = Array<UInt8>(repeating: 0, count: expected.count)
  60. do {
  61. let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message)
  62. XCTAssertEqual(encrypted, expected, "Ciphertext failed")
  63. } catch {
  64. XCTFail()
  65. }
  66. }
  67. func testChaCha20EncryptPartial() {
  68. let key:Array<UInt8> = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
  69. let iv:Array<UInt8> = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
  70. let plaintext:Array<UInt8> = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
  71. do {
  72. let cipher = try ChaCha20(key: key, iv:iv)
  73. var ciphertext = Array<UInt8>()
  74. var encryptor = cipher.makeEncryptor()
  75. ciphertext += try encryptor.update(withBytes: Array(plaintext[0..<8]))
  76. ciphertext += try encryptor.update(withBytes: Array(plaintext[8..<16]))
  77. ciphertext += try encryptor.update(withBytes: Array(plaintext[16..<32]))
  78. ciphertext += try encryptor.finish()
  79. XCTAssertEqual(try cipher.encrypt(plaintext), ciphertext, "encryption failed")
  80. } catch {
  81. XCTFail()
  82. }
  83. }
  84. func testChaCha20Performance() {
  85. #if !CI
  86. let key:Array<UInt8> = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
  87. let iv:Array<UInt8> = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
  88. let message = Array<UInt8>(repeating: 7, count: (1024 * 1024) * 1)
  89. measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, for: { () -> Void in
  90. do {
  91. let _ = try ChaCha20(key: key, iv: iv).encrypt(message)
  92. } catch {
  93. XCTFail()
  94. }
  95. self.stopMeasuring()
  96. })
  97. #endif
  98. }
  99. static let allTests = [
  100. ("testChaCha20", testChaCha20),
  101. ("testVector1Py", testVector1Py),
  102. ("testChaCha20EncryptPartial", testChaCha20EncryptPartial),
  103. ("testChaCha20Performance", testChaCha20Performance)
  104. ]
  105. }