pが素数であり、2p+1=qも素数である場合、qを安全素数(safe prime)と呼ぶ。
安全という名前は暗号理論に由来する。
iOSでRSAを使いメッセージを暗号化してみる(SwiftyRSA)
iOSでRSAを使ってメッセージを暗号化してみます。
SwiftRSA
https://github.com/TakeScoop/SwiftyRSA
というライブラリを利用します。
RSAの実装は、AppleのSecurity.Frameworkが利用されています。
macOS版はサポートされていないようです。
サンプルiOSアプリを作り、CocoaPodを使ってフレームワークをリンクします。
pod 'SwiftyRSA'
opensslコマンドを使って、RSAの鍵ペアを作ります。
$ openssl genrsa 2048 > private-key.pem ...+++ ......+++ e is 65537 (0x10001) $ openssl rsa -in private-key.pem -pubout -out public-key.pem writing RSA key
できた2つのファイルはこのようになっています。
$ cat private-key.pem -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAvwLN8/7d+VIDVqZ3T1PFf3fohfhzJkN9ZhGdk+lii4YQ/ywG Wwf2pp5786+ZIxCseUUcWRn0flk44rCRwdxbkPlb+s8dWnLcyggMz71DbcdGxGhA mCMP8XlD/m2Oa7UMyHGnL/JXf3gCSrAmeP7qMWviSw2MElmkbQxWJ86kY8Lq7Pua LJJ83RdNHiAN5+gRQPAWZxVQAXggae7XUFAwYfmtic09JLu5oHmW/1ha82kXReK7 tczDCl6B++3I2GsIV3zHo6STENvggTXQtsyej7Lo+oQekTXpXfalRql5L5WTRYU1 I8H/zNy/GFQXQSdzvwQ2k1E5kbol+nUMjrrzaQIDAQABAoIBAQCjVxedvmY9rXdz YtkGOiHatkReRC7cGryiSxAQi3Sc0aG5RAGPWMkAhOiEY7Y1uS10argqLbrZTR0L JWkPeYvH9qVEXlbAoRbToXyrLTL7Ln0Cug/6yYj5uvR9H1y6GFH9GsuYgcl3FL4I 9od/0qWca6BRBB2zF3s3UWRfmCMVtv3LnAarO1v5d8GKz4220/FHueEHoHaQCE9j PRWEbiTlzrO+jTY7hr2xpC2sUz2TiOeQijD4eVOZsrup0r4Wxn4+hS02yvD5/Zqu 6KP5xW8eCvQu0DRHw0E/7pv89d17LX1l4lXvb3cqDuX4rvM4kwx+HjFodKeelMm0 8xfiU1FtAoGBAPa9Yqmdt2599XhOXY7croXW4Eq4StHkO0x2GNejQzp62vwgH8Lf 8uxad4ZFTQiMtiu0ar/0awIxd6A8Ov8SivB5pdGkCOiovl2xn8SdxEsMQon4ydZD BbKdnDdMmXpdZhU9mOnftg5iDKVv3r+JvuX/mzBalUN/J3NsJ0E7AonzAoGBAMYt /YYm1bl0alL77THd+NI7d9qfRFYkg8+/W4Uqo1XD8t//9457oawKQ8quEB5fonv+ pvnR8/HY5VKQlmrO3e/kgvHCc7hhWiNOmH8GWQ0QlTOEQkFcwe9gc0w3ntY69JrH nMtzrK5NjhkjoyVHlaAExDTs90CjYicijoI9BqgzAoGBAJlC4foBoWLckpD7/Fk0 8qLn6cH/31morry7zoqDOsskbMmXGqNtf/MX7o5UlZjt7moPUw+QvrdKCshZITw3 RF5C8aDahz4dMsH4BwmWBcun/dy90IFqeCuOgu5Ggj7jrPkcndMHxooAlWJdrrrC 0PUEZF0Qpw6Z+ONVFr0J7nXJAoGAFu41WnNd4WJ99vIdZNq5MqIc4RfykUESW1RZ 45OmaIMOtCpq23qkn0Jky6vOQ6VvKIezjE5luoMNLbt7HAqplVtMZ2rHdvsUsecj L/dtEFzt1pMkE2oHKopvbM82urUBnnMgSk4tGdHxcik0dFjPED/c7/7HMRx2e+68 rIchIQ8CgYA+0wBpkDIpkK2EEw6GVRHAtJ8amMEpsG2sCE8TkHdhL5Oi0jcLpcoN R4JPWLDrGEwHXe38b8jfgdl2oe0eQS3mnDFSj82hIjJEgkZDpjVq9M2m8hBLgbV7 eBsJr5dJq6OvULI7clWaRBpFaekUtoxzeozCwK4xEcYKfDdce4aOdA== -----END RSA PRIVATE KEY----- $ cat public-key.pem -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvwLN8/7d+VIDVqZ3T1PF f3fohfhzJkN9ZhGdk+lii4YQ/ywGWwf2pp5786+ZIxCseUUcWRn0flk44rCRwdxb kPlb+s8dWnLcyggMz71DbcdGxGhAmCMP8XlD/m2Oa7UMyHGnL/JXf3gCSrAmeP7q MWviSw2MElmkbQxWJ86kY8Lq7PuaLJJ83RdNHiAN5+gRQPAWZxVQAXggae7XUFAw Yfmtic09JLu5oHmW/1ha82kXReK7tczDCl6B++3I2GsIV3zHo6STENvggTXQtsye j7Lo+oQekTXpXfalRql5L5WTRYU1I8H/zNy/GFQXQSdzvwQ2k1E5kbol+nUMjrrz aQIDAQAB -----END PUBLIC KEY-----
opensslコマンドで暗号化を行ったメッセージをiOSアプリで復号できるかやってみます。
$ echo -n "hogefuga" > msg.bin $ openssl rsautl -encrypt -pubin -inkey public-key.pem -in msg.bin -out encrypted_msg.bin
作成されたencrypted_msg.binファイルとprivate-key.pemファイルをiOSプロジェクトに追加します。
import SwiftyRSA do { let privatekey:PrivateKey = try PrivateKey(pemNamed: "private-key") let url:URL = Bundle.main.url(forResource: "encrypted_msg", withExtension: "bin")! let data:Data = try Data(contentsOf: url) let encrypted:EncryptedMessage = EncryptedMessage(data: data) let decrypted:ClearMessage = try encrypted.decrypted(with: privatekey, padding: .PKCS1) print("\(try decrypted.string(encoding: .utf8))") } catch { fatalError() }
実行結果
hogefuga
swift3 IntegerArithmaticプロトコル
IntegerArithmeticプロトコルを実装するには、以下8つの関数を定義する必要がある。 最初の2つはComparableである。
static func ==(lhs: M, rhs: M) -> Bool static func <(lhs: M, rhs: M) -> Bool static func addWithOverflow(_ lhs: M, _ rhs: M) -> (M, overflow: Bool) static func subtractWithOverflow(_ lhs: M, _ rhs: M) -> (M, overflow: Bool) static func multiplyWithOverflow(_ lhs: M, _ rhs: M) -> (M, overflow: Bool) static func divideWithOverflow(_ lhs: M, _ rhs: M) -> (M, overflow: Bool) static func remainderWithOverflow(_ lhs: M, _ rhs: M) -> (M, overflow: Bool) func toIntMax() -> IntMax
最後の一つはswiftの最大Int(=UInt64)へ変換するものである。 このプロトコルを実装すると以下の5つの演算や関連する演算ができるようになる。
public static func +(lhs: Self, rhs: Self) -> Self public static func -(lhs: Self, rhs: Self) -> Self public static func *(lhs: Self, rhs: Self) -> Self public static func /(lhs: Self, rhs: Self) -> Self public static func %(lhs: Self, rhs: Self) -> Self
このプロトコルを用いると、通常とは異なる演算規則を持つ整数を作ることができる。 複素整数や桁数が無制限の整数などを自作することができる。
swift3 Comparableプロトロル
Comparableプロトコルを作るには、
static func <(lhs: Even, rhs: Even) -> Bool
static func ==(lhs: Even, rhs: Even) -> Bool
の2つを実装すればよい。
struct M : Comparable { var val:Int static func <(lhs: M, rhs: M) -> Bool { return lhs.val < rhs.val } static func ==(lhs: M, rhs: M) -> Bool { return lhs.val == rhs.val } } let r1 = M(val:1) let p1 = M(val:2) assert(r1 < p1) let r2 = M(val:1) assert(r1 == r2)
swift3 Collectionプロトコル
Collectionプロトコルを作るには、
startIndexプロパティ,endIndexプロパティ,subscript,index(after:)
の4つを実装する必要がある。
Collection - Swift Standard Library | Apple Developer Documentation
ここでは奇数を返すコレクションOddを作ってみた。
struct Odd : Collection { var startIndex: Int var endIndex: Int subscript(i: Int) -> Int { return 1 + 2 * i } func index(after: Int) -> Int { return after + 1 } } let odd = Odd(startIndex:1, endIndex:4) for i in odd { print("\(i)") }
3 5 7