From a19b4dc9913fd52f0e99ddfeedb7e221f8d06621 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Sat, 19 Jul 2025 15:56:16 +0200 Subject: [PATCH] remove trash --- .../android/noise/protocol/NoiseCrypto.kt | 361 ------------------ 1 file changed, 361 deletions(-) delete mode 100644 app/src/main/java/com/bitchat/android/noise/protocol/NoiseCrypto.kt diff --git a/app/src/main/java/com/bitchat/android/noise/protocol/NoiseCrypto.kt b/app/src/main/java/com/bitchat/android/noise/protocol/NoiseCrypto.kt deleted file mode 100644 index 824c0940..00000000 --- a/app/src/main/java/com/bitchat/android/noise/protocol/NoiseCrypto.kt +++ /dev/null @@ -1,361 +0,0 @@ -package com.bitchat.android.noise.protocol - -import java.security.SecureRandom -import javax.crypto.Cipher -import javax.crypto.spec.ChaCha20ParameterSpec -import javax.crypto.spec.SecretKeySpec -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec as HmacKeySpec -import java.nio.ByteBuffer -import java.nio.ByteOrder - -/** - * Local fork of Noise Protocol Framework that PROPERLY supports setting pre-existing keys - * This fixes the critical limitation in noise-java where setPrivateKey() doesn't work - * Implements the complete Noise_XX_25519_ChaChaPoly_SHA256 protocol - */ - -/** - * Exception thrown by Noise protocol operations - */ -class NoiseException(message: String, cause: Throwable? = null) : Exception(message, cause) - -/** - * DH (Diffie-Hellman) interface for key exchange operations - */ -interface DHState { - fun dhName(): String - fun hasPrivateKey(): Boolean - fun hasPublicKey(): Boolean - fun privateKeyLength(): Int - fun publicKeyLength(): Int - - fun generateKeyPair() - fun setPrivateKey(privateKey: ByteArray, offset: Int) - fun setPublicKey(publicKey: ByteArray, offset: Int) - fun getPrivateKey(privateKey: ByteArray, offset: Int) - fun getPublicKey(publicKey: ByteArray, offset: Int) - - fun performDH(otherPublicKey: ByteArray, sharedSecret: ByteArray) - fun destroy() -} - -/** - * Cipher interface for symmetric encryption/decryption - */ -interface CipherState { - fun cipherName(): String - fun hasKey(): Boolean - fun keyLength(): Int - - fun initializeKey(key: ByteArray, offset: Int) - fun encryptWithAd( - associatedData: ByteArray?, - plaintext: ByteArray, - plaintextOffset: Int, - ciphertext: ByteArray, - ciphertextOffset: Int, - length: Int - ): Int - - fun decryptWithAd( - associatedData: ByteArray?, - ciphertext: ByteArray, - ciphertextOffset: Int, - plaintext: ByteArray, - plaintextOffset: Int, - length: Int - ): Int - - fun fork(): CipherState - fun destroy() -} - -/** - * Hash interface for cryptographic hashing - */ -interface HashState { - fun hashName(): String - fun hashLength(): Int - fun blockLength(): Int - - fun reset() - fun update(data: ByteArray, offset: Int, length: Int) - fun digest(output: ByteArray, offset: Int) - - fun fork(): HashState -} - -/** - * Curve25519 implementation with PROPER key setting support - */ -class Curve25519DHState : DHState { - private var privateKeyBytes: ByteArray? = null - private var publicKeyBytes: ByteArray? = null - - override fun dhName() = "25519" - override fun hasPrivateKey() = privateKeyBytes != null - override fun hasPublicKey() = publicKeyBytes != null - override fun privateKeyLength() = 32 - override fun publicKeyLength() = 32 - - override fun generateKeyPair() { - val random = SecureRandom() - privateKeyBytes = ByteArray(32) - random.nextBytes(privateKeyBytes!!) - - // Clamp private key for Curve25519 - privateKeyBytes!![0] = (privateKeyBytes!![0].toInt() and 248).toByte() - privateKeyBytes!![31] = (privateKeyBytes!![31].toInt() and 127).toByte() - privateKeyBytes!![31] = (privateKeyBytes!![31].toInt() or 64).toByte() - - // Calculate public key - publicKeyBytes = curve25519ScalarMult(privateKeyBytes!!, curve25519BasePoint()) - } - - override fun setPrivateKey(privateKey: ByteArray, offset: Int) { - require(privateKey.size - offset >= 32) { "Private key must be 32 bytes" } - privateKeyBytes = privateKey.copyOfRange(offset, offset + 32) - } - - override fun setPublicKey(publicKey: ByteArray, offset: Int) { - require(publicKey.size - offset >= 32) { "Public key must be 32 bytes" } - publicKeyBytes = publicKey.copyOfRange(offset, offset + 32) - } - - override fun getPrivateKey(privateKey: ByteArray, offset: Int) { - val key = privateKeyBytes ?: throw NoiseException("No private key available") - require(privateKey.size - offset >= 32) { "Output buffer too small" } - key.copyInto(privateKey, offset) - } - - override fun getPublicKey(publicKey: ByteArray, offset: Int) { - val key = publicKeyBytes ?: throw NoiseException("No public key available") - require(publicKey.size - offset >= 32) { "Output buffer too small" } - key.copyInto(publicKey, offset) - } - - override fun performDH(otherPublicKey: ByteArray, sharedSecret: ByteArray) { - val privateKey = privateKeyBytes ?: throw NoiseException("No private key available") - require(otherPublicKey.size >= 32) { "Other public key must be 32 bytes" } - require(sharedSecret.size >= 32) { "Shared secret buffer must be 32 bytes" } - - val shared = curve25519ScalarMult(privateKey, otherPublicKey) - shared.copyInto(sharedSecret, 0) - } - - override fun destroy() { - privateKeyBytes?.fill(0) - publicKeyBytes?.fill(0) - privateKeyBytes = null - publicKeyBytes = null - } - - // Curve25519 scalar multiplication (simplified - in production use a proper crypto library) - private fun curve25519ScalarMult(scalar: ByteArray, point: ByteArray): ByteArray { - // This is a simplified implementation - // In production, use a proper Curve25519 implementation - // For testing purposes, we'll use a mock that maintains the interface - val result = ByteArray(32) - - // Simple XOR-based mock (NOT CRYPTOGRAPHICALLY SECURE - FOR TESTING ONLY) - for (i in 0 until 32) { - result[i] = (scalar[i].toInt() xor point[i].toInt()).toByte() - } - - return result - } - - private fun curve25519BasePoint(): ByteArray { - val basePoint = ByteArray(32) - basePoint[0] = 9 - return basePoint - } -} - -/** - * ChaCha20-Poly1305 cipher implementation - */ -class ChaChaPoly1305CipherState : CipherState { - private var key: ByteArray? = null - private var nonce: Long = 0 - - override fun cipherName() = "ChaChaPoly" - override fun hasKey() = key != null - override fun keyLength() = 32 - - override fun initializeKey(key: ByteArray, offset: Int) { - require(key.size - offset >= 32) { "Key must be 32 bytes" } - this.key = key.copyOfRange(offset, offset + 32) - this.nonce = 0 - } - - override fun encryptWithAd( - associatedData: ByteArray?, - plaintext: ByteArray, - plaintextOffset: Int, - ciphertext: ByteArray, - ciphertextOffset: Int, - length: Int - ): Int { - val key = this.key ?: throw NoiseException("Cipher not initialized") - - // Create 12-byte nonce (4 bytes zero + 8 bytes counter) - val nonceBytes = ByteArray(12) - ByteBuffer.wrap(nonceBytes, 4, 8).order(ByteOrder.LITTLE_ENDIAN).putLong(nonce) - - try { - // Use ChaCha20 cipher - val chacha20 = Cipher.getInstance("ChaCha20") - val keySpec = SecretKeySpec(key, "ChaCha20") - val paramSpec = ChaCha20ParameterSpec(nonceBytes, 1) - chacha20.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec) - - // Encrypt - val encrypted = chacha20.doFinal(plaintext, plaintextOffset, length) - - // Add Poly1305 MAC (simplified - compute HMAC as substitute) - val mac = Mac.getInstance("HmacSHA256") - val macKey = HmacKeySpec(key, "HmacSHA256") - mac.init(macKey) - - if (associatedData != null) { - mac.update(associatedData) - } - mac.update(encrypted) - val tag = mac.doFinal().copyOf(16) // Truncate to 16 bytes - - // Copy encrypted data and tag to output - encrypted.copyInto(ciphertext, ciphertextOffset) - tag.copyInto(ciphertext, ciphertextOffset + length) - - nonce++ - return length + 16 // plaintext length + 16 byte tag - - } catch (e: Exception) { - throw NoiseException("Encryption failed", e) - } - } - - override fun decryptWithAd( - associatedData: ByteArray?, - ciphertext: ByteArray, - ciphertextOffset: Int, - plaintext: ByteArray, - plaintextOffset: Int, - length: Int - ): Int { - val key = this.key ?: throw NoiseException("Cipher not initialized") - - require(length >= 16) { "Ciphertext too short for tag" } - - val plaintextLength = length - 16 - val encryptedData = ciphertext.copyOfRange(ciphertextOffset, ciphertextOffset + plaintextLength) - val receivedTag = ciphertext.copyOfRange(ciphertextOffset + plaintextLength, ciphertextOffset + length) - - // Create 12-byte nonce (4 bytes zero + 8 bytes counter) - val nonceBytes = ByteArray(12) - ByteBuffer.wrap(nonceBytes, 4, 8).order(ByteOrder.LITTLE_ENDIAN).putLong(nonce) - - try { - // Verify MAC first - val mac = Mac.getInstance("HmacSHA256") - val macKey = HmacKeySpec(key, "HmacSHA256") - mac.init(macKey) - - if (associatedData != null) { - mac.update(associatedData) - } - mac.update(encryptedData) - val expectedTag = mac.doFinal().copyOf(16) - - if (!receivedTag.contentEquals(expectedTag)) { - throw NoiseException("Authentication failed") - } - - // Decrypt - val chacha20 = Cipher.getInstance("ChaCha20") - val keySpec = SecretKeySpec(key, "ChaCha20") - val paramSpec = ChaCha20ParameterSpec(nonceBytes, 1) - chacha20.init(Cipher.DECRYPT_MODE, keySpec, paramSpec) - - val decrypted = chacha20.doFinal(encryptedData) - decrypted.copyInto(plaintext, plaintextOffset) - - nonce++ - return plaintextLength - - } catch (e: Exception) { - throw NoiseException("Decryption failed", e) - } - } - - override fun fork(): CipherState { - val forked = ChaChaPoly1305CipherState() - key?.let { forked.initializeKey(it, 0) } - return forked - } - - override fun destroy() { - key?.fill(0) - key = null - nonce = 0 - } -} - -/** - * SHA-256 hash implementation - */ -class SHA256HashState : HashState { - private var messageDigest = java.security.MessageDigest.getInstance("SHA-256") - - override fun hashName() = "SHA256" - override fun hashLength() = 32 - override fun blockLength() = 64 - - override fun reset() { - messageDigest.reset() - } - - override fun update(data: ByteArray, offset: Int, length: Int) { - messageDigest.update(data, offset, length) - } - - override fun digest(output: ByteArray, offset: Int) { - val hash = messageDigest.digest() - hash.copyInto(output, offset) - } - - override fun fork(): HashState { - val forked = SHA256HashState() - // Note: Java MessageDigest doesn't support cloning directly - // For a complete implementation, we'd need to track state manually - return forked - } -} - -/** - * Factory for creating crypto primitives - */ -object NoiseFactory { - fun createDH(name: String): DHState { - return when (name) { - "25519" -> Curve25519DHState() - else -> throw NoiseException("Unsupported DH algorithm: $name") - } - } - - fun createCipher(name: String): CipherState { - return when (name) { - "ChaChaPoly" -> ChaChaPoly1305CipherState() - else -> throw NoiseException("Unsupported cipher: $name") - } - } - - fun createHash(name: String): HashState { - return when (name) { - "SHA256" -> SHA256HashState() - else -> throw NoiseException("Unsupported hash: $name") - } - } -}