File: ECDH.swift.gyb

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (289 lines) | stat: -rw-r--r-- 13,095 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftCrypto open source project
//
// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else
#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
typealias NISTCurvePublicKeyImpl = CoreCryptoNISTCurvePublicKeyImpl
typealias NISTCurvePrivateKeyImpl = CoreCryptoNISTCurvePrivateKeyImpl
#else
typealias NISTCurvePublicKeyImpl = OpenSSLNISTCurvePublicKeyImpl
typealias NISTCurvePrivateKeyImpl = OpenSSLNISTCurvePrivateKeyImpl
#endif

import Foundation

// MARK: - Generated file, do NOT edit
// any edits of this file WILL be overwritten and thus discarded
// see section `gyb` in `README` for details.

%{
    NIST_CURVES = ["P256", "P384", "P521"]
    CURVES_FUNC = ["Signing", "KeyAgreement"]
}%
% for CURVE in NIST_CURVES:
%{ DISPLAY_CURVE = CURVE[:1] + "-" + CURVE[1:] }%
% for FUNC in CURVES_FUNC:
// MARK: - ${CURVE} + ${FUNC}
extension ${CURVE} {
    
    % if FUNC == "Signing":
    /// A mechanism used to create or verify a cryptographic signature using
    /// the NIST ${DISPLAY_CURVE} elliptic curve digital signature algorithm (ECDSA).
    % else:
    /// A mechanism used to create a shared secret between two users by
    /// performing NIST ${DISPLAY_CURVE} elliptic curve Diffie Hellman (ECDH) key
    /// exchange.
    % end
    public enum ${FUNC} {
            
        % if FUNC == "Signing":
        %{ READABLE_FUNC = "signing" }%
        /// A ${DISPLAY_CURVE} public key used to verify cryptographic signatures.
        % else:
        %{ READABLE_FUNC = "key agreement" }%
        /// A ${DISPLAY_CURVE} public key used for key agreement.
        % end
        public struct PublicKey: NISTECPublicKey {
            var impl: NISTCurvePublicKeyImpl<${CURVE}>

            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a collection of bytes.
            ///
            /// - Parameters:
            ///   - rawRepresentation: A raw representation of the key as a collection of
            /// contiguous bytes.
            public init<D: ContiguousBytes>(rawRepresentation: D) throws {
                impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation)
            }

            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a compact
            /// representation of the key.
            ///
            /// - Parameters:
            ///   - compactRepresentation: A compact representation of the key
            /// as a collection of contiguous bytes.
            public init<Bytes: ContiguousBytes>(compactRepresentation: Bytes) throws {
                impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation)
            }

            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from an ANSI x9.63
            /// representation.
            ///
            /// - Parameters:
            ///   - x963Representation: An ANSI x9.63 representation of the key.
            public init<Bytes: ContiguousBytes>(x963Representation: Bytes) throws {
                impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation)
            }
            
            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a compressed representation of
            /// the key.
            ///
            /// - Parameters:
            ///   - compressedRepresentation: A compressed representation of the key as a collection
            /// of contiguous bytes.
            public init<Bytes: ContiguousBytes>(compressedRepresentation: Bytes) throws {
                impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation)
            }

            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a Privacy-Enhanced Mail
            /// (PEM) representation.
            ///
            /// - Parameters:
            ///   - pemRepresentation: A PEM representation of the key.
            public init(pemRepresentation: String) throws {
                let pem = try ASN1.PEMDocument(pemString: pemRepresentation)
                guard pem.type == "PUBLIC KEY" else {
                    throw CryptoKitASN1Error.invalidPEMDocument
                }
                self = try .init(derRepresentation: pem.derBytes)
            }

            /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a Distinguished Encoding
            /// Rules (DER) encoded representation.
            ///
            /// - Parameters:
            ///   - derRepresentation: A DER-encoded representation of the key.
            public init<Bytes: RandomAccessCollection>(derRepresentation: Bytes) throws where Bytes.Element == UInt8 {
                let bytes = Array(derRepresentation)
                let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes)
                self = try .init(x963Representation: parsed.key)
            }

            init(impl: NISTCurvePublicKeyImpl<${CURVE}>) {
                self.impl = impl
            }

            /// A compact representation of the public key.
            public var compactRepresentation: Data? { impl.compactRepresentation }
            
            /// A full representation of the public key.
            public var rawRepresentation: Data { impl.rawRepresentation }
            
            /// An ANSI x9.63 representation of the public key.
            public var x963Representation: Data { impl.x963Representation }

            /// A compressed representation of the public key.
            public var compressedRepresentation: Data { impl.compressedRepresentation }
            
            /// A Distinguished Encoding Rules (DER) encoded representation of the public key.
            public var derRepresentation: Data {
                let spki = ASN1.SubjectPublicKeyInfo(algorithmIdentifier: .ecdsa${CURVE}, key: Array(self.x963Representation))
                var serializer = ASN1.Serializer()

                // Serializing these keys can't throw
                try! serializer.serialize(spki)
                return Data(serializer.serializedBytes)
            }

            /// A Privacy-Enhanced Mail (PEM) representation of the public key.
            public var pemRepresentation: String {
                let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation)
                return pemDocument.pemString
            }
        }

        % if FUNC == "Signing":
        /// A ${DISPLAY_CURVE} private key used to create cryptographic signatures.
        % else:
        /// A ${DISPLAY_CURVE} private key used for key agreement.
        % end
        public struct PrivateKey: NISTECPrivateKey {
            let impl: NISTCurvePrivateKeyImpl<${CURVE}>

            /// Creates a random ${DISPLAY_CURVE} private key for ${READABLE_FUNC}.
            ///
            /// Keys that use a compact point encoding enable shorter public keys, but aren’t
            /// compliant with FIPS certification. If your app requires FIPS certification,
            /// create a key with ``init(rawRepresentation:)``.
            ///
            /// - Parameters:
            ///   - compactRepresentable: A Boolean value that indicates whether CryptoKit
            /// creates the key with the structure to enable compact point encoding.
            public init(compactRepresentable: Bool = true) {
                impl = NISTCurvePrivateKeyImpl(compactRepresentable: compactRepresentable)
            }

            /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from an ANSI x9.63
            /// representation.
            ///
            /// - Parameters:
            ///   - x963Representation: An ANSI x9.63 representation of the key.
            public init<Bytes: ContiguousBytes>(x963Representation: Bytes) throws {
                impl = try NISTCurvePrivateKeyImpl(x963: x963Representation)
            }

            /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from a collection of bytes.
            ///
            /// - Parameters:
            ///   - rawRepresentation: A raw representation of the key as a collection of
            /// contiguous bytes.
            public init<Bytes: ContiguousBytes>(rawRepresentation: Bytes) throws {
                impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation)
            }

            /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from a Privacy-Enhanced Mail
            /// PEM) representation.
            ///
            /// - Parameters:
            ///   - pemRepresentation: A PEM representation of the key.
            public init(pemRepresentation: String) throws {
                let pem = try ASN1.PEMDocument(pemString: pemRepresentation)

                switch pem.type {
                case "EC PRIVATE KEY":
                    let parsed = try ASN1.SEC1PrivateKey(asn1Encoded: Array(pem.derBytes))
                    self = try .init(rawRepresentation: parsed.privateKey)
                case "PRIVATE KEY":
                    let parsed = try ASN1.PKCS8PrivateKey(asn1Encoded: Array(pem.derBytes))
                    self = try .init(rawRepresentation: parsed.privateKey.privateKey)
                default:
                    throw CryptoKitASN1Error.invalidPEMDocument
                }
            }

            /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from a Distinguished Encoding
            /// Rules (DER) encoded representation.
            ///
            /// - Parameters:
            ///   - derRepresentation: A DER-encoded representation of the key.
            public init<Bytes: RandomAccessCollection>(derRepresentation: Bytes) throws where Bytes.Element == UInt8 {
                let bytes = Array(derRepresentation)

                // We have to try to parse this twice because we have no information about what kind of key this is.
                // We try with PKCS#8 first, and then fall back to SEC.1.

                do {
                    let key = try ASN1.PKCS8PrivateKey(asn1Encoded: bytes)
                    self = try .init(rawRepresentation: key.privateKey.privateKey)
                } catch {
                    let key = try ASN1.SEC1PrivateKey(asn1Encoded: bytes)
                    self = try .init(rawRepresentation: key.privateKey)
                }
            }

            init(impl: NISTCurvePrivateKeyImpl<${CURVE}>) {
                self.impl = impl
            }

            /// The corresponding public key.
            public var publicKey: ${CURVE}.${FUNC}.PublicKey {
                return PublicKey(impl: impl.publicKey())
            }

            /// A data representation of the private key.
            public var rawRepresentation: Data { impl.rawRepresentation }
            
            /// An ANSI x9.63 representation of the private key.
            public var x963Representation: Data { impl.x963Representation }

            /// A Distinguished Encoding Rules (DER) encoded representation of the private key.
            public var derRepresentation: Data {
                let pkey = ASN1.PKCS8PrivateKey(algorithm: .ecdsa${CURVE}, privateKey: Array(self.rawRepresentation), publicKey: Array(self.publicKey.x963Representation))
                var serializer = ASN1.Serializer()

                // Serializing these keys can't throw
                try! serializer.serialize(pkey)
                return Data(serializer.serializedBytes)
            }

            /// A Privacy-Enhanced Mail (PEM) representation of the private key.
            public var pemRepresentation: String {
                let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation)
                return pemDocument.pemString
            }
        }
    }
}
% end
% end

% for CURVE in NIST_CURVES:
// MARK: - ${CURVE} + DH
extension ${CURVE}.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
    /// Computes a shared secret with the provided public key from another party.
    ///
    /// - Parameters:
    ///   - publicKeyShare: The public key from another party to be combined with the private
    /// key from this user to create the shared secret.
    /// - Returns: The computed shared secret.
    public func sharedSecretFromKeyAgreement(with publicKeyShare: ${CURVE}.KeyAgreement.PublicKey) throws -> SharedSecret {
        #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
        return try self.coreCryptoSharedSecretFromKeyAgreement(with: publicKeyShare)
        #else
        return try self.openSSLSharedSecretFromKeyAgreement(with: publicKeyShare)
        #endif
    }
}
% end
#endif // Linux or !SwiftPM