Skip to content

Commit

Permalink
Renaming crypto algorithms (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
amika-sq authored Feb 16, 2024
1 parent 9b56c52 commit 4290f12
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 254 deletions.
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
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

0 comments on commit 4290f12

Please sign in to comment.