From a46905442266dbf9830978aa3c23cab33b0fd4cb Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 17 Apr 2023 12:23:36 +0200 Subject: [PATCH] Make NIST PublicKey's conform to Equatable --- Sources/Crypto/Key Agreement/ECDH.swift | 24 ++++++ Sources/Crypto/Key Agreement/ECDH.swift.gyb | 4 + Sources/Crypto/Keys/EC/NISTCurvesKeys.swift | 2 +- .../ECDSA/ECDSASignatureTests.swift | 85 ++++++++++++++++++- 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/Sources/Crypto/Key Agreement/ECDH.swift b/Sources/Crypto/Key Agreement/ECDH.swift index acb8e75c..7472b29c 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift +++ b/Sources/Crypto/Key Agreement/ECDH.swift @@ -88,6 +88,10 @@ extension P256 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { @@ -222,6 +226,10 @@ extension P256 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { @@ -356,6 +364,10 @@ extension P384 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { @@ -490,6 +502,10 @@ extension P384 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { @@ -624,6 +640,10 @@ extension P521 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { @@ -758,6 +778,10 @@ extension P521 { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { diff --git a/Sources/Crypto/Key Agreement/ECDH.swift.gyb b/Sources/Crypto/Key Agreement/ECDH.swift.gyb index 57b7094e..72fa13ac 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift.gyb +++ b/Sources/Crypto/Key Agreement/ECDH.swift.gyb @@ -94,6 +94,10 @@ extension ${CURVE} { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } } public struct PrivateKey: NISTECPrivateKey { diff --git a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift index 730001a2..73227c53 100644 --- a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift +++ b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift @@ -32,7 +32,7 @@ protocol ECPrivateKey { var publicKey: PublicKey { get } } -protocol NISTECPublicKey: ECPublicKey { +protocol NISTECPublicKey: ECPublicKey, Equatable { init(compactRepresentation: Bytes) throws init(compressedRepresentation: Bytes) throws init(x963Representation: Bytes) throws diff --git a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift index 5b2af040..450ec083 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift @@ -453,6 +453,89 @@ class SignatureTests: XCTestCase { let compressedX963Positive = Data(base64Encoded: "A+QHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")! XCTAssertThrowsError(try P256.Signing.PublicKey(x963Representation: compressedX963Positive)) } - + + func testP256SigningPublicKeyEquatable() throws { + // Equality + let publicKey = P256.Signing.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P256.Signing.PrivateKey().publicKey + ) + } + } + + func testP256KeyAgreementPublicKeyEquatable() throws { + // Equality + let publicKey = P256.KeyAgreement.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P256.KeyAgreement.PrivateKey().publicKey + ) + } + } + + func testP384SigningPublicKeyEquatable() throws { + // Equality + let publicKey = P384.Signing.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P384.Signing.PrivateKey().publicKey + ) + } + } + + func testP384KeyAgreementPublicKeyEquatable() throws { + // Equality + let publicKey = P384.KeyAgreement.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P384.KeyAgreement.PrivateKey().publicKey + ) + } + } + + func testP521SigningPublicKeyEquatable() throws { + // Equality + let publicKey = P521.Signing.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P521.Signing.PrivateKey().publicKey + ) + } + } + + func testP521KeyAgreementPublicKeyEquatable() throws { + // Equality + let publicKey = P521.KeyAgreement.PrivateKey().publicKey + XCTAssertEqual(publicKey, publicKey) + + // Inequality + for _ in 0..<32 { + XCTAssertNotEqual( + publicKey, + P521.KeyAgreement.PrivateKey().publicKey + ) + } + } } #endif // (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM