@@ -32,7 +32,7 @@ This encompasses:
3232In your project Package.swift file add a dependency like<br />
3333
3434 dependencies: [
35- .package(url: "https://github.com/leif-ibsen/SwiftECC", from: "3.6 .0"),
35+ .package(url: "https://github.com/leif-ibsen/SwiftECC", from: "3.7 .0"),
3636 ]
3737SwiftECC requires Swift 5.0. It also requires that the Int and UInt types be 64 bit types.
3838SwiftECC uses Apple's CryptoKit framework. Therefore, for macOS the version must be at least 10.15,
@@ -166,7 +166,7 @@ SwiftECC can read encrypted private key files provided they were encrypted with
166166
167167<h2 id =" basic5 " ><b >Encryption and Decryption</b ></h2 >
168168Encryption and decryption is done using the ECIES algorithm based on the AES block cipher using one of
169- AES-128, AES-192 or AES-256 ciphers, depending on your choice.</ br >
169+ AES-128, AES-192 or AES-256 ciphers, depending on your choice.<br / >
170170The following cipher block modes are supported:
171171<ul >
172172<li >GCM - Galois Counter mode. This is the default mode</li >
@@ -196,38 +196,38 @@ Six cases are considered:
196196<h3 ><b >AES-128/GCM block mode</b ></h3 >
197197KDF generates 32 bytes.
198198
199- AES encryption/decryption key = bytes 0 ..< 16</ br >
200- Nonce = bytes 16 ..< 32</ br >
199+ AES encryption/decryption key = bytes 0 ..< 16<br / >
200+ Nonce = bytes 16 ..< 32<br / >
201201
202202<h3 ><b >AES-192/GCM block mode</b ></h3 >
203203KDF generates 40 bytes.
204204
205- AES encryption/decryption key = bytes 0 ..< 24</ br >
206- Nonce = bytes 24 ..< 40</ br >
205+ AES encryption/decryption key = bytes 0 ..< 24<br / >
206+ Nonce = bytes 24 ..< 40<br / >
207207
208208<h3 ><b >AES-256/GCM block mode</b ></h3 >
209209KDF generates 48 bytes.
210210
211- AES encryption/decryption key = bytes 0 ..< 32</ br >
212- Nonce = bytes 32 ..< 48</ br >
211+ AES encryption/decryption key = bytes 0 ..< 32<br / >
212+ Nonce = bytes 32 ..< 48<br / >
213213
214214<h3 ><b >AES-128/Non-GCM block mode</b ></h3 >
215215KDF generates 48 bytes.
216216
217- AES encryption/decryption key = bytes 0 ..< 16</ br >
218- HMAC key = bytes 16 ..< 48</ br >
217+ AES encryption/decryption key = bytes 0 ..< 16<br / >
218+ HMAC key = bytes 16 ..< 48<br / >
219219
220220<h3 ><b >AES-192/Non-GCM block mode</b ></h3 >
221221KDF generates 56 bytes.
222222
223- AES encryption/decryption key = bytes 0 ..< 24</ br >
224- HMAC key = bytes 24 ..< 56</ br >
223+ AES encryption/decryption key = bytes 0 ..< 24<br / >
224+ HMAC key = bytes 24 ..< 56<br / >
225225
226226<h3 ><b >AES-256/Non-GCM block mode</b ></h3 >
227227KDF generates 64 bytes.
228228
229- AES encryption/decryption key = bytes 0 ..< 32</ br >
230- HMAC key = bytes 32 ..< 64</ br >
229+ AES encryption/decryption key = bytes 0 ..< 32<br / >
230+ HMAC key = bytes 32 ..< 64<br / >
231231
232232The AES key and HMAC key can be retrieved with the ECPrivateKey method 'getKeyAndMac'.
233233
@@ -320,26 +320,26 @@ Four cases are considered:
320320<h3 ><b >ChaCha20/Poly1305</b ></h3 >
321321KDF generates 44 bytes.
322322
323- Encryption/decryption key = bytes 0 ..< 32</ br >
324- Nonce = bytes 32 ..< 44</ br >
323+ Encryption/decryption key = bytes 0 ..< 32<br / >
324+ Nonce = bytes 32 ..< 44<br / >
325325
326326<h3 ><b >AES-128/GCM</b ></h3 >
327327KDF generates 28 bytes.
328328
329- AES encryption/decryption key = bytes 0 ..< 16</ br >
330- Nonce = bytes 16 ..< 28</ br >
329+ AES encryption/decryption key = bytes 0 ..< 16<br / >
330+ Nonce = bytes 16 ..< 28<br / >
331331
332332<h3 ><b >AES-192/GCM</b ></h3 >
333333KDF generates 36 bytes.
334334
335- AES encryption/decryption key = bytes 0 ..< 24</ br >
336- Nonce = bytes 24 ..< 36</ br >
335+ AES encryption/decryption key = bytes 0 ..< 24<br / >
336+ Nonce = bytes 24 ..< 36<br / >
337337
338338<h3 ><b >AES-256/GCM</b ></h3 >
339339KDF generates 44 bytes.
340340
341- AES encryption/decryption key = bytes 0 ..< 32</ br >
342- Nonce = bytes 32 ..< 44</ br >
341+ AES encryption/decryption key = bytes 0 ..< 32<br / >
342+ Nonce = bytes 32 ..< 44<br / >
343343
344344<h2 id =" basic6 " ><b >Signing and Verifying</b ></h2 >
345345Signing data and verifying signatures is performed using the ECDSA algorithm. It is possible to generate
@@ -408,8 +408,13 @@ giving (for example):<br/>
408408
409409<h2 id =" basic7 " ><b >Secret Key Agreement</b ></h2 >
410410Given your own private key and another party's public key, you can generate a byte array that can be used as a symmetric encryption key.
411- The other party can generate the same byte array by using his own private key and your public key.
412- <h3 ><b >Example</b ></h3 >
411+ The other party can generate the same byte array by using his own private key and your public key.<br />
412+ SwiftECC supports two mechanisms:
413+ <ul >
414+ <li >The X9.63 version specified in [SEC 1] section 3.6.1</li >
415+ <li >The HKDF version specified in [RFC-5869]</li >
416+ </ul >
417+ <h3 ><b >X9.63 Example</b ></h3 >
413418
414419 import SwiftECC
415420
@@ -423,33 +428,68 @@ The other party can generate the same byte array by using his own private key an
423428 let (pubB, privB) = domain.makeKeyPair()
424429
425430 let info: Bytes = [1, 2, 3]
426- let secretA = try privA.keyAgreement (pubKey: pubB, length: 16, md: .SHA2_256, sharedInfo: info)
427- let secretB = try privB.keyAgreement (pubKey: pubA, length: 16, md: .SHA2_256, sharedInfo: info)
431+ let secretA = try privA.x963KeyAgreement (pubKey: pubB, length: 16, md: .SHA2_256, sharedInfo: info)
432+ let secretB = try privB.x963KeyAgreement (pubKey: pubA, length: 16, md: .SHA2_256, sharedInfo: info)
428433 print(secretA)
429434 print(secretB)
430435 } catch {
431436 print("Exception: \(error)")
432437 }
433438
434- giving (for example):</ br >
439+ giving (for example):<br / >
435440
436441 [92, 161, 137, 44, 47, 30, 6, 26, 43, 183, 199, 130, 19, 254, 232, 106]
437442 [92, 161, 137, 44, 47, 30, 6, 26, 43, 183, 199, 130, 19, 254, 232, 106]
438443
439- For the key agreement to work, the two parties must agree on which domain to use, which message digest to use
440- and which shared information (possibly none) to use.
444+ For the key agreement to work, the two parties must agree on which domain, which message digest and which shared information (possibly none) to use.
445+ <h3 ><b >HKDF Example</b ></h3 >
446+
447+ import SwiftECC
448+
449+ do {
450+ let domain = Domain.instance(curve: .EC256r1)
451+
452+ // Party A's keys
453+ let (pubA, privA) = domain.makeKeyPair()
454+
455+ // Party B's keys
456+ let (pubB, privB) = domain.makeKeyPair()
457+
458+ let info: Bytes = [1, 2, 3]
459+ let salt: Bytes = [4, 5, 6]
460+ let secretA = try privA.hkdfKeyAgreement(pubKey: pubB, length: 16, md: .SHA2_256, sharedInfo: info, salt: salt)
461+ let secretB = try privB.hkdfKeyAgreement(pubKey: pubA, length: 16, md: .SHA2_256, sharedInfo: info, salt: salt)
462+ print(secretA)
463+ print(secretB)
464+ } catch {
465+ print("Exception: \(error)")
466+ }
467+
468+ giving (for example):<br />
469+
470+ [202, 36, 31, 96, 207, 220, 135, 77, 130, 41, 214, 139, 214, 30, 106, 180]
471+ [202, 36, 31, 96, 207, 220, 135, 77, 130, 41, 214, 139, 214, 30, 106, 180]
472+
473+ For the key agreement to work, the two parties must agree on which domain, which message digest,
474+ which shared information (possibly none) and which salt (possibly none) to use.
441475<h3 ><b >CryptoKit Compatibility</b ></h3 >
442476SwiftECC key agreement is compatible with Swift CryptoKit key agreement
443477in that the EC256r1, EC384r1 and EC521r1 domains correspond to CryptoKit's P256, P384 and P521 curves,
444- and the SHA2_256, SHA2_384 and SHA2_512 message digests correspond to CryptoKit's SHA256, SHA384 and SHA512 message digests.
478+ and the SHA2_256, SHA2_384 and SHA2_512 message digests correspond to CryptoKit's SHA256, SHA384 and SHA512 message digests.<br />
479+ <ul >
480+ <li >The <i >x963KeyAgreement</i > method corresponds to the CryptoKit method <i >x963DerivedSymmetricKey</i ></li >
481+ <li >The <i >hkdfKeyAgreement</i > method corresponds to the CryptoKit method <i >hkdfDerivedSymmetricKey</i ></li >
482+ </ul >
445483
446- To convert a CryptoKit public key - e.g. ' ckPubKey' - to the corresponding SwiftECC public key:</ br >
484+ To convert CryptoKit keys - e.g. < i > ckPubKey</ i >, < i >ckPrivKey</ i > - to the corresponding SwiftECC keys:< br / >
447485
448- let eccPubKey = try ECPublickey(pem: ckPubKey.pemRepresentation)
486+ let eccPubKey = try ECPublicKey(pem: ckPubKey.pemRepresentation)
487+ let eccPrivKey = try ECPrivateKey(pem: ckPrivKey.pemRepresentation)
449488
450- To convert a SwiftECC public key - e.g. ' eccPubKey' - to the corresponding CryptoKit public key:</ br >
489+ To convert SwiftECC keys - e.g. < i > eccPubKey</ i >, < i >eccPrivKey</ i > - to the corresponding CryptoKit keys:< br / >
451490
452491 let ckPubKey = try P256.KeyAgreement.PublicKey(pemRepresentation: eccPubKey.pem)
492+ let ckPrivKey = try P256.KeyAgreement.PrivateKey(pemRepresentation: eccPrivKey.pem)
453493
454494<h2 id =" basic8 " ><b >Creating New Domains</b ></h2 >
455495You can create your own domains as illustrated by the two examples below.
@@ -606,6 +646,7 @@ There are references in the source code where appropriate.
606646<li >[KNUTH] - Donald E. Knuth: Seminumerical Algorithms. Addison-Wesley 1971</li >
607647<li >[NIST] - NIST Special Publication 800-38D, November 2007</li >
608648<li >[PKCS#5] - Password-Based Cryptography Specification - Version 2.0, September 2000</li >
649+ <li >[RFC-5869] - HMAC-based Extract-and-Expand Key Derivation Function (HKDF), May 2010</li >
609650<li >[RFC-6979] - Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA), August 2013</li >
610651<li >[SAVACS] - E. Savacs, C.K. Koc: The Montgomery Modular Inverse - Revisited, July 2000</li >
611652<li >[SEC 1] - Standards for Efficient Cryptography 1 (SEC 1), Certicom Corp. 2009</li >
@@ -614,4 +655,4 @@ There are references in the source code where appropriate.
614655<li >[X9.62] - X9.62 - Public Key Cryptography For The Financial Services Industry, 1998</li >
615656</ul >
616657<h2 id =" ack " ><b >Acknowledgement</b ></h2 >
617- The AES block cipher implementation is essentially a translation to Swift of the Go Language implementation of AES.</ br >
658+ The AES block cipher implementation is essentially a translation to Swift of the Go Language implementation of AES.<br / >
0 commit comments