Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renaming crypto algorithms #16

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions Sources/Web5/Crypto/Algorithms/Ed25519.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import CryptoKit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why github makes this one look like it's a brand new file 🤔

import Foundation

/// Cryptographic operations using the Edwards-curve Digital Signature Algorithm (EdDSA)
/// with the Ed25519 elliptic curve
public enum Ed25519: AsymmetricKeyGenerator, Signer {

enum Error: Swift.Error {
case invalidPrivateJwk
case invalidPublicJwk
}

public static func generatePrivateKey() throws -> Jwk {
return try Curve25519.Signing.PrivateKey().jwk()
}

public static func computePublicKey(privateKey: Jwk) throws -> Jwk {
let privateKey = try Curve25519.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.publicKey.jwk()
}

public static func privateKeyToBytes(_ privateKey: Jwk) throws -> Data {
let privateKey = try Curve25519.Signing.PrivateKey(privateJwk: privateKey)
return privateKey.rawRepresentation
}

public static func privateKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try Curve25519.Signing.PrivateKey(rawRepresentation: bytes).jwk()
}

public static func publicKeyToBytes(_ publicKey: Jwk) throws -> Data {
let publicKey = try Curve25519.Signing.PublicKey(publicJwk: publicKey)
return publicKey.rawRepresentation
}

public static func publicKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try Curve25519.Signing.PublicKey(rawRepresentation: bytes).jwk()
}

public static func sign<D>(payload: D, privateKey: Jwk) throws -> Data where D: DataProtocol {
let privateKey = try Curve25519.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.signature(for: payload)
}

public static func verify<P, S>(payload: P, signature: S, publicKey: Jwk) throws -> Bool
where P: DataProtocol, S: DataProtocol {
let publicKey = try Curve25519.Signing.PublicKey(publicJwk: publicKey)
return publicKey.isValidSignature(signature, for: payload)
}

public static func isValidPrivateKey(_ privateKey: Jwk) -> Bool {
let privateKey = try? Curve25519.Signing.PrivateKey(privateJwk: privateKey)
return privateKey != nil
}

public static func isValidPublicKey(_ publicKey: Jwk) -> Bool {
let publicKey = try? Curve25519.Signing.PublicKey(publicJwk: publicKey)
return publicKey != nil
}
}

// MARK: - Curve25519 Extensions

extension Curve25519.Signing.PrivateKey {

init(privateJwk: Jwk) throws {
guard
privateJwk.keyType == .octetKeyPair,
privateJwk.algorithm == .eddsa || privateJwk.curve == .ed25519,
privateJwk.y == nil,
let d = privateJwk.d
else {
throw Ed25519.Error.invalidPrivateJwk
}

try self.init(rawRepresentation: d.decodeBase64Url())
}

func jwk() throws -> Jwk {
var jwk = try publicKey.jwk()
jwk.d = rawRepresentation.base64UrlEncodedString()
return jwk
}

}

extension Curve25519.Signing.PublicKey {

init(publicJwk: Jwk) throws {
guard
publicJwk.keyType == .octetKeyPair,
publicJwk.algorithm == .eddsa || publicJwk.curve == .ed25519,
publicJwk.y == nil,
publicJwk.d == nil,
let x = publicJwk.x
else {
throw Ed25519.Error.invalidPublicJwk
}

try self.init(rawRepresentation: x.decodeBase64Url())
}

func jwk() throws -> Jwk {
var jwk = Jwk(
keyType: .octetKeyPair,
algorithm: .eddsa,
curve: .ed25519,
x: rawRepresentation.base64UrlEncodedString()
)
jwk.keyID = try jwk.thumbprint()

return jwk
}

}
Original file line number Diff line number Diff line change
@@ -1,73 +1,70 @@
import Foundation
import secp256k1

extension ECDSA {
/// Crypto operations using the Elliptic Curve Digital Signature Algorithm (ECDSA)
/// with the secp256k1 elliptic curve and SHA-256
public enum Secp256k1: AsymmetricKeyGenerator, Signer {

/// Crypto operations using the Elliptic Curve Digital Signature Algorithm (ECDSA)
/// with the secp256k1 elliptic curve and SHA-256
public enum Es256k: AsymmetricKeyGenerator, Signer {

public static func generatePrivateKey() throws -> Jwk {
return try secp256k1.Signing.PrivateKey().jwk()
}
public static func generatePrivateKey() throws -> Jwk {
return try secp256k1.Signing.PrivateKey().jwk()
}

public static func computePublicKey(privateKey: Jwk) throws -> Jwk {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.publicKey.jwk()
}
public static func computePublicKey(privateKey: Jwk) throws -> Jwk {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.publicKey.jwk()
}

public static func privateKeyToBytes(_ privateKey: Jwk) throws -> Data {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return privateKey.dataRepresentation
}
public static func privateKeyToBytes(_ privateKey: Jwk) throws -> Data {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return privateKey.dataRepresentation
}

public static func privateKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try secp256k1.Signing.PrivateKey(dataRepresentation: bytes).jwk()
}
public static func privateKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try secp256k1.Signing.PrivateKey(dataRepresentation: bytes).jwk()
}

public static func publicKeyToBytes(_ publicKey: Jwk) throws -> Data {
let publicKey = try secp256k1.Signing.PublicKey(publicJwk: publicKey)
return publicKey.uncompressedBytes()
}
public static func publicKeyToBytes(_ publicKey: Jwk) throws -> Data {
let publicKey = try secp256k1.Signing.PublicKey(publicJwk: publicKey)
return publicKey.uncompressedBytes()
}

public static func publicKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try secp256k1.Signing.PublicKey(
dataRepresentation: bytes,
format: bytes.count == secp256k1.Signing.PublicKey.Constants.compressedKeySize
? .compressed
: .uncompressed
).jwk()
}
public static func publicKeyFromBytes(_ bytes: Data) throws -> Jwk {
return try secp256k1.Signing.PublicKey(
dataRepresentation: bytes,
format: bytes.count == secp256k1.Signing.PublicKey.Constants.compressedKeySize
? .compressed
: .uncompressed
).jwk()
}

