Rabbit.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // CryptoSwift
  3. //
  4. // Copyright (C) 2014-2021 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
  5. // This software is provided 'as-is', without any express or implied warranty.
  6. //
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  10. //
  11. // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
  12. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  13. // - This notice may not be removed or altered from any source or binary distribution.
  14. //
  15. public final class Rabbit: BlockCipher {
  16. public enum Error: Swift.Error {
  17. case invalidKeyOrInitializationVector
  18. }
  19. /// Size of IV in bytes
  20. public static let ivSize = 64 / 8
  21. /// Size of key in bytes
  22. public static let keySize = 128 / 8
  23. /// Size of block in bytes
  24. public static let blockSize = 128 / 8
  25. public var keySize: Int {
  26. self.key.count
  27. }
  28. /// Key
  29. private let key: Key
  30. /// IV (optional)
  31. private let iv: Array<UInt8>?
  32. /// State variables
  33. private var x = Array<UInt32>(repeating: 0, count: 8)
  34. /// Counter variables
  35. private var c = Array<UInt32>(repeating: 0, count: 8)
  36. /// Counter carry
  37. private var p7: UInt32 = 0
  38. /// 'a' constants
  39. private var a: Array<UInt32> = [
  40. 0x4d34d34d,
  41. 0xd34d34d3,
  42. 0x34d34d34,
  43. 0x4d34d34d,
  44. 0xd34d34d3,
  45. 0x34d34d34,
  46. 0x4d34d34d,
  47. 0xd34d34d3
  48. ]
  49. // MARK: - Initializers
  50. public convenience init(key: Array<UInt8>) throws {
  51. try self.init(key: key, iv: nil)
  52. }
  53. public init(key: Array<UInt8>, iv: Array<UInt8>?) throws {
  54. self.key = Key(bytes: key)
  55. self.iv = iv
  56. guard key.count == Rabbit.keySize && (iv == nil || iv!.count == Rabbit.ivSize) else {
  57. throw Error.invalidKeyOrInitializationVector
  58. }
  59. }
  60. // MARK: -
  61. fileprivate func setup() {
  62. self.p7 = 0
  63. // Key divided into 8 subkeys
  64. let k = Array<UInt32>(unsafeUninitializedCapacity: 8) { buf, count in
  65. for j in 0..<8 {
  66. buf[j] = UInt32(self.key[Rabbit.blockSize - (2 * j + 1)]) | (UInt32(self.key[Rabbit.blockSize - (2 * j + 2)]) << 8)
  67. }
  68. count = 8
  69. }
  70. // Initialize state and counter variables from subkeys
  71. for j in 0..<8 {
  72. if j % 2 == 0 {
  73. self.x[j] = (k[(j + 1) % 8] << 16) | k[j]
  74. self.c[j] = (k[(j + 4) % 8] << 16) | k[(j + 5) % 8]
  75. } else {
  76. self.x[j] = (k[(j + 5) % 8] << 16) | k[(j + 4) % 8]
  77. self.c[j] = (k[j] << 16) | k[(j + 1) % 8]
  78. }
  79. }
  80. // Iterate system four times
  81. self.nextState()
  82. self.nextState()
  83. self.nextState()
  84. self.nextState()
  85. // Reinitialize counter variables
  86. for j in 0..<8 {
  87. self.c[j] = self.c[j] ^ self.x[(j + 4) % 8]
  88. }
  89. if let iv = iv {
  90. self.setupIV(iv)
  91. }
  92. }
  93. private func setupIV(_ iv: Array<UInt8>) {
  94. // 63...56 55...48 47...40 39...32 31...24 23...16 15...8 7...0 IV bits
  95. // 0 1 2 3 4 5 6 7 IV bytes in array
  96. let iv0 = UInt32(bytes: [iv[4], iv[5], iv[6], iv[7]])
  97. let iv1 = UInt32(bytes: [iv[0], iv[1], iv[4], iv[5]])
  98. let iv2 = UInt32(bytes: [iv[0], iv[1], iv[2], iv[3]])
  99. let iv3 = UInt32(bytes: [iv[2], iv[3], iv[6], iv[7]])
  100. // Modify the counter state as function of the IV
  101. c[0] = self.c[0] ^ iv0
  102. self.c[1] = self.c[1] ^ iv1
  103. self.c[2] = self.c[2] ^ iv2
  104. self.c[3] = self.c[3] ^ iv3
  105. self.c[4] = self.c[4] ^ iv0
  106. self.c[5] = self.c[5] ^ iv1
  107. self.c[6] = self.c[6] ^ iv2
  108. self.c[7] = self.c[7] ^ iv3
  109. // Iterate system four times
  110. self.nextState()
  111. self.nextState()
  112. self.nextState()
  113. self.nextState()
  114. }
  115. private func nextState() {
  116. // Before an iteration the counters are incremented
  117. var carry = self.p7
  118. for j in 0..<8 {
  119. let prev = self.c[j]
  120. self.c[j] = prev &+ self.a[j] &+ carry
  121. carry = prev > self.c[j] ? 1 : 0 // detect overflow
  122. }
  123. self.p7 = carry // save last carry bit
  124. // Iteration of the system
  125. self.x = Array<UInt32>(unsafeUninitializedCapacity: 8) { newX, count in
  126. newX[0] = self.g(0) &+ rotateLeft(self.g(7), by: 16) &+ rotateLeft(self.g(6), by: 16)
  127. newX[1] = self.g(1) &+ rotateLeft(self.g(0), by: 8) &+ self.g(7)
  128. newX[2] = self.g(2) &+ rotateLeft(self.g(1), by: 16) &+ rotateLeft(self.g(0), by: 16)
  129. newX[3] = self.g(3) &+ rotateLeft(self.g(2), by: 8) &+ self.g(1)
  130. newX[4] = self.g(4) &+ rotateLeft(self.g(3), by: 16) &+ rotateLeft(self.g(2), by: 16)
  131. newX[5] = self.g(5) &+ rotateLeft(self.g(4), by: 8) &+ self.g(3)
  132. newX[6] = self.g(6) &+ rotateLeft(self.g(5), by: 16) &+ rotateLeft(self.g(4), by: 16)
  133. newX[7] = self.g(7) &+ rotateLeft(self.g(6), by: 8) &+ self.g(5)
  134. count = 8
  135. }
  136. }
  137. private func g(_ j: Int) -> UInt32 {
  138. let sum = self.x[j] &+ self.c[j]
  139. let square = UInt64(sum) * UInt64(sum)
  140. return UInt32(truncatingIfNeeded: square ^ (square >> 32))
  141. }
  142. fileprivate func nextOutput() -> Array<UInt8> {
  143. self.nextState()
  144. var output16 = Array<UInt16>(repeating: 0, count: Rabbit.blockSize / 2)
  145. output16[7] = UInt16(truncatingIfNeeded: self.x[0]) ^ UInt16(truncatingIfNeeded: self.x[5] >> 16)
  146. output16[6] = UInt16(truncatingIfNeeded: self.x[0] >> 16) ^ UInt16(truncatingIfNeeded: self.x[3])
  147. output16[5] = UInt16(truncatingIfNeeded: self.x[2]) ^ UInt16(truncatingIfNeeded: self.x[7] >> 16)
  148. output16[4] = UInt16(truncatingIfNeeded: self.x[2] >> 16) ^ UInt16(truncatingIfNeeded: self.x[5])
  149. output16[3] = UInt16(truncatingIfNeeded: self.x[4]) ^ UInt16(truncatingIfNeeded: self.x[1] >> 16)
  150. output16[2] = UInt16(truncatingIfNeeded: self.x[4] >> 16) ^ UInt16(truncatingIfNeeded: self.x[7])
  151. output16[1] = UInt16(truncatingIfNeeded: self.x[6]) ^ UInt16(truncatingIfNeeded: self.x[3] >> 16)
  152. output16[0] = UInt16(truncatingIfNeeded: self.x[6] >> 16) ^ UInt16(truncatingIfNeeded: self.x[1])
  153. var output8 = Array<UInt8>(repeating: 0, count: Rabbit.blockSize)
  154. for j in 0..<output16.count {
  155. output8[j * 2] = UInt8(truncatingIfNeeded: output16[j] >> 8)
  156. output8[j * 2 + 1] = UInt8(truncatingIfNeeded: output16[j])
  157. }
  158. return output8
  159. }
  160. }
  161. // MARK: Cipher
  162. extension Rabbit: Cipher {
  163. public func encrypt(_ bytes: ArraySlice<UInt8>) throws -> Array<UInt8> {
  164. self.setup()
  165. return Array<UInt8>(unsafeUninitializedCapacity: bytes.count) { result, count in
  166. var output = self.nextOutput()
  167. var byteIdx = 0
  168. var outputIdx = 0
  169. while byteIdx < bytes.count {
  170. if outputIdx == Rabbit.blockSize {
  171. output = self.nextOutput()
  172. outputIdx = 0
  173. }
  174. result[byteIdx] = bytes[byteIdx] ^ output[outputIdx]
  175. byteIdx += 1
  176. outputIdx += 1
  177. }
  178. count = bytes.count
  179. }
  180. }
  181. public func decrypt(_ bytes: ArraySlice<UInt8>) throws -> Array<UInt8> {
  182. try self.encrypt(bytes)
  183. }
  184. }