mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			50 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Swift
		
	
		
		
			
		
	
	
			50 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Swift
		
	
| 
								 
											5 years ago
										 
									 | 
							
								import CryptoSwift
							 | 
						||
| 
								 | 
							
								import Curve25519Kit
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public final class DiffieHellman : NSObject {
							 | 
						||
| 
								 | 
							
								    public static let ivSize: UInt = 16
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public enum Error : LocalizedError {
							 | 
						||
| 
								 | 
							
								        case decryptionFailed
							 | 
						||
| 
								 | 
							
								        case sharedSecretGenerationFailed
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public var errorDescription: String {
							 | 
						||
| 
								 | 
							
								            switch self {
							 | 
						||
| 
								 | 
							
								            case .decryptionFailed: return "Couldn't decrypt data"
							 | 
						||
| 
								 | 
							
								            case .sharedSecretGenerationFailed: return "Couldn't generate a shared secret."
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    private override init() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public static func encrypt(_ plaintext: Data, using symmetricKey: Data) throws -> Data {
							 | 
						||
| 
								 | 
							
								        let iv = Data.getSecureRandomData(ofSize: ivSize)!
							 | 
						||
| 
								 | 
							
								        let cbc = CBC(iv: iv.bytes)
							 | 
						||
| 
								 | 
							
								        let aes = try AES(key: symmetricKey.bytes, blockMode: cbc)
							 | 
						||
| 
								 | 
							
								        let ciphertext = try aes.encrypt(plaintext.bytes)
							 | 
						||
| 
								 | 
							
								        let ivAndCiphertext = iv.bytes + ciphertext
							 | 
						||
| 
								 | 
							
								        return Data(ivAndCiphertext)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public static func encrypt(_ plaintext: Data, publicKey: Data, privateKey: Data) throws -> Data {
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								        guard let symmetricKey = try? Curve25519.generateSharedSecret(fromPublicKey: publicKey, privateKey: privateKey) else { throw Error.sharedSecretGenerationFailed }
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								        return try encrypt(plaintext, using: symmetricKey)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public static func decrypt(_ ivAndCiphertext: Data, using symmetricKey: Data) throws -> Data {
							 | 
						||
| 
								 | 
							
								        guard ivAndCiphertext.count >= ivSize else { throw Error.decryptionFailed }
							 | 
						||
| 
								 | 
							
								        let iv = ivAndCiphertext[..<ivSize]
							 | 
						||
| 
								 | 
							
								        let ciphertext = ivAndCiphertext[ivSize...]
							 | 
						||
| 
								 | 
							
								        let cbc = CBC(iv: iv.bytes)
							 | 
						||
| 
								 | 
							
								        let aes = try AES(key: symmetricKey.bytes, blockMode: cbc)
							 | 
						||
| 
								 | 
							
								        let plaintext = try aes.decrypt(ciphertext.bytes)
							 | 
						||
| 
								 | 
							
								        return Data(plaintext)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public static func decrypt(_ ivAndCiphertext: Data, publicKey: Data, privateKey: Data) throws -> Data {
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								        guard let symmetricKey = try? Curve25519.generateSharedSecret(fromPublicKey: publicKey, privateKey: privateKey) else { throw Error.sharedSecretGenerationFailed }
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								        return try decrypt(ivAndCiphertext, using: symmetricKey)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |