RustNoiseNative.kt

3.4 KB · raw

1package com.peachpasswords.sync23/**4 * Thin JNI boundary over the canonical Rust `snow` state machine.5 *6 * No transcript, key schedule, cipher, or nonce logic belongs in Kotlin.7 */8internal object RustNoiseNative {9    init {10        val explicitPath = System.getProperty("peach.noise.library.path")11        if (explicitPath.isNullOrBlank()) {12            System.loadLibrary("peach_noise_core")13        } else {14            System.load(explicitPath)15        }16    }1718    external fun nativeCreateNkInitiator(remotePublicKey: ByteArray): Long19    external fun nativeCreateNkResponder(20        localPrivateKey: ByteArray,21        localPublicKey: ByteArray,22    ): Long23    external fun nativeCreateNkInitiatorForTest(24        remotePublicKey: ByteArray,25        ephemeralPrivateKey: ByteArray,26    ): Long27    external fun nativeCreateNkResponderForTest(28        localPrivateKey: ByteArray,29        localPublicKey: ByteArray,30        ephemeralPrivateKey: ByteArray,31    ): Long3233    external fun nativeCreateKkInitiator(34        localPrivateKey: ByteArray,35        localPublicKey: ByteArray,36        remotePublicKey: ByteArray,37    ): Long38    external fun nativeCreateKkResponder(39        localPrivateKey: ByteArray,40        localPublicKey: ByteArray,41        remotePublicKey: ByteArray,42    ): Long43    external fun nativeCreateKkInitiatorForTest(44        localPrivateKey: ByteArray,45        localPublicKey: ByteArray,46        remotePublicKey: ByteArray,47        ephemeralPrivateKey: ByteArray,48    ): Long49    external fun nativeCreateKkResponderForTest(50        localPrivateKey: ByteArray,51        localPublicKey: ByteArray,52        remotePublicKey: ByteArray,53        ephemeralPrivateKey: ByteArray,54    ): Long5556    external fun nativeWriteHandshake(handle: Long, payload: ByteArray): ByteArray57    external fun nativeReadHandshake(handle: Long, message: ByteArray): ByteArray58    external fun nativeEncrypt(handle: Long, plaintext: ByteArray): ByteArray59    external fun nativeDecrypt(handle: Long, ciphertext: ByteArray): ByteArray60    external fun nativeHandshakeHash(handle: Long): ByteArray61    external fun nativeRekeyOutgoing(handle: Long)62    external fun nativeRekeyIncoming(handle: Long)63    external fun nativeClose(handle: Long)64}6566internal class RustNoiseSession(67    private var handle: Long,68) : NoiseNKSession {69    private fun openHandle(): Long {70        check(handle != 0L) { "Noise session is closed" }71        return handle72    }7374    fun writeHandshake(payload: ByteArray = ByteArray(0)): ByteArray =75        RustNoiseNative.nativeWriteHandshake(openHandle(), payload)7677    fun readHandshake(message: ByteArray): ByteArray =78        RustNoiseNative.nativeReadHandshake(openHandle(), message)7980    override fun encrypt(plaintext: ByteArray): ByteArray =81        RustNoiseNative.nativeEncrypt(openHandle(), plaintext)8283    override fun decrypt(ciphertext: ByteArray): ByteArray =84        RustNoiseNative.nativeDecrypt(openHandle(), ciphertext)8586    override val handshakeHash: ByteArray87        get() = RustNoiseNative.nativeHandshakeHash(openHandle())8889    override fun rekeyOutgoing() {90        RustNoiseNative.nativeRekeyOutgoing(openHandle())91    }9293    override fun rekeyIncoming() {94        RustNoiseNative.nativeRekeyIncoming(openHandle())95    }9697    override fun close() {98        val value = handle99        if (value == 0L) return100        handle = 0L101        RustNoiseNative.nativeClose(value)102    }103}104