Skip to content

Releases: r00tedbrain-backup/Securechatskeyboard

SecureChats Keyboard BWT v3.0.1

24 Feb 15:46

Choose a tag to compare

SecureChats Keyboard BWT v3.0.1

Critical bugfix release -- Resolves a FATAL CRASH introduced in v3.0.0 that affected all users on every keyboard invocation.


Critical Fix: Application Crash on Launch

The Problem

After upgrading to libsignal 0.86.5 in v3.0.0, the app crashed immediately every time the keyboard was activated:

FATAL EXCEPTION: main
java.lang.IllegalArgumentException: protocol address is invalid: 
    1e5e3bdf-2d8d-4e8d-8204-64ea2ba387bd.7642
  at org.signal.libsignal.internal.Native.ProtocolAddress_New(Native Method)
  at org.signal.libsignal.protocol.SignalProtocolAddress.<init>
  at ...SignalProtocolMain.initializeProtocol
  at ...LatinIME.onStartInputInternal

This crash made the keyboard completely unusable for all users.

Root Cause

libsignal 0.86.5 introduced two strict validations on SignalProtocolAddress that the previous code violated:

Constraint Required by libsignal 0.86.5 Old code behavior
deviceId range 1 - 127 inclusive Random().nextInt(10000) generated 0 - 9999
name format Valid UUID (ServiceId) Older stored data had UUID.deviceId format

The native Rust layer (ProtocolAddress_New) rejects any address where deviceId > 127 or name is not a valid UUID, throwing an unrecoverable IllegalArgumentException.

The Fix

Added a sanitization layer that intercepts all SignalProtocolAddress construction:

  • sanitizeAddressName(String) -- Extracts a clean UUID from legacy UUID.deviceId stored formats. Falls back to generating a new UUID if the name is completely invalid.
  • sanitizeDeviceId(int) -- Maps any out-of-range deviceId into the valid 1-127 range using modulo arithmetic.
  • createSafeAddress(String, int) -- Factory method used by all code paths that create a SignalProtocolAddress.

All 5 call sites that previously used new SignalProtocolAddress(name, deviceId) directly have been migrated to createSafeAddress():

File Method Context
SignalProtocolMain.java initializeProtocol() New account creation
SignalProtocolMain.java extractContactFromEnvelope() Incoming message processing
JsonUtil.java SignalProtocolAddressDeserializer SharedPreferences reload
Contact.java Constructor Contact deserialization from JSON
E2EEStripView.java addContact() UI contact creation

Migration Compatibility

Users upgrading from older versions (pre-v3.0.0) that had addresses stored in the legacy UUID.deviceId format will have their data automatically migrated on first load -- the sanitizer strips the .deviceId suffix and remaps the deviceId to a valid range. No data loss occurs.


iOS: Keyboard Performance Overhaul

Major rewrite of KeyboardView.swift rendering pipeline to eliminate frame drops and animation jank:

Optimization Impact
Pre-computed shadowPath on all keys Eliminates offscreen rendering (~9ms/frame for 30 keys)
CATransaction.setDisableActions(true) Kills 0.25s implicit CoreAnimation animations
shouldRasterize = true + rasterizationScale GPU caches composited key bitmaps
isOpaque = true everywhere Skips alpha blending calculations
autoresizingMask instead of Auto Layout Fewer constraint solver passes
Shift icon UIImageView reuse No allocation/layout churn on shift toggle
CADisplayLink for delete repeat Frame-synced, jitter-free key repeat
Batched CATransaction blocks Single compositing pass per state change

iOS marketing version bumped to 9.1.0.


Version Details

Platform Version
Android versionCode 13 (up from 2; exceeds Play Store versionCode 12)
Android versionName 3.0.1
iOS Marketing Version 9.1.0

Verification

Tested on physical ZTE device (arm64-v8a, Android 15):

  • Fresh install (no SharedPreferences): initializeProtocol() creates address with valid UUID + deviceId in range 1-127. Kyber/PQC prekey generation succeeds.
  • Existing account reload: Deserializer sanitizes legacy format and loads account without crash.
  • No regressions: Encryption, decryption, contact management, and session establishment all function correctly.

Checksums

SHA-256: 7cd3c9fddc885ea3687efb902338d7197a2c0ba73d9bc8deffdaf217b7d5b23f
File:    SecureChatKeyboard-release-20260224.apk
Size:    18 MB

Download

Platform Link
Android APK Attached below
iOS App Store

SecureChats Keyboard BWT v3.0.0

15 Feb 20:18

Choose a tag to compare

SecureChats Keyboard BWT v3.0.0

Post-Quantum Encrypted Keyboard for Android β€” End-to-end encryption with Signal Protocol + Kyber PQC, directly from your keyboard. No servers. No phone numbers. No internet required.


What's New in v3.0.0

All Dependencies Updated to Latest Stable Versions

Library Previous New Purpose
libsignal-android 0.73.2 0.86.5 Signal Protocol core (E2EE + native PQXDH/Kyber)
jackson-databind 2.14.1 2.18.2 JSON serialization engine
jackson-datatype-jsr310 2.14.1 2.18.2 Java 8+ date/time support
protobuf-javalite 3.21.12 3.25.5 Protocol Buffers (libsignal dependency)
desugar_jdk_libs 2.0.3 2.1.4 Java 8+ API backport for Android
security-crypto 1.1.0-alpha03 1.1.0-alpha06 EncryptedSharedPreferences
bcprov-ext-jdk18on 1.78.1 1.78.1 BouncyCastle PQC (already latest)

