Rabbit.swift 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. //
  2. // Rabbit.swift
  3. // CryptoSwift
  4. //
  5. // Created by Dima Kalachov on 12/11/15.
  6. // Copyright © 2015 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. final public class Rabbit {
  9. /// Size of IV in bytes
  10. public static let ivSize = 64 / 8
  11. /// Size of key in bytes
  12. public static let keySize = 128 / 8
  13. /// Size of block in bytes
  14. public static let blockSize = 128 / 8
  15. /// Key
  16. private let key: [UInt8]
  17. /// IV (optional)
  18. private let iv: [UInt8]?
  19. /// State variables
  20. private var x = [UInt32](count: 8, repeatedValue: 0)
  21. /// Counter variables
  22. private var c = [UInt32](count: 8, repeatedValue: 0)
  23. /// Counter carry
  24. private var p7: UInt32 = 0
  25. /// 'a' constants
  26. private var a: [UInt32] = [
  27. 0x4D34D34D,
  28. 0xD34D34D3,
  29. 0x34D34D34,
  30. 0x4D34D34D,
  31. 0xD34D34D3,
  32. 0x34D34D34,
  33. 0x4D34D34D,
  34. 0xD34D34D3,
  35. ]
  36. // MARK: - Initializers
  37. convenience public init?(key:[UInt8]) {
  38. self.init(key: key, iv: nil)
  39. }
  40. public init?(key:[UInt8], iv:[UInt8]?) {
  41. self.key = key
  42. self.iv = iv
  43. guard key.count == Rabbit.keySize && (iv == nil || iv!.count == Rabbit.ivSize) else {
  44. return nil
  45. }
  46. }
  47. // MARK: -
  48. private func setup() {
  49. p7 = 0
  50. // Key divided into 8 subkeys
  51. var k = [UInt32](count: 8, repeatedValue: 0)
  52. for j in 0 ..< 8 {
  53. k[j] = UInt32(key[Rabbit.blockSize - (2*j + 1)]) | (UInt32(key[Rabbit.blockSize - (2*j + 2)]) << 8)
  54. }
  55. // Initialize state and counter variables from subkeys
  56. for j in 0 ..< 8 {
  57. if j % 2 == 0 {
  58. x[j] = (k[(j+1) % 8] << 16) | k[j]
  59. c[j] = (k[(j+4) % 8] << 16) | k[(j+5) % 8]
  60. } else {
  61. x[j] = (k[(j+5) % 8] << 16) | k[(j+4) % 8]
  62. c[j] = (k[j] << 16) | k[(j+1) % 8]
  63. }
  64. }
  65. // Iterate system four times
  66. nextState()
  67. nextState()
  68. nextState()
  69. nextState()
  70. // Reinitialize counter variables
  71. for j in 0 ..< 8 {
  72. c[j] = c[j] ^ x[(j+4) % 8]
  73. }
  74. if let iv = iv {
  75. setupIV(iv)
  76. }
  77. }
  78. private func setupIV(iv: [UInt8]) {
  79. // 63...56 55...48 47...40 39...32 31...24 23...16 15...8 7...0 IV bits
  80. // 0 1 2 3 4 5 6 7 IV bytes in array
  81. let iv0: UInt32 = integerWithBytes([iv[4], iv[5], iv[6], iv[7]])
  82. let iv1: UInt32 = integerWithBytes([iv[0], iv[1], iv[4], iv[5]])
  83. let iv2: UInt32 = integerWithBytes([iv[0], iv[1], iv[2], iv[3]])
  84. let iv3: UInt32 = integerWithBytes([iv[2], iv[3], iv[6], iv[7]])
  85. // Modify the counter state as function of the IV
  86. c[0] = c[0] ^ iv0
  87. c[1] = c[1] ^ iv1
  88. c[2] = c[2] ^ iv2
  89. c[3] = c[3] ^ iv3
  90. c[4] = c[4] ^ iv0
  91. c[5] = c[5] ^ iv1
  92. c[6] = c[6] ^ iv2
  93. c[7] = c[7] ^ iv3
  94. // Iterate system four times
  95. nextState()
  96. nextState()
  97. nextState()
  98. nextState()
  99. }
  100. private func nextState() {
  101. // Before an iteration the counters are incremented
  102. var carry = p7
  103. for j in 0 ..< 8 {
  104. let prev = c[j]
  105. c[j] = prev &+ a[j] &+ carry
  106. carry = prev > c[j] ? 1 : 0 // detect overflow
  107. }
  108. p7 = carry // save last carry bit
  109. // Iteration of the system
  110. var newX = [UInt32](count: 8, repeatedValue: 0)
  111. newX[0] = g(0) &+ rotateLeft(g(7), 16) &+ rotateLeft(g(6), 16)
  112. newX[1] = g(1) &+ rotateLeft(g(0), 8) &+ g(7)
  113. newX[2] = g(2) &+ rotateLeft(g(1), 16) &+ rotateLeft(g(0), 16)
  114. newX[3] = g(3) &+ rotateLeft(g(2), 8) &+ g(1)
  115. newX[4] = g(4) &+ rotateLeft(g(3), 16) &+ rotateLeft(g(2), 16)
  116. newX[5] = g(5) &+ rotateLeft(g(4), 8) &+ g(3)
  117. newX[6] = g(6) &+ rotateLeft(g(5), 16) &+ rotateLeft(g(4), 16)
  118. newX[7] = g(7) &+ rotateLeft(g(6), 8) &+ g(5)
  119. x = newX
  120. }
  121. private func g(j: Int) -> UInt32 {
  122. let sum = x[j] &+ c[j]
  123. let square = UInt64(sum) * UInt64(sum)
  124. return UInt32(truncatingBitPattern: square ^ (square >> 32))
  125. }
  126. private func nextOutput() -> [UInt8] {
  127. nextState()
  128. var output16 = [UInt16](count: Rabbit.blockSize / 2, repeatedValue: 0)
  129. output16[7] = UInt16(truncatingBitPattern: x[0]) ^ UInt16(truncatingBitPattern: x[5] >> 16)
  130. output16[6] = UInt16(truncatingBitPattern: x[0] >> 16) ^ UInt16(truncatingBitPattern: x[3])
  131. output16[5] = UInt16(truncatingBitPattern: x[2]) ^ UInt16(truncatingBitPattern: x[7] >> 16)
  132. output16[4] = UInt16(truncatingBitPattern: x[2] >> 16) ^ UInt16(truncatingBitPattern: x[5])
  133. output16[3] = UInt16(truncatingBitPattern: x[4]) ^ UInt16(truncatingBitPattern: x[1] >> 16)
  134. output16[2] = UInt16(truncatingBitPattern: x[4] >> 16) ^ UInt16(truncatingBitPattern: x[7])
  135. output16[1] = UInt16(truncatingBitPattern: x[6]) ^ UInt16(truncatingBitPattern: x[3] >> 16)
  136. output16[0] = UInt16(truncatingBitPattern: x[6] >> 16) ^ UInt16(truncatingBitPattern: x[1])
  137. var output8 = [UInt8](count: Rabbit.blockSize, repeatedValue: 0)
  138. for j in 0 ..< output16.count {
  139. output8[j * 2] = UInt8(truncatingBitPattern: output16[j] >> 8)
  140. output8[j * 2 + 1] = UInt8(truncatingBitPattern: output16[j])
  141. }
  142. return output8
  143. }
  144. // MARK: - Public
  145. public func encrypt(bytes: [UInt8]) -> [UInt8] {
  146. setup()
  147. var result = [UInt8](count: bytes.count, repeatedValue: 0)
  148. var output = nextOutput()
  149. var byteIdx = 0
  150. var outputIdx = 0
  151. while byteIdx < bytes.count {
  152. if (outputIdx == Rabbit.blockSize) {
  153. output = nextOutput()
  154. outputIdx = 0
  155. }
  156. result[byteIdx] = bytes[byteIdx] ^ output[outputIdx]
  157. byteIdx += 1
  158. outputIdx += 1
  159. }
  160. return result
  161. }
  162. public func decrypt(bytes: [UInt8]) -> [UInt8] {
  163. return encrypt(bytes)
  164. }
  165. }
  166. // MARK: - Cipher
  167. extension Rabbit: Cipher {
  168. public func cipherEncrypt(bytes:[UInt8]) -> [UInt8] {
  169. return self.encrypt(bytes)
  170. }
  171. public func cipherDecrypt(bytes: [UInt8]) -> [UInt8] {
  172. return self.decrypt(bytes)
  173. }
  174. }