Last active
April 8, 2022 17:37
-
-
Save jmcd/b9a212df5dfa88b6d8dcb52c51b6be6b to your computer and use it in GitHub Desktop.
Diffie–Hellman key exchange simple implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
protocol Cipher { | |
func encrypt(message: String, secret: Int) -> String | |
func decrypt(message: String, secret: Int) -> String | |
} | |
struct XOR: Cipher { | |
private func impl(message: String, secret: Int) -> String? { | |
return message.unicodeScalars.map { UnicodeScalar(Int($0.value) ^ secret) }.flatMap{ $0 }.reduce("") { $0 + String($1) } | |
} | |
func encrypt(message: String, secret: Int) -> String { return impl(message: message, secret: secret)! } | |
func decrypt(message: String, secret: Int) -> String { return impl(message: message, secret: secret)! } | |
} | |
protocol Exchange { | |
func sharedBaseForInsecureTransmission(secret: Int) -> Int | |
func sharedSecretByMixing(receivedSharedBase: Int, with secret: Int) -> Int | |
} | |
struct MultiplicativeGroupOfIntegersModulo: Exchange { | |
private let modulus: Int | |
private let base: Int | |
init(modulus: Int, base: Int) { | |
self.modulus = modulus | |
self.base = base | |
} | |
func sharedBaseForInsecureTransmission(secret: Int) -> Int { | |
return powMod(radix: base, power: secret) | |
} | |
func sharedSecretByMixing(receivedSharedBase: Int, with secret: Int) -> Int { | |
return powMod(radix: receivedSharedBase, power: secret) | |
} | |
private func powMod(radix: Int, power: Int) -> Int { | |
return Int(pow(Double(radix), Double(power))) % modulus | |
} | |
} | |
let exchange: Exchange = MultiplicativeGroupOfIntegersModulo(modulus: 23, base: 5) | |
let cipher: Cipher = XOR() | |
class Person { | |
let name: String | |
private let secret: Int | |
private var contacts = [(Person, sharedSecret: Int)]() | |
init(name: String, secret: Int) { | |
self.name = name | |
self.secret = secret | |
} | |
private func establishSharedSecret(with other: Person) { | |
let sharedBase = exchange.sharedBaseForInsecureTransmission(secret: secret) | |
other.accept(sharedBase: sharedBase, from: self) | |
} | |
private func accept(sharedBase: Int, from other: Person) { | |
let sharedSecret = exchange.sharedSecretByMixing(receivedSharedBase: sharedBase, with: secret) | |
contacts.append((other, sharedSecret)) | |
} | |
static func establishSharedSecret(_ p0: Person, _ p1: Person) { | |
p0.establishSharedSecret(with: p1) | |
p1.establishSharedSecret(with: p0) | |
} | |
private func sharedSecret(for contact: Person) -> Int? { | |
guard let sharedSecret = (contacts.first { $0.0 === contact })?.sharedSecret else { return nil } | |
return sharedSecret | |
} | |
func send(message plaintext: String, to contact: Person) { | |
guard let sharedSecret = sharedSecret(for: contact) else { return } | |
let ciphertext = cipher.encrypt(message: plaintext, secret: sharedSecret) | |
print("\(name) encrypted '\(plaintext)' to '\(ciphertext)'") | |
contact.recieve(ciphertext: ciphertext, from: self) | |
} | |
private func recieve(ciphertext: String, from contact: Person) { | |
guard let sharedSecret = sharedSecret(for: contact) else { return } | |
let plaintext = cipher.encrypt(message: ciphertext, secret: sharedSecret) | |
print("\(name) decrypted '\(ciphertext)' to '\(plaintext)'") | |
} | |
} | |
let alice = Person(name: "Alice", secret: 6) | |
let bob = Person(name: "Bob", secret: 15) | |
Person.establishSharedSecret(alice, bob) | |
alice.send(message: "Hello!", to: bob) | |
bob.send(message: "Hi Alice", to: alice) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Alice encrypted 'Hello!' to 'Jgnnm#' | |
Bob decrypted 'Jgnnm#' to 'Hello!' | |
Bob encrypted 'Hi Alice' to 'Jk"Cnkag' | |
Alice decrypted 'Jk"Cnkag' to 'Hi Alice' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/raoarafat/DeffieHelmanKeyExchange-Swift
Please check this out complete example.