libsignal API Migration (Breaking Changes Resolved)

The upgrade from libsignal 0.73.2 to 0.86.5 involved significant API breaking changes that were fully migrated:

  • Curve.generateKeyPair() replaced by ECKeyPair.generate()
  • Curve.calculateSignature(key, data) replaced by key.calculateSignature(data)
  • Curve.decodePoint(bytes, offset) replaced by new ECPublicKey(bytes, offset)
  • markKyberPreKeyUsed(int) updated to markKyberPreKeyUsed(int, int, ECPublicKey) for PQXDH session support
  • IdentityKeyPair(byte[]) now throws checked InvalidKeyException (properly handled)
  • Removed deprecated Curve utility class and Pair imports entirely

Build Verification

  • assembleDebug β€” BUILD SUCCESSFUL
  • compileDebugUnitTestJavaWithJavac β€” BUILD SUCCESSFUL
  • All 9 modified source files compile cleanly with zero errors

Core Features

Hybrid Post-Quantum Encryption

  • Signal Protocol (X3DH + Double Ratchet) β€” Industry-standard E2EE with Perfect Forward Secrecy
  • Kyber-1024 (PQXDH) β€” Native libsignal post-quantum key encapsulation, resistant to Shor's algorithm
  • Kyber-512 (BouncyCastle) β€” Secondary PQC layer via KEM encapsulation/decapsulation
  • Dual key rotation β€” Both ECC and Kyber pre-keys rotate independently every 2 days

Zero-Trust Architecture

  • No internet permission β€” The keyboard requests zero network permissions. All cryptography is fully offline
  • No server β€” Key bundles are shared directly through any messenger (WhatsApp, Telegram, Signal, SMS, etc.)
  • No phone numbers β€” Users identified by randomized UUIDs
  • No plaintext storage β€” All data encrypted at rest with AES-256-GCM via Android Keystore hardware-backed MasterKey
  • No backup leakage β€” android:allowBackup=false prevents cloud backup of encryption keys

Steganography

  • Fairy Tale Mode β€” Encrypted messages hidden inside invisible Unicode characters, appended to decoy fairy tale text (Cinderella, Rapunzel)
  • 16 zero-width Unicode characters map 4-bit groups after GZIP compression and JSON minification
  • Messages appear as innocent fairy tale excerpts to any observer

Full Keyboard

  • 49 keyboard layouts β€” QWERTY, QWERTZ, AZERTY, Dvorak, Colemak, Cyrillic, Arabic, Hindi, Bengali, Thai, Georgian, Armenian, and more
  • 89 language localizations β€” Full i18n coverage
  • Customizable β€” Dark/light themes, custom color picker, adjustable height, haptic and sound feedback
  • E2EE control strip β€” Dedicated encryption interface above the keyboard with 6 switchable views

Contact Verification

  • SHA-512 numeric fingerprints β€” 12-segment security codes with animated reveal
  • Visual comparison β€” Compare 12 five-digit codes between devices to verify identity
  • Per-contact history deletion β€” Cryptographic erasure of message history

Technical Specifications

Spec Value
compileSdk 35 (Android 15)
targetSdk 35
minSdk 26 (Android 8.0 Oreo)
Java 17
Architectures arm64-v8a, armeabi-v7a
License GPL-3.0
F-Droid Compatible (no proprietary dependencies)

Protocol Stores

Store Purpose
IdentityKeyStore Permanent identity key pair and trust decisions
PreKeyStore One-time pre-keys (2 keys, auto-renewed)
SignedPreKeyStore Signed pre-keys with 2-day rotation
SessionStore Per-contact session state
SenderKeyStore Group messaging sender keys
KyberPreKeyStore Native libsignal Kyber-1024 pre-keys
BCKyberPreKeyStore BouncyCastle Kyber-512 pre-keys
PreKeyMetadataStore Rotation schedules and active key IDs

Message Flow

Alice                                    Bob
  |                                        |
  |--- PreKeyBundle (ECC + Kyber keys) --->|  Invite
  |                                        |
  |<-- PreKeySignalMessage ----------------|  Session established
  |                                        |
  |--- SignalMessage ---------------------->|  Double Ratchet
  |<-- SignalMessage -----------------------|
  |         ...                            |
  |--- SignalMessage + Updated PreKeys --->|  Auto key rotation (every 2 days)
  |                                        |

Files Changed in This Release

app/build.gradle                              β€” Updated all dependency versions + packaging rules
SignalProtocolMain.java                       β€” Migrated Curve to ECKeyPair/ECPrivateKey API
PreKeyEntity.java                             β€” Migrated Curve.decodePoint to new ECPublicKey
PreKeyResponse.java                           β€” Updated version comments
KyberPreKeyStoreImpl.java                     β€” Updated markKyberPreKeyUsed signature (3 params)
SignalProtocolStoreImpl.java                  β€” Updated markKyberPreKeyUsed delegation
JsonUtil.java                                 β€” Wrapped IdentityKeyPair InvalidKeyException
KeyUtil.java                                  β€” Removed stale try-catch and unused import
SignalProtocolTest.java                       β€” Migrated test Curve calls

Important Notes

  • This keyboard is designed to work on top of any existing messenger. It encrypts text before you send it.
  • The keyboard itself never connects to the internet. Encryption keys are shared as text messages through your existing apps.
  • Based on the open-source KryptEY project (https://github.com/amnesica/KryptEY) by mellitopia and amnesica, with significant enhancements.