Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions .licenseignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*.md
*.txt
Package.swift
Package@swift-6.0.swift
Package.resolved
.gitignore
.swift-format
Expand Down
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:6.0
// swift-tools-version:6.1
//===----------------------------------------------------------------------===//
//
// This source file is part of the swift-libp2p open source project
Expand Down Expand Up @@ -36,7 +36,7 @@ let package = Package(
// Protobuf Marshaling
.package(url: "https://github.com/apple/swift-protobuf.git", .upToNextMajor(from: "1.33.3")),
// Secp256k1 Support
.package(url: "https://github.com/Boilertalk/secp256k1.swift.git", .upToNextMinor(from: "0.1.7")),
.package(url: "https://github.com/21-DOT-DEV/swift-secp256k1.git", .upToNextMinor(from: "0.23.0")),
// 🔑 Hashing (BCrypt, SHA2, HMAC), encryption (AES), public-key (RSA), PEM and DER file handling, and random data generation.
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "4.0.0")),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.9.0")),
Expand All @@ -50,7 +50,7 @@ let package = Package(
.product(name: "Multibase", package: "swift-multibase"),
.product(name: "Multihash", package: "swift-multihash"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "secp256k1", package: "secp256k1.swift"),
.product(name: "P256K", package: "swift-secp256k1"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "CryptoSwift", package: "CryptoSwift"),
],
Expand Down
66 changes: 66 additions & 0 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// swift-tools-version:6.0
//===----------------------------------------------------------------------===//
//
// This source file is part of the swift-libp2p open source project
//
// Copyright (c) 2022-2025 swift-libp2p project authors
// Licensed under MIT
//
// See LICENSE for license information
// See CONTRIBUTORS for the list of swift-libp2p project authors
//
// SPDX-License-Identifier: MIT
//
//===----------------------------------------------------------------------===//

import PackageDescription

let package = Package(
name: "swift-libp2p-crypto",
platforms: [
.macOS(.v10_15),
.iOS(.v13),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "LibP2PCrypto",
targets: ["LibP2PCrypto"]
)
],
dependencies: [
// Multibase Support
.package(url: "https://github.com/swift-libp2p/swift-multibase.git", .upToNextMinor(from: "0.2.0")),
// Multihash Support
.package(url: "https://github.com/swift-libp2p/swift-multihash.git", .upToNextMinor(from: "0.2.0")),
// Protobuf Marshaling
.package(url: "https://github.com/apple/swift-protobuf.git", .upToNextMajor(from: "1.33.3")),
// Secp256k1 Support
.package(url: "https://github.com/21-DOT-DEV/swift-secp256k1.git", .upToNextMinor(from: "0.21.0")),
// 🔑 Hashing (BCrypt, SHA2, HMAC), encryption (AES), public-key (RSA), PEM and DER file handling, and random data generation.
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "4.0.0")),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.9.0")),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "LibP2PCrypto",
dependencies: [
.product(name: "Multibase", package: "swift-multibase"),
.product(name: "Multihash", package: "swift-multihash"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "P256K", package: "swift-secp256k1"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "CryptoSwift", package: "CryptoSwift"),
],
resources: [
.copy("Protobufs/keys.proto")
]
),
.testTarget(
name: "LibP2PCryptoTests",
dependencies: ["LibP2PCrypto"]
),
]
)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ let package = Package(
...
dependencies: [
...
.package(url: "https://github.com/swift-libp2p/swift-libp2p-crypto.git", .upToNextMajor(from: "0.0.1"))
.package(url: "https://github.com/swift-libp2p/swift-libp2p-crypto.git", .upToNextMinor(from: "0.2.0"))
],
...
.target(
Expand Down Expand Up @@ -228,7 +228,7 @@ Let's make this code better together! 🤝

## License

[MIT](LICENSE) © 2022 Breth Inc.
[MIT](LICENSE) © 2026 Breth Inc.



Expand Down
16 changes: 9 additions & 7 deletions Sources/LibP2PCrypto/HMAC/HMAC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ extension LibP2PCrypto {
internal func encrypt(_ message: Data, key: String) -> Data {
switch self {
case .MD5:
var hmac = Crypto.HMAC<Insecure.MD5>(key: SymmetricKey(data: key.bytes))
var hmac = Crypto.HMAC<Insecure.MD5>(key: SymmetricKey(data: Array(key.utf8)))
hmac.update(data: message)
return Data(hmac.finalize())
case .SHA1:
var hmac = Crypto.HMAC<Insecure.SHA1>(key: SymmetricKey(data: key.bytes))
var hmac = Crypto.HMAC<Insecure.SHA1>(key: SymmetricKey(data: Array(key.utf8)))
hmac.update(data: message)
return Data(hmac.finalize())
case .SHA256:
var hmac = Crypto.HMAC<SHA256>(key: SymmetricKey(data: key.bytes))
var hmac = Crypto.HMAC<SHA256>(key: SymmetricKey(data: Array(key.utf8)))
hmac.update(data: message)
return Data(hmac.finalize())
case .SHA384:
var hmac = Crypto.HMAC<SHA384>(key: SymmetricKey(data: key.bytes))
var hmac = Crypto.HMAC<SHA384>(key: SymmetricKey(data: Array(key.utf8)))
hmac.update(data: message)
return Data(hmac.finalize())
case .SHA512:
var hmac = Crypto.HMAC<SHA512>(key: SymmetricKey(data: key.bytes))
var hmac = Crypto.HMAC<SHA512>(key: SymmetricKey(data: Array(key.utf8)))
hmac.update(data: message)
return Data(hmac.finalize())
}
Expand Down Expand Up @@ -69,11 +69,13 @@ extension LibP2PCrypto {
}

public func verify(_ str: String, hash: Data) -> Bool {
self.encrypt(str) == hash
guard !hash.isEmpty, !str.isEmpty else { return false }
return self.encrypt(str) == hash
}

public func verify(_ data: Data, hash: Data) -> Bool {
self.encrypt(data) == hash
guard !hash.isEmpty, !data.isEmpty else { return false }
return self.encrypt(data) == hash
}
}

Expand Down
27 changes: 15 additions & 12 deletions Sources/LibP2PCrypto/Keys/KeyPair.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Crypto
import Foundation
import Multibase
import Multihash
import P256K

extension LibP2PCrypto.Keys {
public struct KeyPair: Sendable {
Expand All @@ -41,7 +42,7 @@ extension LibP2PCrypto.Keys {
case .Ed25519:
try self.init(privateKey: Curve25519.Signing.PrivateKey())
case .Secp256k1:
try self.init(privateKey: Secp256k1PrivateKey())
try self.init(privateKey: P256K.Signing.PrivateKey())
case .RSA(let keySize):
try self.init(privateKey: RSAPrivateKey(keySize: keySize.bits))
//default:
Expand Down Expand Up @@ -170,7 +171,7 @@ extension LibP2PCrypto.Keys {
try self.init(publicKey: Curve25519.Signing.PublicKey(marshaledData: proto.data))

case .secp256K1:
try self.init(publicKey: Secp256k1PublicKey(marshaledData: proto.data))
try self.init(publicKey: P256K.Signing.PublicKey(marshaledData: proto.data))
}
}

Expand Down Expand Up @@ -221,7 +222,7 @@ extension LibP2PCrypto.Keys {
throw NSError(domain: "Invalid private key protobuf encoding -> invalid data payload", code: 0)
}
case .secp256K1:
try self.init(privateKey: Secp256k1PrivateKey(marshaledData: proto.data))
try self.init(privateKey: P256K.Signing.PrivateKey(marshaledData: proto.data))
}
}

Expand Down Expand Up @@ -281,7 +282,7 @@ extension LibP2PCrypto.Keys {

extension LibP2PCrypto.Keys.KeyPair {
public init(pem: String, password: String? = nil) throws {
try self.init(pem: pem.bytes, password: password)
try self.init(pem: Array(pem.utf8), password: password)
}

public init(pem: Data, password: String? = nil) throws {
Expand Down Expand Up @@ -313,8 +314,8 @@ extension LibP2PCrypto.Keys.KeyPair {
try self.init(
publicKey: Curve25519.Signing.PublicKey(pem: pemBytes, asType: Curve25519.Signing.PublicKey.self)
)
} else if ids.contains(Secp256k1PublicKey.primaryObjectIdentifier) {
try self.init(publicKey: Secp256k1PublicKey(pem: pemBytes, asType: Secp256k1PublicKey.self))
} else if ids.contains(P256K.Signing.PublicKey.primaryObjectIdentifier) {
try self.init(publicKey: P256K.Signing.PublicKey(pem: pemBytes, asType: P256K.Signing.PublicKey.self))
} else {
throw LibP2PCrypto.PEM.Error.unsupportedPEMType
}
Expand All @@ -327,8 +328,10 @@ extension LibP2PCrypto.Keys.KeyPair {
try self.init(
privateKey: Curve25519.Signing.PrivateKey(pem: pemBytes, asType: Curve25519.Signing.PrivateKey.self)
)
} else if ids.contains(Secp256k1PrivateKey.primaryObjectIdentifier) {
try self.init(privateKey: Secp256k1PrivateKey(pem: pemBytes, asType: Secp256k1PrivateKey.self))
} else if ids.contains(P256K.Signing.PrivateKey.primaryObjectIdentifier) {
try self.init(
privateKey: P256K.Signing.PrivateKey(pem: pemBytes, asType: P256K.Signing.PrivateKey.self)
)
} else {
throw LibP2PCrypto.PEM.Error.unsupportedPEMType
}
Expand Down Expand Up @@ -379,13 +382,13 @@ extension LibP2PCrypto.Keys.KeyPair {
expectedSecondaryObjectIdentifier: Curve25519.Signing.PrivateKey.secondaryObjectIdentifier
)
try self.init(privateKey: Curve25519.Signing.PrivateKey(privateDER: der))
} else if ids.contains(Secp256k1PrivateKey.primaryObjectIdentifier) {
} else if ids.contains(P256K.Signing.PrivateKey.primaryObjectIdentifier) {
let der = try LibP2PCrypto.PEM.decodePrivateKeyPEM(
Data(decryptedPEM),
expectedPrimaryObjectIdentifier: Secp256k1PrivateKey.primaryObjectIdentifier,
expectedSecondaryObjectIdentifier: Secp256k1PrivateKey.secondaryObjectIdentifier
expectedPrimaryObjectIdentifier: P256K.Signing.PrivateKey.primaryObjectIdentifier,
expectedSecondaryObjectIdentifier: P256K.Signing.PrivateKey.secondaryObjectIdentifier
)
try self.init(privateKey: Secp256k1PrivateKey(privateDER: der))
try self.init(privateKey: P256K.Signing.PrivateKey(privateDER: der))
} else {
print(ids)
throw LibP2PCrypto.PEM.Error.unsupportedPEMType
Expand Down
8 changes: 4 additions & 4 deletions Sources/LibP2PCrypto/Keys/Types/Ed25519/Ed25519.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Crypto
import Foundation

extension Curve25519.Signing.PublicKey: CommonPublicKey, @unchecked Sendable {
extension Curve25519.Signing.PublicKey: CommonPublicKey, @retroactive @unchecked Sendable {
public static var keyType: LibP2PCrypto.Keys.GenericKeyType { .ed25519 }

init(marshaledData data: Data) throws {
Expand All @@ -38,7 +38,7 @@ extension Curve25519.Signing.PublicKey: CommonPublicKey, @unchecked Sendable {
}
}

extension Curve25519.Signing.PrivateKey: CommonPrivateKey, @unchecked Sendable {
extension Curve25519.Signing.PrivateKey: CommonPrivateKey, @retroactive @unchecked Sendable {
public static var keyType: LibP2PCrypto.Keys.GenericKeyType { .ed25519 }

init(marshaledData data: Data) throws {
Expand Down Expand Up @@ -109,7 +109,7 @@ extension Curve25519.Signing.PublicKey: DERCodable {

let base64String = ASN1.Encoder.encode(asnNodes).toBase64()
let bodyString = base64String.chunks(ofCount: 64).joined(separator: "\n")
let bodyUTF8Bytes = bodyString.bytes
let bodyUTF8Bytes = Array(bodyString.utf8)

if withHeaderAndFooter {
let header = LibP2PCrypto.PEM.PEMType.publicKey.headerBytes + [0x0a]
Expand Down Expand Up @@ -164,7 +164,7 @@ extension Curve25519.Signing.PrivateKey: DERCodable {
public func exportPrivateKeyPEM(withHeaderAndFooter: Bool) throws -> [UInt8] {
let base64String = try self.exportPrivateKeyPEMRaw().toBase64()
let bodyString = base64String.chunks(ofCount: 64).joined(separator: "\n")
let bodyUTF8Bytes = bodyString.bytes
let bodyUTF8Bytes = Array(bodyString.utf8)

if withHeaderAndFooter {
let header = LibP2PCrypto.PEM.PEMType.privateKey.headerBytes + [0x0a]
Expand Down
4 changes: 2 additions & 2 deletions Sources/LibP2PCrypto/Keys/Types/RSA/RSA+DER.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ extension RSAPublicKey: DERCodable {

let base64String = publicDER.toBase64()
let bodyString = base64String.chunks(ofCount: 64).joined(separator: "\n")
let bodyUTF8Bytes = bodyString.bytes
let bodyUTF8Bytes = Array(bodyString.utf8)

if withHeaderAndFooter {
let header = LibP2PCrypto.PEM.PEMType.publicKey.headerBytes + [0x0a]
Expand Down Expand Up @@ -93,7 +93,7 @@ extension RSAPrivateKey: DERCodable {
public func exportPrivateKeyPEM(withHeaderAndFooter: Bool) throws -> [UInt8] {
let base64String = try self.exportPrivateKeyPEMRaw().toBase64()
let bodyString = base64String.chunks(ofCount: 64).joined(separator: "\n")
let bodyUTF8Bytes = bodyString.bytes
let bodyUTF8Bytes = Array(bodyString.utf8)

if withHeaderAndFooter {
let header = LibP2PCrypto.PEM.PEMType.privateKey.headerBytes + [0x0a]
Expand Down
Loading
Loading