RC4.swift 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // RC4.swift
  3. // Swifter
  4. //
  5. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  6. //
  7. #if os(Linux)
  8. import Glibc
  9. #else
  10. import Foundation
  11. #endif
  12. public struct RC4 {
  13. //
  14. // Rivest Cipher 4
  15. //
  16. // https://en.wikipedia.org/wiki/RC4
  17. //
  18. // TODO Improvements:
  19. // - Use inout structs rather than copies.
  20. // - Avoid key schedule every encrypt(...) call.
  21. public static func encrypt(_ data: [UInt8], _ key : [UInt8]) -> [UInt8] {
  22. return generate(data, key)
  23. }
  24. public static func decrypt(_ data: [UInt8], _ key : [UInt8]) -> [UInt8] {
  25. return generate(data, key)
  26. }
  27. private static func generate(_ data: [UInt8], _ key : [UInt8]) -> [UInt8] {
  28. var S = keySchedule(key)
  29. var ouput = [UInt8]()
  30. var i = 0, j = 0
  31. for byte in data {
  32. i = ( i + 1 ) % 256
  33. j = ( j + Int(S[i]) ) % 256
  34. let tmp = S[i]
  35. S[i] = S[j]
  36. S[j] = tmp
  37. let t = (Int(S[i]) + Int(S[j])) % 256
  38. let k = S[t]
  39. ouput.append(k ^ byte)
  40. }
  41. return ouput
  42. }
  43. private static func keySchedule(_ key: [UInt8]) -> [UInt8] {
  44. var S = [UInt8](repeating: 0, count: 256)
  45. for i in 0..<S.count {
  46. S[i] = UInt8(i)
  47. }
  48. var j : Int = 0
  49. for i in 0..<S.count {
  50. j = ( j + Int(S[i]) + Int(key[i % key.count]) ) % 256
  51. let tmp = S[i]
  52. S[i] = S[j]
  53. S[j] = tmp
  54. }
  55. return S
  56. }
  57. }