Rabbit.swift 6.6 KB

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