public static func sign<D>(payload: D, privateKey: Jwk) throws -> Data where D: DataProtocol {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.signature(for: payload).compactRepresentation
}
public static func sign<D>(payload: D, privateKey: Jwk) throws -> Data where D: DataProtocol {
let privateKey = try secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return try privateKey.signature(for: payload).compactRepresentation
}

public static func verify<P, S>(payload: P, signature: S, publicKey: Jwk) throws -> Bool
where P: DataProtocol, S: DataProtocol {
let publicKey = try secp256k1.Signing.PublicKey(publicJwk: publicKey)
let ecdsaSignature = try secp256k1.Signing.ECDSASignature(compactRepresentation: signature)
let normalizedSignature = try ecdsaSignature.normalized()
public static func verify<P, S>(payload: P, signature: S, publicKey: Jwk) throws -> Bool
where P: DataProtocol, S: DataProtocol {
let publicKey = try secp256k1.Signing.PublicKey(publicJwk: publicKey)
let ecdsaSignature = try secp256k1.Signing.ECDSASignature(compactRepresentation: signature)
let normalizedSignature = try ecdsaSignature.normalized()

return publicKey.isValidSignature(normalizedSignature, for: payload)
}
return publicKey.isValidSignature(normalizedSignature, for: payload)
}

public static func isValidPrivateKey(_ privateKey: Jwk) -> Bool {
let privateKey = try? secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return privateKey != nil
}
public static func isValidPrivateKey(_ privateKey: Jwk) -> Bool {
let privateKey = try? secp256k1.Signing.PrivateKey(privateJwk: privateKey)
return privateKey != nil
}

public static func isValidPublicKey(_ publicKey: Jwk) -> Bool {
let publicKey = try? secp256k1.Signing.PublicKey(publicJwk: publicKey)
return publicKey != nil
}
public static func isValidPublicKey(_ publicKey: Jwk) -> Bool {
let publicKey = try? secp256k1.Signing.PublicKey(publicJwk: publicKey)
return publicKey != nil
}

/// Errors thrown by `ECDSA.Es256k`
enum Error: Swift.Error {
case invalidPrivateJwk
case invalidPublicJwk
}
/// Errors thrown by `Secp256k1`
enum Error: Swift.Error {
case invalidPrivateJwk
case invalidPublicJwk
}
}

Expand All @@ -81,7 +78,7 @@ extension secp256k1.Signing.PrivateKey {
privateJwk.algorithm == .es256k || privateJwk.curve == .secp256k1,
let d = privateJwk.d
else {
throw ECDSA.Es256k.Error.invalidPrivateJwk
throw Secp256k1.Error.invalidPrivateJwk
}

try self.init(dataRepresentation: d.decodeBase64Url())
Expand Down Expand Up @@ -122,7 +119,7 @@ extension secp256k1.Signing.PublicKey {
let x = publicJwk.x,
let y = publicJwk.y
else {
throw ECDSA.Es256k.Error.invalidPublicJwk
throw Secp256k1.Error.invalidPublicJwk
}

var data = Data()
Expand All @@ -131,7 +128,7 @@ extension secp256k1.Signing.PublicKey {
data.append(contentsOf: try y.decodeBase64Url())

guard data.count == Constants.uncompressedKeySize else {
throw ECDSA.Es256k.Error.invalidPublicJwk
throw Secp256k1.Error.invalidPublicJwk
}

try self.init(dataRepresentation: data, format: .uncompressed)
Expand Down
14 changes: 7 additions & 7 deletions Sources/Web5/Crypto/Crypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ extension CryptoAlgorithm {
algorithm = .ed25519
}
case .es256k:
algorithm = .es256k
algorithm = .secp256k1
}
} else {
// If no JWS algorithm was provided, use the public key alone to determine the `CryptoAlgorithm`
Expand Down Expand Up @@ -166,10 +166,10 @@ extension CryptoAlgorithm {
/// `Signer` associated with the `CryptoAlgorithm`
fileprivate var signer: Signer.Type? {
switch self {
case .es256k:
return ECDSA.Es256k.self
case .secp256k1:
return Secp256k1.self
case .ed25519:
return EdDSA.Ed25519.self
return Ed25519.self
}
}

Expand All @@ -181,10 +181,10 @@ extension CryptoAlgorithm {
/// `AsymmetricKeyGenerator` associated with the `CryptoAlgorithm`
fileprivate var asymmetricKeyGenerator: AsymmetricKeyGenerator.Type? {
switch self {
case .es256k:
return ECDSA.Es256k.self
case .secp256k1:
return Secp256k1.self
case .ed25519:
return EdDSA.Ed25519.self
return Ed25519.self
}
}
}
2 changes: 1 addition & 1 deletion Sources/Web5/Crypto/CryptoAlgorithm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public enum CryptoAlgorithm: CaseIterable {
/// EdDSA using the Ed25519 curve
case ed25519
/// ECDSA using the secp256k1 curve and SHA-256
case es256k
case secp256k1
}
4 changes: 0 additions & 4 deletions Sources/Web5/Crypto/DigitalSignatureAlgorithms/ECDSA.swift

This file was deleted.

Loading
Loading