1
0

RSA.swift 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //
  2. // RSA.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 RSA {
  13. //
  14. // RSA
  15. //
  16. // https://en.wikipedia.org/wiki/RSA_(cryptosystem)
  17. // TODO
  18. // - Switch to BigNum.
  19. public struct Config {
  20. public var n, e, d : Int
  21. }
  22. public static func encrypt(_ s: Int, _ config: Config) -> Int {
  23. return powmod(s, config.e, config.n);
  24. }
  25. public static func decrypt(_ c: Int, _ config: Config) -> Int {
  26. return powmod(c, config.d, config.n);
  27. }
  28. public static func config(_ p: Int, _ q: Int) -> Config {
  29. let n = p * q
  30. let phin = (p - 1) * (q - 1)
  31. let e = coprimes(phin)[1]
  32. let d = inverse(e, phin)
  33. return Config(n: n, e: e, d: d)
  34. }
  35. public static func inverse(_ a: Int, _ n: Int) -> Int {
  36. for i in 1..<n {
  37. if (a * i) % n == 1 {
  38. return i
  39. }
  40. }
  41. return -1
  42. }
  43. public static func gcd(_ a: Int, _ b: Int) -> Int {
  44. var r = b, pr = a
  45. while r > 0 {
  46. let t = r
  47. r = pr % r
  48. pr = t
  49. }
  50. return pr;
  51. }
  52. public static func coprimes(_ a: Int) -> [Int] {
  53. var r = [Int]()
  54. for i in 1..<a {
  55. if gcd(i, a) == 1 { r.append(i) }
  56. }
  57. return r
  58. }
  59. public static func powmod(_ a: Int, _ b: Int, _ n: Int) -> Int {
  60. let amod = a % n
  61. var r = 1
  62. for _ in 0..<b {
  63. r = (r * amod) % n
  64. }
  65. return r
  66. }
  67. public static func divisors(_ n: Int) -> [Int] {
  68. var r = [Int]()
  69. for i in 0...n {
  70. if n % i == 0 { r.append(i) }
  71. }
  72. return r
  73. }
  74. public static func factorization(_ n: Int) -> [Int] {
  75. var nn = n
  76. var r = [Int]()
  77. while nn > 1 {
  78. for d in 2...nn {
  79. if nn % d == 0 {
  80. r.append(d)
  81. nn = nn / d
  82. break
  83. }
  84. }
  85. }
  86. return r
  87. }
  88. public static func phi(_ n: Int) -> Int {
  89. var r = 1, p = 1
  90. factorization(n).forEach { f in
  91. r *= (f != p) ? (f - 1) : f
  92. p = f
  93. }
  94. return r
  95. }
  96. }