{"id":31811197,"url":"https://github.com/ditzdev/libsignal-rust","last_synced_at":"2025-10-11T06:39:49.680Z","repository":{"id":314638034,"uuid":"1056249023","full_name":"DitzDev/libsignal-rust","owner":"DitzDev","description":"A complete Rust implementation of the Signal messaging protocol.","archived":false,"fork":false,"pushed_at":"2025-09-13T17:42:29.000Z","size":26,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-13T19:31:49.357Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/DitzDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-13T17:31:58.000Z","updated_at":"2025-09-13T17:42:32.000Z","dependencies_parsed_at":"2025-09-13T19:31:51.432Z","dependency_job_id":"bcd83106-9aaa-42d7-b9e8-8a1ab753d39a","html_url":"https://github.com/DitzDev/libsignal-rust","commit_stats":null,"previous_names":["ditzdev/libsignal-rust"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/DitzDev/libsignal-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DitzDev%2Flibsignal-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DitzDev%2Flibsignal-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DitzDev%2Flibsignal-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DitzDev%2Flibsignal-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DitzDev","download_url":"https://codeload.github.com/DitzDev/libsignal-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DitzDev%2Flibsignal-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006451,"owners_count":26084107,"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-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","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":[],"created_at":"2025-10-11T06:39:47.809Z","updated_at":"2025-10-11T06:39:49.671Z","avatar_url":"https://github.com/DitzDev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LibSignal Rust\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://crates.io/crates/libsignal-rust\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/libsignal-rust.svg?label=libsignal-rust\u0026color=blue\" alt=\"Crates.io\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://docs.rs/libsignal-rust\"\u003e\n    \u003cimg src=\"https://docs.rs/libsignal-rust/badge.svg\" alt=\"Docs.rs\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/DitzDev/libsignal-rust/blob/main/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nA complete Rust implementation of the Signal messaging protocol, providing secure end-to-end encryption for messaging applications. This library offers full protocol compatibility with Signal's cryptographic primitives while leveraging Rust's safety and performance benefits.\n\n## Features\n\n- **End-to-End Encryption**: Full Signal protocol implementation with Perfect Forward Secrecy.\n- **Double Ratchet Algorithm**: Advanced key management for secure message chains.\n- **Industry-Standard Cryptography**: Curve25519 key agreement, Ed25519 signatures, AES-256-CBC encryption, HMAC-SHA256 authentication.\n- **Multiple Message Types**: Supports WhisperMessage, PreKeyWhisperMessage, and KeyExchangeMessage.\n- **Protocol Buffer Integration**: Complete protobuf serialization/deserialization.\n- **Session Management**: Automatic session initialization, key rotation, and state persistence.\n- **Memory Safe**: Leverages Rust's ownership model to prevent security vulnerabilities.\n- **Zero-Copy Operations**: Efficient message processing with minimal allocations.\n- **Async/Await Support**: Modern asynchronous programming patterns throughout.\n- **Comprehensive API**: Easy-to-use interfaces for session management and message encryption.\n- **Rich Error Handling**: Detailed error types and proper error propagation.\n- **Extensive Testing**: Full test coverage for cryptographic, session, and protocol buffer components.\n\n---\n\n## Quick Start\n\n### Installation\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nlibsignal-rust = \"0.1.0\"\n```\n\n### Basic Usage\n\n```rust\nuse libsignal_rust::{SessionCipher, SessionBuilder, ProtocolAddress};\nuse std::sync::Arc;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // Create a protocol address for the recipient\n    let remote_address = ProtocolAddress::new(\"alice@example.com\".to_string(), 1)?;\n    \n    // Initialize your storage implementation\n    let storage = Arc::new(YourStorageImpl::new());\n    \n    // Create session cipher for encryption/decryption\n    let cipher = SessionCipher::new(storage.clone(), remote_address.clone());\n    \n    // Encrypt a message\n    let plaintext = b\"Hello, secure world!\";\n    let ciphertext_message = cipher.encrypt(plaintext).await?;\n    \n    println!(\"Encrypted message type: {}\", ciphertext_message.message_type);\n    println!(\"Encrypted body length: {}\", ciphertext_message.body.len());\n    \n    Ok(())\n}\n```\n\n## Core Components\n\n### SessionCipher\n\nThe main interface for encrypting and decrypting messages:\n\n```rust\nuse libsignal_rust::{SessionCipher, CiphertextMessage};\n\n// Encrypt a message\nlet message = b\"Secret message\";\nlet encrypted: CiphertextMessage = cipher.encrypt(message).await?;\n\n// Decrypt a message  \nlet decrypted: Vec\u003cu8\u003e = cipher.decrypt(\u0026encrypted).await?;\nlet original_message = String::from_utf8(decrypted)?;\n```\n\n### SessionBuilder\n\nManages session initialization and key exchange:\n\n```rust\nuse libsignal_rust::{SessionBuilder, Device, PreKeyBundle, SignedPreKeyBundle};\n\n// Create session builder\nlet remote_address = ProtocolAddress::new(\"alice@example.com\".to_string(), 1)?;\nlet builder = SessionBuilder::new(storage, remote_address);\n\n// Initialize outgoing session\nlet device = Device {\n    registration_id: 12345,\n    identity_key: identity_key_bytes,\n    signed_pre_key: SignedPreKeyBundle {\n        key_id: 1,\n        public_key: signed_prekey_bytes,\n        signature: signature_bytes,\n    },\n    pre_key: Some(PreKeyBundle {\n        key_id: 2,\n        public_key: prekey_bytes,\n    }),\n};\n\nbuilder.init_outgoing(device).await?;\n```\n\n### Key Generation\n\nGenerate cryptographic keys for your application:\n\n```rust\nuse libsignal_rust::{keyhelper, curve};\n\n// Generate identity key pair\nlet identity_keys = keyhelper::generate_identity_key_pair();\n\n// Generate pre-keys\nlet pre_key = keyhelper::generate_pre_key(1);\nlet signed_pre_key = keyhelper::generate_signed_pre_key(\u0026identity_keys, 1)?;\n\n// Generate signing key pair for Ed25519 signatures\nlet signing_keys = curve::generate_signing_key_pair();\n```\n\n## Storage Implementation\n\nImplement the `SessionStorage` trait to provide persistence:\n\n```rust\nuse libsignal_rust::{SessionStorage, SessionRecord, KeyPair};\nuse async_trait::async_trait;\n\npub struct YourStorageImpl {\n    // Your storage backend (database, file system, etc.)\n}\n\n#[async_trait]\nimpl SessionStorage for YourStorageImpl {\n    async fn is_trusted_identity(\u0026self, address: \u0026str, identity_key: \u0026[u8]) -\u003e bool {\n        // Implement identity verification logic\n        true\n    }\n    \n    async fn load_session(\u0026self, address: \u0026str) -\u003e Option\u003cSessionRecord\u003e {\n        // Load session from your storage backend\n        None\n    }\n    \n    async fn store_session(\u0026self, address: \u0026str, record: SessionRecord) {\n        // Store session to your storage backend\n    }\n    \n    async fn load_pre_key(\u0026self, pre_key_id: u32) -\u003e Option\u003cKeyPair\u003e {\n        // Load pre-key by ID\n        None\n    }\n    \n    async fn load_signed_pre_key(\u0026self, signed_pre_key_id: u32) -\u003e Option\u003cKeyPair\u003e {\n        // Load signed pre-key by ID  \n        None\n    }\n    \n    async fn get_our_identity(\u0026self) -\u003e KeyPair {\n        // Return your identity key pair\n        KeyPair {\n            priv_key: vec![],\n            pub_key: vec![],\n        }\n    }\n}\n```\n\n## Protocol Buffer Messages\n\nThe library uses protocol buffers for message serialization:\n\n```rust\nuse prost::Message;\nuse libsignal_rust::protos::{WhisperMessage, PreKeyWhisperMessage};\n\n// Decode a received message\nlet whisper_msg = WhisperMessage::decode(message_bytes)?;\nprintln!(\"Message counter: {}\", whisper_msg.counter);\n\n// Encode a message for transmission\nlet encoded = whisper_msg.encode_to_vec();\n```\n\n## Testing\n\nRun the comprehensive test suite:\n\n```bash\n# Run all tests\ncargo test\n\n# Run specific test categories\ncargo test --test crypto_tests      # Cryptographic primitives\ncargo test --test curve_tests       # Elliptic curve operations  \ncargo test --test session_tests     # Session management\ncargo test --test protobuf_tests    # Protocol buffer serialization\n```\n\n## Advanced Usage\n\n### Custom Message Processing\n\n```rust\nuse libsignal_rust::{crypto, curve};\n\n// Direct cryptographic operations\nlet key = b\"32-byte-encryption-key-here!!!!!!\";\nlet iv = b\"16-byte-iv-here!\"; \nlet plaintext = b\"Hello World\";\n\nlet ciphertext = crypto::encrypt(key, plaintext, iv)?;\nlet decrypted = crypto::decrypt(key, \u0026ciphertext, iv)?;\n\n// ECDH key agreement\nlet alice_keys = curve::generate_key_pair();\nlet bob_keys = curve::generate_key_pair();\nlet shared_secret = curve::calculate_agreement(\u0026bob_keys.pub_key, \u0026alice_keys.priv_key)?;\n```\n\n### Error Handling\n\nThe library provides detailed error types for different failure scenarios:\n\n```rust\nuse libsignal_rust::{SessionCipher, errors::*};\n\nmatch cipher.decrypt(\u0026message).await {\n    Ok(plaintext) =\u003e println!(\"Decrypted successfully\"),\n    Err(e) =\u003e match e.downcast_ref::\u003cUntrustedIdentityKeyError\u003e() {\n        Some(identity_error) =\u003e {\n            println!(\"Untrusted identity: {}\", identity_error.addr);\n        }\n        None =\u003e println!(\"Other error: {}\", e),\n    }\n}\n```\n\n## Architecture\n\n### Security Design\n- **Memory Safe**: All cryptographic operations use Rust's ownership system to prevent buffer overflows and use-after-free vulnerabilities\n- **Constant-Time Operations**: Uses libraries designed to resist timing attacks\n- **Forward Secrecy**: Automatic key rotation ensures past messages remain secure even if current keys are compromised\n\n### Protocol Compatibility\n- **Signal Protocol v3**: Full compatibility with Signal's current protocol version\n- **Cross-Platform**: Generated protocol buffers ensure compatibility with other Signal implementations\n- **Standard Cryptography**: Uses widely-audited cryptographic libraries\n\n## Documentation\nWe will be creating comprehensive and clear documentation soon. For now, check out our documentation on the rust registry.\n\n- [API Documentation](https://docs.rs/libsignal-rust) - Complete API reference\n\n## Contributing\n\nContributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) and ensure all tests pass:\n\n```bash\ncargo fmt\ncargo clippy\ncargo test\n```\n\n## License\n```\nMIT License\n\nCopyright (c) 2025 DitzDev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fditzdev%2Flibsignal-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fditzdev%2Flibsignal-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fditzdev%2Flibsignal-rust/lists"}