Skip to content

πŸ”’οΈπŸ“±This repository demonstrates a secure communication using the Signal protocol in both 1:1 and group messaging scenarios. Written in Dart, created as a Flutter project.

License

Notifications You must be signed in to change notification settings

stdNullPtr/Flutter-Signal-Protocol-PoC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flutter Signal Protocol Client - Proof of Concept

A proof-of-concept implementation of the Signal Protocol in Flutter/Dart, demonstrating end-to-end encrypted messaging through executable test scenarios.
Credits go to https://github.com/MixinNetwork/libsignal_protocol_dart for the core implementation of the protocol for Dart.

🎯 Purpose

This repository serves as a technical demonstration of Signal Protocol implementation in Dart. Rather than being a runnable application, it provides a comprehensive test suite that showcases:

  • Complete Signal Protocol implementation
  • Key exchange mechanisms
  • Session establishment and proper acknowledgment
  • Message encryption/decryption
  • Multi-user communication scenarios
  • Multi-device support per user
  • Group messaging

Important: This codebase is designed to be explored through its test suite. The tests serve as living documentation and executable examples of the Signal Protocol implementation.

πŸ“‹ Requirements

  • Flutter >=3.7.2 (Developed with 3.16.9)
  • Dart >=3.7.2 (Developed with 3.2.6)

πŸ› οΈ Installation

# Clone the repository
git clone https://github.com/stdNullPtr/Flutter-Signal-Protocol-PoC.git
cd Flutter-Signal-Protocol-PoC

# Install dependencies
flutter pub get

# Generate Freezed code
flutter pub run build_runner build --delete-conflicting-outputs

πŸ—οΈ Architecture

Core Implementation

SignalClient (lib/client/signal_client.dart)

The main Signal Protocol implementation featuring:

  • Identity key pair generation and management
  • PreKey bundle creation and distribution
  • Session establishment with other users
  • Proper session acknowledgment for Double Ratchet initialization
  • Message encryption using the Double Ratchet algorithm
  • Message decryption and session management
  • Multi-device support through device-specific sessions
  • Group messaging with sender key distribution

SignalClientState (lib/client/signal_client.freezed.dart)

Immutable state management using Freezed, containing:

  • User identity keys
  • PreKey and signed PreKey stores
  • Active sessions cache
  • Pending messages queue
  • One-time PreKey management

Supporting Infrastructure

Data Models

  • UserKeys (lib/server/models/user_keys.dart): Represents a user's PreKey bundle for key exchange
  • Message (lib/common/models/message.dart): Encapsulates encrypted message data
  • GroupMessage (lib/common/models/group_message.dart): Represents encrypted group messages
  • PublicPreKey & PublicSignedPreKey (lib/server/models/): Key structures for exchange

(Mock) Server Communication (lib/server/server.dart)

  • PreKey bundle upload and retrieval
  • Encrypted message routing
  • Message acknowledgment handling
  • Multi-device awareness
  • Group membership management

Utilities

  • Logger (lib/utils/logger.dart): Logging utility for debugging

Project Structure

lib/
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ signal_client.dart             # Signal Protocol implementation
β”‚   └── signal_client.freezed.dart     # Generated immutable state
β”œβ”€β”€ common/
β”‚   └── models/
β”‚       β”œβ”€β”€ message.dart               # Message structure
β”‚       └── group_message.dart         # Group message support
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ user_keys.dart             # PreKey bundle model
β”‚   β”‚   β”œβ”€β”€ public_prekey.dart         # Public PreKey structure
β”‚   β”‚   └── public_signed_prekey.dart  # Signed PreKey structure
β”‚   └── server.dart                    # Server API client
└── utils/
    └── logger.dart                    # Logging utility

test/
β”œβ”€β”€ signal_protocol_test.dart          # Comprehensive test scenarios
β”œβ”€β”€ key_reuse_test.dart                # Tests for key reuse prevention
└── multi_device_test.dart             # Tests for multi-device support

πŸ§ͺ Understanding the Implementation Through Tests

The test suites serve as the primary documentation for this PoC. Each test file demonstrates specific aspects of the Signal Protocol:

  • test/signal_protocol_test.dart: Core protocol implementation scenarios
  • test/key_reuse_test.dart: Security tests for preventing key reuse attacks
  • test/multi_device_test.dart: Tests for multi-device support

Running the Test Suite

# Run all test scenarios
flutter test

# Run with verbose output to see the implementation in action
flutter test --reporter expanded

# Run a specific test scenario
flutter test --name "should establish session and exchange messages"

Test Scenarios

  1. Basic Key Generation

    • Demonstrates identity key creation
    • Shows PreKey bundle generation
    • Validates cryptographic material
  2. PreKey Bundle Exchange

    • Shows how users publish their PreKey bundles
    • Demonstrates bundle retrieval from server
    • Validates bundle integrity
  3. Session Establishment

    • Illustrates initial session creation
    • Shows the X3DH key agreement protocol
    • Demonstrates session caching
    • Properly acknowledges and transitions session states
  4. Message Exchange

    • Shows complete message encryption flow
    • Demonstrates the Double Ratchet algorithm
    • Illustrates proper message type transitions (prekey β†’ whisper)
    • Illustrates message decryption
  5. Multi-User Scenarios

    • Complex interactions between multiple users
    • Concurrent session management
    • Message ordering and delivery
  6. Multi-Device Support

    • Multiple devices for a single user
    • Proper message routing to all user devices
    • Independent session management per device
  7. Group Messaging

    • Sender key distribution for groups
    • Group membership management
    • Encrypted group communication
    • Handling members joining existing groups
  8. Key Reuse Prevention (in key_reuse_test.dart)

    • Ensures one-time PreKeys are not reused
    • Validates security against key reuse attacks
    • Tests proper key rotation mechanisms

