{"id":21664697,"url":"https://github.com/swift-libp2p/swift-libp2p-crypto","last_synced_at":"2025-07-22T13:04:54.618Z","repository":{"id":39874031,"uuid":"487681122","full_name":"swift-libp2p/swift-libp2p-crypto","owner":"swift-libp2p","description":"Core LibP2P cryptography API for commonly used Keys, Hashes and Ciphers","archived":false,"fork":false,"pushed_at":"2025-04-08T01:23:26.000Z","size":593,"stargazers_count":2,"open_issues_count":5,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-28T14:43:10.875Z","etag":null,"topics":["cryptography","libp2p","multiformats"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swift-libp2p.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-02T01:11:45.000Z","updated_at":"2025-03-05T06:25:54.000Z","dependencies_parsed_at":"2024-11-25T10:42:13.629Z","dependency_job_id":"ac33a296-0419-42ca-bd53-82e32c6f92e9","html_url":"https://github.com/swift-libp2p/swift-libp2p-crypto","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/swift-libp2p/swift-libp2p-crypto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swift-libp2p%2Fswift-libp2p-crypto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swift-libp2p%2Fswift-libp2p-crypto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swift-libp2p%2Fswift-libp2p-crypto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swift-libp2p%2Fswift-libp2p-crypto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swift-libp2p","download_url":"https://codeload.github.com/swift-libp2p/swift-libp2p-crypto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swift-libp2p%2Fswift-libp2p-crypto/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266499016,"owners_count":23938772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","libp2p","multiformats"],"created_at":"2024-11-25T10:42:00.723Z","updated_at":"2025-07-22T13:04:54.599Z","avatar_url":"https://github.com/swift-libp2p.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LibP2PCrypto\n\n[![](https://img.shields.io/badge/made%20by-Breth-blue.svg?style=flat-square)](https://breth.app)\n[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)\n[![Swift Package Manager compatible](https://img.shields.io/badge/SPM-compatible-blue.svg?style=flat-square)](https://github.com/apple/swift-package-manager)\n![Build \u0026 Test (macos and linux)](https://github.com/swift-libp2p/swift-libp2p-crypto/actions/workflows/build+test.yml/badge.svg)\n\n\u003e Core LibP2P cryptography API for interacting with various Keys, Hashes and Ciphers \n\n## Table of Contents\n\n- [Overview](#overview)\n- [Disclaimer](#disclaimer)\n- [Install](#install)\n- [Usage](#usage)\n  - [Example](#example)\n  - [API](#api)\n- [Contributing](#contributing)\n- [Credits](#credits)\n- [Resources](#resources)\n  - [Links](#links) \n- [License](#license)\n\n## Overview\nLibP2PCrypto is an API / abstraction layer for commonly used cryptography within the LibP2P ecosystem. \nThis library...\n- Wraps Public Private Key Pairs such as RSA, ED25519, Secp256k1 and EC keys in a common KeyPair class that can perform signing and signature verification without having to worry about the nuances of each algorithm. \n- Tries to make importing PEM, CERTIFICATES and DER files a little easier. \n- Provides methods for Marshaling Public and Private Keys for use in LibP2P PeerIDs and CIDs. \n- Makes various HMAC and AES Ciphers available under a common API as well.\n\n#### Note:\nThis package currently doesn't support Blake2b, Blake2s \u0026 Blake3. If you're up for the challenge, please feel free to add support!\n\n## Disclaimer\n‼️ This is a work in progress ‼️ \n\n## Install\n\nInclude the following dependency in your Package.swift file\n```Swift\nlet package = Package(\n    ...\n    dependencies: [\n        ...\n        .package(url: \"https://github.com/swift-libp2p/swift-libp2p-crypto.git\", .upToNextMajor(from: \"0.0.1\"))\n    ],\n    ...\n        .target(\n            ...\n            dependencies: [\n                ...\n                .product(name: \"LibP2PCrypto\", package: \"swift-libp2p-crypto\"),\n            ]),\n    ...\n)\n```\n\n## Usage\n\n### Example \ncheck out the [tests](https://github.com/SwiftEthereum/libp2p-crypto/blob/main/Tests/libp2p-cryptoTests/libp2p_cryptoTests.swift) for more examples\n\n```Swift\n\nimport LibP2PCrypto\n\n/// Generate a new Public / Private Key Pair\nlet rsaKeyPair = try LibP2PCrypto.Keys.generateKeyPair(.RSA(bits: .B2048))\nrsaKeyPair.keyType          // -\u003e .rsa\nrsaKeyPair.publicKey        // -\u003e PublicKey\nrsaKeyPair.publicKey.data   // -\u003e raw public key data\nrsaKeyPair.privateKey       // -\u003e optional(PrivateKey)\n\n/// Key Types\ntry LibP2PCrypto.Keys.generateKeyPair(.RSA(bits: .B2048))   // RSA w/ Bit Options... 1024, 2048, 3072, 4096 \ntry LibP2PCrypto.Keys.generateKeyPair(.Ed25519)             // Ed25519 Elliptic Key\ntry LibP2PCrypto.Keys.generateKeyPair(.Secp256k1)           // Secp256k1 Key\n\n\n/// Importing Marshalled Keys \nlet pubKey = try LibP2PCrypto.Keys.importMarshaledPublicKey(marshaledPublicKeyData)\n/// or using a marshaled private key...\nlet privateKey = try LibP2PCrypto.Keys.importMarshaledPrivateKey(marshaledPrivateKeyData)\n/// or instantiate a KeyPair instead... (if you pass in a public key, the private key will be nil, if you pass in a private key, both public and private keys will be imported/extracted)\nlet keyPair = try LibP2PCrypto.Keys.KeyPair(marshaledPrivateKey: marshaledPrivateKeyData)\nlet keyPair = try LibP2PCrypto.Keys.KeyPair(marshaledPrivateKey: marshaledPrivateKeyAsBase64String, base: .base64Pad) // Or you can use a String encoding of the key data\n\n\n/// Importing PEM files (PEM, Encrypted PEM, DER and CERTIFICATES are supported. See the tests for more examples...)\nlet pem = \"\"\"\n-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEACM3Nzttt7KmXG9qDEYys++oQ9G749jqrbRRs92BUzpA=\n-----END PUBLIC KEY-----\n\"\"\"\n\nlet keyPair = try LibP2PCrypto.Keys.KeyPair(pem: pem)\n\nkeyPair.keyType     // -\u003e .ed25519\nkeyPair.publicKey   // -\u003e Public Key (can be used for verifying signed messages...)\nkeyPair.privateKey  // -\u003e nil (private key is nil when importing public keys...)\n\n/// You can import encrypted PEM files as well...\nlet keyPair = try LibP2PCrypto.Keys.KeyPair(pem: encryptedPem, password: \"mypassword\")\n\n\n/// Once you have a KeyPair, you can use it to.... \n\n/// Sign \u0026 Verify Messages \nlet keyPair = try LibP2PCrypto.Keys.generateKeyPair(.Ed25519)\nlet message = \"Hello, world!\".data(using: .utf8)!\nlet signedData = try keyPair.privateKey!.sign(message: message)\n\nif try keyPair.publicKey.verfiy(signedData, for: message) {\n // The signature is valid! It means that the public key used to verify the signed message was derived from the same private key that signed the message\n} else { \n // Invalid signature. This public key does not belong to the private key that signed the message. \n}\n\n/// If you want to share the public key, you can export it by marshaling it \ntry keyPair.publicKey.marshal()\n\n/// If you want to safely store the Private key between sessions you can export it as an encrypted PEM String\ntry keyPair.exportEncryptedPrivatePEMString(withPassword \"mypassword\")\n\n\n\n/// AES Cipher (streaming encryption cipher)\nlet message = \"Hello World!\"\nlet key256  = \"12345678901234561234567890123456\"   // 32 bytes for AES256\nlet iv      = \"abcdefghijklmnop\"                   // 16 bytes for AES128\n\nlet aes256Key = try LibP2PCrypto.AES.createKey(key: key256, iv: iv)\n\nlet encrypted = try aes256Key.encrypt(message)\nlet decrypted:String = try aes256Key.decrypt(encrypted)\n\n/// AES GCM \nlet message = \"Hello World!\"\nlet encrypted = try message.encryptGCM(password: \"mypassword\")\nlet decrypted = try encrypted.decryptGCM(password: \"mypassword\")\n\n\n\n/// HMAC (Hashed Message Authentication Codes)\nlet message = \"Hello World!\"\nlet key = \"secret\"\nlet hmacKeyLocal = LibP2PCrypto.HMAC.create(algorithm: .SHA256, secret: key)\nlet hmacKeyRemote = LibP2PCrypto.HMAC.create(algorithm: .SHA256, secret: key)\n\nlet encrypted = hmacKeyLocal.encrypt(message)\n\nhmacKeyRemote.verify(message, hash: encrypted)          // -\u003e Returns true. Correct data + correct HMAC == true \nhmacKeyRemote.verify(\"HellØ world!\", hash: encrypted)   // -\u003e Returns false. Corrupted data + correct HMAC == false \n\n\n/// PBKDF2 (password based key derivation function 2)\nlet key = PBKDF2.SHA1(password: \"mypassword\", salt: salt, keyByteCount: 16, rounds: itterations)\n\n\n```\n\n### API\n```Swift\n\n/// Generate Keys\nLibP2PCrypto.Keys.generateKeyPair(_ type:KeyPairType) throws -\u003e KeyPair\n\n/// Import Marshaled Keys\nLibP2PCrypto.Keys.KeyPair(marshaledPublicKey str:String, base:BaseEncoding) throws\nLibP2PCrypto.Keys.KeyPair(marshaledPublicKey data:Data) throws\nLibP2PCrypto.Keys.KeyPair(marshaledPrivateKey str:String, base:BaseEncoding) throws\nLibP2PCrypto.Keys.KeyPair(marshaledPrivateKey data:Data) throws\n\n/// Import PEM formatted Keys\nLibP2PCrypto.Keys.KeyPair(pem:String, password:String? = nil) throws -\u003e KeyPair\nLibP2PCrypto.Keys.KeyPair(pem:Data, password:String? = nil) throws -\u003e KeyPair\n\n/// Sign \u0026 Verify\nRawPrivateKey.sign(message: Data) throws -\u003e Data\nRawPublicKey.verfiy(_ signature: Data, for expectedData:Data) throws -\u003e Bool\n\n/// AES CIPHER\nLibP2PCrypto.AES.createKey(key:String, iv:String) throws -\u003e AESKey\nLibP2PCrypto.AES.AESKey.encrypt(_ data:Data) throws -\u003e Data\nLibP2PCrypto.AES.AESKey.decrypt(_ data: Data) throws -\u003e Data\n\n/// HMAC\nLibP2PCrypto.HMAC.create(algorithm:CryptoAlgorithm, secret:String) -\u003e LibP2PCrypto.HMAC.HMACKey\nLibP2PCrypto.HMAC.HMACKey.encrypt(_ message:Data) -\u003e Data\nLibP2PCrypto.HMAC.HMACKey.verify(_ data:Data, hash:Data) -\u003e Bool\n\n/// PBKDF2\nLibP2PCrypto.PBKDF2.SHA1(password: String, salt: Data, keyByteCount: Int, rounds: Int) -\u003e Data?\nLibP2PCrypto.PBKDF2.SHA256(password: String, salt: Data, keyByteCount: Int = 16, rounds: Int = 32767) -\u003e Data?\nLibP2PCrypto.PBKDF2.SHA512(password: String, salt: Data, keyByteCount: Int, rounds: Int) -\u003e Data?\n\n```\n\n## Contributing\n\nContributions are welcomed! This code is very much a proof of concept. I can guarantee you there's a better / safer way to accomplish the same results. Any suggestions, improvements, or even just critiques, are welcome! \n\nLet's make this code better together! 🤝\n\n## Credits\n\n- [krzyzanowskim - CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)\n- [Koray Koska - Secp256k1](https://github.com/bitcoin-core/secp256k1)\n- [siemensikkema - JWT-Kit](https://github.com/vapor/jwt-kit.git) \n- [RSA Import/Export](https://github.com/nextincrement/rsa-public-key-importer-exporter.git)\n- [CommonCrypto, Crypto-Kit and swift-crypto libraries]\n\n## Resources\n### Links\n- [JWK to PEM](https://github.com/ibm-cloud-security/Swift-JWK-to-PEM)\n- [OpenSSL](https://stackoverflow.com/questions/31380713/how-to-add-openssl-to-a-swift-project)\n- [SecItemExport](https://developer.apple.com/documentation/security/1394828-secitemexport?language=objc)\n- [SwiftyRSA](https://github.com/TakeScoop/SwiftyRSA)\n- [Swift Sodium (Blake2B)](https://github.com/jedisct1/swift-sodium#hashing)\n- [Create a SecKey from a Cert](https://stackoverflow.com/questions/10579985/how-can-i-get-seckeyref-from-der-pem-file)\n- [PEM Thread](https://developer.apple.com/forums/thread/96278)\n- [SECKey from PEM](https://developer.apple.com/forums/thread/104753)\n- [How SwiftyRSA does it](https://github.com/TakeScoop/SwiftyRSA/blob/master/Source/SwiftyRSA.swift#L44)\n- [More PEM Discussion](https://developer.apple.com/forums/thread/85915?answerId=256298022#256298022)\n- [PEM and DER Format](https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem)\n- [ASN.1 Overview](https://www.obj-sys.com/asn1tutorial/node4.html)\n\n## License\n\n[MIT](LICENSE) © 2022 Breth Inc.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswift-libp2p%2Fswift-libp2p-crypto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswift-libp2p%2Fswift-libp2p-crypto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswift-libp2p%2Fswift-libp2p-crypto/lists"}