SwiftChaChaPoly implements Authenticated Encryption with Associated Data as defined in [RFC-8439]. It is based on the ChaCha20 stream cipher and Poly1305 authentication.
dependencies: [
.package(url: "https://github.com/leif-ibsen/SwiftChaChaPoly", from: "2.0.0"),
]
import SwiftChaChaPoly
let key: Bytes = [
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f]
let nonce: Bytes = [
0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47]
let aad: Bytes = [
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7]
let text = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
var bytes = Bytes(text.utf8)
let chacha = try ChaChaPoly(key, nonce)
let tag = chacha.encrypt(&bytes, aad)
print(tag)
let ok = chacha.decrypt(&bytes, tag, aad)
print(ok && bytes == Bytes(text.utf8) ? "Ok" : "Fail")
Giving
[26, 225, 11, 89, 79, 9, 226, 106, 126, 144, 46, 203, 208, 96, 6, 145]
Ok
import CryptoKit
let msg = Bytes("Hi, there".utf8)
let aad = Bytes("The AAD".utf8)
let key = Bytes(repeating: 7, count: 32)
let nonce = Bytes(repeating: 1, count: 12)
let chacha = try ChaChaPoly(key, nonce)
var ct = msg
let tag = chacha.encrypt(&ct, aad)
// ct contains the ciphertext
let ckKey = CryptoKit.SymmetricKey(data: key)
let ckNonce = try CryptoKit.ChaChaPoly.Nonce(data: nonce)
let sealedBox = try CryptoKit.ChaChaPoly.SealedBox(nonce: ckNonce, ciphertext: ct, tag: tag)
let pt = try CryptoKit.ChaChaPoly.open(sealedBox, using: ckKey, authenticating: aad)
print(String(bytes: pt, encoding: .utf8)!)
giving:
Hi, there
import CryptoKit
let msg = Bytes("Hi, there".utf8)
let aad = Bytes("The AAD".utf8)
let ckKey = CryptoKit.SymmetricKey(size: .bits256)
let sealedBox = try CryptoKit.ChaChaPoly.seal(msg, using: ckKey, authenticating: aad)
let key = ckKey.withUnsafeBytes {
return Bytes($0)
}
let nonce = Bytes(sealedBox.nonce)
let chacha = try ChaChaPoly(key, nonce)
var ct = Bytes(sealedBox.ciphertext)
// ct contains the ciphertext
let ok = chacha.decrypt(&ct, Bytes(sealedBox.tag), aad)
print(String(bytes: ct, encoding: .utf8)!)
giving:
Hi, there
SwiftChaChaPoly requires Swift 5.0. It does not depend on other packages.
Algorithms from the following papers have been used in the implementation. There are references in the source code where appropriate.
link |
Stars: 3 |
Last commit: 2 weeks ago |
About SwiftChaChaPoly release 2.0.0:
The ChaChaPoly constructor throws an exception if its key or nonce parameters have wrong size. In the previous release this would cause a precondition to fail
API and functionality is otherwise unchanged
A number of project Wycheproof test cases added
Updated documentation
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics