ChaCha20.swift 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // ChaCha20.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 25/08/14.
  6. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. import Foundation
  9. public class ChaCha20 {
  10. let keySize = 32
  11. let nonceSize = 8
  12. let stateSize = 16
  13. let blockSize = 16 * 4
  14. public init() {
  15. }
  16. public func wordToByte(input:[UInt32] /* 64 */) -> [Byte]? /* 16 */ {
  17. if (input.count != stateSize) {
  18. return nil;
  19. }
  20. var x:[UInt32] = [UInt32]()
  21. for val in input[0...15] {
  22. x.append(val)
  23. }
  24. for (var i = 8; i > 0; i -= 2) {
  25. quarterround(&x[0], &x[4], &x[8], &x[12])
  26. quarterround(&x[1], &x[5], &x[9], &x[13])
  27. quarterround(&x[2], &x[6], &x[10], &x[14])
  28. quarterround(&x[3], &x[7], &x[11], &x[15])
  29. quarterround(&x[0], &x[5], &x[10], &x[15])
  30. quarterround(&x[1], &x[6], &x[11], &x[12])
  31. quarterround(&x[2], &x[7], &x[8], &x[13])
  32. quarterround(&x[3], &x[4], &x[9], &x[14])
  33. }
  34. for (idx,val) in enumerate(input[0...15]) {
  35. x[idx] = plus(x[idx],val)
  36. }
  37. var output:[Byte] = [Byte](count: 64, repeatedValue: 0)
  38. for (i,xval) in enumerate(x[0...15]) {
  39. let bytes = x[i].bytes()
  40. let start = (i * 4)
  41. for o in start..<(start + 4) {
  42. output[o] = bytes[o - start]
  43. }
  44. }
  45. return output;
  46. }
  47. private func UInt32To8Little(p:UInt32, _ v:UInt32) -> UInt8 {
  48. var tmp1 = (v >> 0) & 0xff | (v >> 8) & 0xff
  49. var tmp2 = (v >> 16) & 0xff | (v >> 24) & 0xff
  50. return UInt8(tmp1 | tmp2)
  51. }
  52. // rotate left
  53. private func rotate(v:UInt32, _ c:UInt32) -> UInt32 {
  54. return ((v << c) & 0xFFFFFFFF) | (v >> (32 - c))
  55. }
  56. private func u32v(x:UInt32) -> UInt32 {
  57. return x & 0xFFFFFFFF
  58. }
  59. private func plusone(v:UInt32) -> UInt32 {
  60. return plus(v, 1)
  61. }
  62. private func plus(v:UInt32, _ w:UInt32) -> UInt32 {
  63. return v &+ w
  64. }
  65. private func quarterround(inout a:UInt32, inout _ b:UInt32, inout _ c:UInt32, inout _ d:UInt32) {
  66. a = plus(a,b);
  67. d = rotate((d ^ a), 16)
  68. c = plus(c,d);
  69. b = rotate((b ^ c), 12);
  70. a = plus(a,b);
  71. d = rotate((d ^ a), 8);
  72. c = plus(c,d);
  73. b = rotate((b ^ c), 7);
  74. }
  75. }