package com.peachpasswords.sync internal data class NoiseKKKeyPair( val publicKey: ByteArray, val secretKey: ByteArray, ) /** * Standard unmodified Noise KK reconnect through the canonical Rust core. * Both static keys are supplied from durable local pairing state; there is no * NK downgrade or peer-controlled key selection. */ internal suspend fun noiseKKInitiator( ourStaticPrivateKey: ByteArray, ourStaticPublicKey: ByteArray, responderStaticPublicKey: ByteArray, send: suspend (ByteArray) -> Unit, receive: suspend () -> ByteArray, ephemeral: NoiseKKKeyPair? = null, ): NoiseNKSession { val native = RustNoiseSession( if (ephemeral == null) { RustNoiseNative.nativeCreateKkInitiator( ourStaticPrivateKey, ourStaticPublicKey, responderStaticPublicKey, ) } else { RustNoiseNative.nativeCreateKkInitiatorForTest( ourStaticPrivateKey, ourStaticPublicKey, responderStaticPublicKey, ephemeral.secretKey, ) }, ) return try { send(native.writeHandshake()) native.readHandshake(receive()) native } catch (error: Throwable) { native.close() throw error } } internal suspend fun noiseKKResponder( ourStaticPrivateKey: ByteArray, ourStaticPublicKey: ByteArray, expectedInitiatorStaticPublicKey: ByteArray, send: suspend (ByteArray) -> Unit, receive: suspend () -> ByteArray, ephemeral: NoiseKKKeyPair? = null, ): NoiseNKSession { val native = RustNoiseSession( if (ephemeral == null) { RustNoiseNative.nativeCreateKkResponder( ourStaticPrivateKey, ourStaticPublicKey, expectedInitiatorStaticPublicKey, ) } else { RustNoiseNative.nativeCreateKkResponderForTest( ourStaticPrivateKey, ourStaticPublicKey, expectedInitiatorStaticPublicKey, ephemeral.secretKey, ) }, ) return try { native.readHandshake(receive()) send(native.writeHandshake()) native } catch (error: Throwable) { native.close() throw error } }