From 24a575015586b4059ae6710a28050cfcafa359c0 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 15 Sep 2025 16:14:43 -0400 Subject: [PATCH] Generalizes fixed key setup --- .../quartz/nip44Encryption/crypto/FixedKey.kt | 46 +++++++++++++++++++ .../quartz/nip44Encryption/crypto/Hkdf.kt | 29 ++---------- 2 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/FixedKey.kt diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/FixedKey.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/FixedKey.kt new file mode 100644 index 000000000..6f4c21bc6 --- /dev/null +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/FixedKey.kt @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip44Encryption.crypto + +import javax.crypto.SecretKey + +class FixedKey( + val key: ByteArray, + val algo: String, +) : SecretKey { + override fun getAlgorithm() = algo + + override fun getEncoded() = key + + override fun getFormat() = "RAW" + + override fun hashCode() = key.contentHashCode() + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is FixedKey) return false + return key.contentEquals(other.key) + } + + override fun destroy() = key.fill(0) + + override fun isDestroyed() = key.all { it.toInt() == 0 } +} diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt index 5ef41fe06..65bc65bbe 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt @@ -23,7 +23,6 @@ package com.vitorpamplona.quartz.nip44Encryption.crypto import com.vitorpamplona.quartz.nip44Encryption.Nip44v2.MessageKey import java.nio.ByteBuffer import javax.crypto.Mac -import javax.crypto.SecretKey import javax.crypto.spec.SecretKeySpec class Hkdf( @@ -35,7 +34,7 @@ class Hkdf( salt: ByteArray, ): ByteArray { val mac = Mac.getInstance(algorithm) - mac.init(HMacKey(salt)) + mac.init(FixedKey(salt, algorithm)) return mac.doFinal(key) } @@ -45,7 +44,7 @@ class Hkdf( salt: ByteArray, ): ByteArray { val mac = Mac.getInstance(algorithm) - mac.init(HMacKey(salt)) + mac.init(FixedKey(salt, algorithm)) mac.update(key1) mac.update(key2) return mac.doFinal() @@ -95,7 +94,7 @@ class Hkdf( check(nonce.size == hashLen) val mac = Mac.getInstance(algorithm) - mac.init(HMacKey(key)) + mac.init(FixedKey(key, algorithm)) // First round: T(1) = HMAC-SHA256(key, nonce || 0x01) mac.update(nonce) @@ -125,25 +124,3 @@ class Hkdf( ) } } - -class HMacKey( - val key: ByteArray, -) : SecretKey { - override fun getAlgorithm() = "HmacSHA256" - - override fun getEncoded() = key - - override fun getFormat() = "RAW" - - override fun hashCode() = key.contentHashCode() - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is HMacKey) return false - return key.contentEquals(other.key) - } - - override fun destroy() = key.fill(0) - - override fun isDestroyed() = key.all { it.toInt() == 0 } -}