Each test includes comprehensive logging that explains what's happening at each step of the protocol. To see detailed logs while running tests, use the --reporter expanded flag. The test output can also be seen in the GitHub Actions workflow: https://github.com/stdNullPtr/Flutter-Signal-Protocol-PoC/actions

Signal Protocol Test Workflow

πŸ” Key Components Explained

Signal Protocol Implementation

The implementation follows the Signal Protocol specification:

  1. Identity Keys: Long-term Curve25519 key pairs
  2. Signed PreKey: Medium-term keys with signatures
  3. One-Time PreKeys: Ephemeral keys for perfect forward secrecy
  4. Sessions: Established using X3DH (Extended Triple Diffie-Hellman)
  5. Double Ratchet: Provides forward secrecy and break-in recovery
  6. Session Acknowledgment: Ensures proper state transitions for the ratchet
  7. Multi-Device Support: Manages separate cryptographic sessions for each device
  8. Group Messaging: Uses sender keys for efficient group communication

State Management

Uses Freezed for immutable state management:

  • Ensures thread safety
  • Prevents accidental state mutations
  • Provides efficient state updates through copying

Server Integration

The implementation requires a compatible server that:

  • Stores and serves PreKey bundles
  • Routes encrypted messages between users and devices
  • Manages group membership
  • Never has access to plaintext content

πŸ”’ Security Considerations

This PoC demonstrates the following security properties:

  • End-to-End Encryption: Messages are encrypted on the sender's device and decrypted on the recipient's device
  • Perfect Forward Secrecy: Compromised keys don't affect past communications
  • Break-in Recovery: Compromised keys don't affect future communications
  • Deniable Authentication: Messages can be authenticated by the recipient but anyone could have forged messages after the conversation - protecting users from being cryptographically proven to have sent a message
  • Multi-Device Security: Each device maintains its own cryptographic session, preventing compromise of all devices if one is breached

🚦 What This PoC Demonstrates

βœ… Complete Signal Protocol implementation in Dart
βœ… Proper key management and rotation
βœ… Session establishment between users
βœ… Session acknowledgment and state management
βœ… Message encryption and decryption
βœ… Multi-user communication patterns
βœ… Multi-device support per user
βœ… Group messaging with sender keys
βœ… Server integration for key exchange

🚫 What This PoC Doesn't Include

❌ User interface implementation
❌ Persistent storage of keys and sessions
❌ Production-ready error handling
❌ Message delivery guarantees
❌ Media/file encryption
❌ Comprehensive cryptographic auditing

πŸ“š Learning from the Code

To understand the Signal Protocol implementation:

  1. Start with the main test file: test/signal_protocol_test.dart
  2. Follow the test scenarios in order
  3. Review security tests in test/key_reuse_test.dart
  4. Explore multi-device capabilities in test/multi_device_test.dart
  5. Examine the SignalClient implementation in lib/client/signal_client.dart
  6. Review the state management in SignalClientState
  7. Understand the server interactions in lib/server/server.dart
  8. Explore the data models in lib/common/models/ and lib/server/models/

Key Signal Protocol Features Explained

Session Acknowledgment

The PoC implements proper session acknowledgment, which is crucial for the Double Ratchet algorithm:

  • Initial messages use PreKey messages (containing X3DH materials)
  • After session establishment, a cryptographic acknowledgment occurs
  • When receiving a PreKey message, the receiver creates a session
  • The receiver acknowledges the session by clearing unacknowledged PreKey flag
  • Subsequent messages use the more efficient "whisper" message type
  • This follows the Signal Protocol's security design for session establishment

Multi-Device Support

The implementation demonstrates how Signal handles multiple devices for a single user:

  • Each device has its own identity and cryptographic material
  • Messages sent to a user are delivered to all their devices
  • Each device maintains independent sessions with other users' devices
  • This models Signal's approach to multi-device support

Group Messaging

Group messaging is implemented using sender keys:

  • Each member distributes their sender key to the group
  • Messages are efficiently encrypted once and distributed to all members
  • New members can join existing groups
  • This matches Signal's efficient approach to group communication

πŸ”— References

🀝 Contributing

This is a proof-of-concept implementation. Contributions should focus on:

  • Improving test coverage and scenarios
  • Adding clarifying documentation
  • Fixing implementation issues
  • Demonstrating additional protocol features

πŸ“„ License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

The GPL-3.0 license ensures that:

  • Source code must be made available when distributed
  • Modifications must be released under the same license
  • Commercial use is allowed only if the source code is provided
  • Patent rights are granted to users

This proof-of-concept demonstrates how the Signal Protocol can be implemented in Flutter/Dart. Explore the test suite to understand the implementation details.

About

πŸ”’οΈπŸ“±This repository demonstrates a secure communication using the Signal protocol in both 1:1 and group messaging scenarios. Written in Dart, created as a Flutter project.

Topics

Resources

License

Stars

Watchers

Forks

Languages