Separating NIP24 into the encryption NIP 44 and the messaging NIP 24

This commit is contained in:
Vitor Pamplona
2023-08-22 09:41:40 -04:00
parent d73dec8f0b
commit fa4257ad7d
8 changed files with 46 additions and 46 deletions

View File

@@ -21,7 +21,7 @@ class ImageUploadTesting {
val image = "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" val image = "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"
fun testBase(server: FileServer) { private fun testBase(server: FileServer) {
val bytes = Base64.getDecoder().decode(image) val bytes = Base64.getDecoder().decode(image)
val inputStream = bytes.inputStream() val inputStream = bytes.inputStream()
@@ -39,7 +39,7 @@ class ImageUploadTesting {
"image/gif", "image/gif",
server, server,
onSuccess = { newUrl, contentType -> onSuccess = { newUrl, contentType ->
println("Uploaded to $url") println("Uploaded $contentType to $url")
url = newUrl url = newUrl
countDownLatch.countDown() countDownLatch.countDown()
}, },

View File

@@ -4128,7 +4128,7 @@ https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db
} }
private fun printStateForDebug(state: RichTextViewerState) { private fun printStateForDebug(state: RichTextViewerState) {
state.paragraphs.forEachIndexed { index, paragraph -> state.paragraphs.forEach { paragraph ->
paragraph.words.forEach { seg -> paragraph.words.forEach { seg ->
println( println(
"\"${ "\"${

View File

@@ -38,7 +38,7 @@ class CryptoBenchmark {
val keyPair2 = KeyPair() val keyPair2 = KeyPair()
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.getSharedSecretNIP24(keyPair1.privKey!!, keyPair2.pubKey)) assertNotNull(CryptoUtils.getSharedSecretNIP44(keyPair1.privKey!!, keyPair2.pubKey))
} }
} }
@@ -58,7 +58,7 @@ class CryptoBenchmark {
val keyPair2 = KeyPair() val keyPair2 = KeyPair()
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.computeSharedSecretNIP24(keyPair1.privKey!!, keyPair2.pubKey)) assertNotNull(CryptoUtils.computeSharedSecretNIP44(keyPair1.privKey!!, keyPair2.pubKey))
} }
} }

View File

@@ -166,7 +166,7 @@ class GiftWrapReceivingBenchmark {
val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray())) assertNotNull(CryptoUtils.decryptNIP44(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray()))
} }
} }
@@ -191,7 +191,7 @@ class GiftWrapReceivingBenchmark {
) )
val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return
val innerJson = CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray()) val innerJson = CryptoUtils.decryptNIP44(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray())
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(innerJson?.let { Event.fromJson(it) }) assertNotNull(innerJson?.let { Event.fromJson(it) })
@@ -236,7 +236,7 @@ class GiftWrapReceivingBenchmark {
val toDecrypt = decodeNIP44(seal.content) ?: return val toDecrypt = decodeNIP44(seal.content) ?: return
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray())) assertNotNull(CryptoUtils.decryptNIP44(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray()))
} }
} }
@@ -256,7 +256,7 @@ class GiftWrapReceivingBenchmark {
) )
val toDecrypt = decodeNIP44(seal.content) ?: return val toDecrypt = decodeNIP44(seal.content) ?: return
val innerJson = CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray()) val innerJson = CryptoUtils.decryptNIP44(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray())
benchmarkRule.measureRepeated { benchmarkRule.measureRepeated {
assertNotNull(innerJson?.let { Gossip.fromJson(it) }) assertNotNull(innerJson?.let { Gossip.fromJson(it) })

View File

@@ -24,7 +24,7 @@ class CryptoUtilsTest {
val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561" val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561"
val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f" val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f"
val key = CryptoUtils.getSharedSecretNIP24(privateKey = privateKey.hexToByteArray(), pubKey = publicKey.hexToByteArray()) val key = CryptoUtils.getSharedSecretNIP44(privateKey = privateKey.hexToByteArray(), pubKey = publicKey.hexToByteArray())
assertEquals("577c966f499dddd8e8dcc34e8f352e283cc177e53ae372794947e0b8ede7cfd8", key.toHexKey()) assertEquals("577c966f499dddd8e8dcc34e8f352e283cc177e53ae372794947e0b8ede7cfd8", key.toHexKey())
} }
@@ -34,8 +34,8 @@ class CryptoUtilsTest {
val sender = KeyPair() val sender = KeyPair()
val receiver = KeyPair() val receiver = KeyPair()
val sharedSecret1 = CryptoUtils.getSharedSecretNIP24(sender.privKey!!, receiver.pubKey) val sharedSecret1 = CryptoUtils.getSharedSecretNIP44(sender.privKey!!, receiver.pubKey)
val sharedSecret2 = CryptoUtils.getSharedSecretNIP24(receiver.privKey!!, sender.pubKey) val sharedSecret2 = CryptoUtils.getSharedSecretNIP44(receiver.privKey!!, sender.pubKey)
assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey()) assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey())
@@ -73,14 +73,14 @@ class CryptoUtilsTest {
} }
@Test @Test
fun encryptDecryptNIP24Test() { fun encryptDecryptNIP44Test() {
val msg = "Hi" val msg = "Hi"
val privateKey = CryptoUtils.privkeyCreate() val privateKey = CryptoUtils.privkeyCreate()
val publicKey = CryptoUtils.pubkeyCreate(privateKey) val publicKey = CryptoUtils.pubkeyCreate(privateKey)
val encrypted = CryptoUtils.encryptNIP24(msg, privateKey, publicKey) val encrypted = CryptoUtils.encryptNIP44(msg, privateKey, publicKey)
val decrypted = CryptoUtils.decryptNIP24(encrypted, privateKey, publicKey) val decrypted = CryptoUtils.decryptNIP44(encrypted, privateKey, publicKey)
assertEquals(msg, decrypted) assertEquals(msg, decrypted)
} }
@@ -99,15 +99,15 @@ class CryptoUtilsTest {
} }
@Test @Test
fun encryptSharedSecretDecryptNIP24Test() { fun encryptSharedSecretDecryptNIP44Test() {
val msg = "Hi" val msg = "Hi"
val privateKey = CryptoUtils.privkeyCreate() val privateKey = CryptoUtils.privkeyCreate()
val publicKey = CryptoUtils.pubkeyCreate(privateKey) val publicKey = CryptoUtils.pubkeyCreate(privateKey)
val sharedSecret = CryptoUtils.getSharedSecretNIP24(privateKey, publicKey) val sharedSecret = CryptoUtils.getSharedSecretNIP44(privateKey, publicKey)
val encrypted = CryptoUtils.encryptNIP24(msg, sharedSecret) val encrypted = CryptoUtils.encryptNIP44(msg, sharedSecret)
val decrypted = CryptoUtils.decryptNIP24(encrypted, sharedSecret) val decrypted = CryptoUtils.decryptNIP44(encrypted, sharedSecret)
assertEquals(msg, decrypted) assertEquals(msg, decrypted)
} }

View File

@@ -17,7 +17,7 @@ import javax.crypto.spec.SecretKeySpec
object CryptoUtils { object CryptoUtils {
private val sharedKeyCache04 = LruCache<Int, ByteArray>(200) private val sharedKeyCache04 = LruCache<Int, ByteArray>(200)
private val sharedKeyCache24 = LruCache<Int, ByteArray>(200) private val sharedKeyCache44 = LruCache<Int, ByteArray>(200)
private val secp256k1 = Secp256k1.get() private val secp256k1 = Secp256k1.get()
private val libSodium = SodiumAndroid() private val libSodium = SodiumAndroid()
@@ -26,7 +26,7 @@ object CryptoUtils {
fun clearCache() { fun clearCache() {
sharedKeyCache04.evictAll() sharedKeyCache04.evictAll()
sharedKeyCache24.evictAll() sharedKeyCache44.evictAll()
} }
fun randomInt(bound: Int): Int { fun randomInt(bound: Int): Int {
@@ -115,12 +115,12 @@ object CryptoUtils {
return String(cipher.doFinal(encryptedMsg)) return String(cipher.doFinal(encryptedMsg))
} }
fun encryptNIP24(msg: String, privateKey: ByteArray, pubKey: ByteArray): EncryptedInfo { fun encryptNIP44(msg: String, privateKey: ByteArray, pubKey: ByteArray): EncryptedInfo {
val sharedSecret = getSharedSecretNIP24(privateKey, pubKey) val sharedSecret = getSharedSecretNIP44(privateKey, pubKey)
return encryptNIP24(msg, sharedSecret) return encryptNIP44(msg, sharedSecret)
} }
fun encryptNIP24(msg: String, sharedSecret: ByteArray): EncryptedInfo { fun encryptNIP44(msg: String, sharedSecret: ByteArray): EncryptedInfo {
val nonce = ByteArray(24) val nonce = ByteArray(24)
random.nextBytes(nonce) random.nextBytes(nonce)
@@ -134,16 +134,16 @@ object CryptoUtils {
return EncryptedInfo( return EncryptedInfo(
ciphertext = cipher ?: ByteArray(0), ciphertext = cipher ?: ByteArray(0),
nonce = nonce, nonce = nonce,
v = Nip44Version.NIP24.versionCode v = Nip44Version.NIP44.versionCode
) )
} }
fun decryptNIP24(encryptedInfo: EncryptedInfo, privateKey: ByteArray, pubKey: ByteArray): String? { fun decryptNIP44(encryptedInfo: EncryptedInfo, privateKey: ByteArray, pubKey: ByteArray): String? {
val sharedSecret = getSharedSecretNIP24(privateKey, pubKey) val sharedSecret = getSharedSecretNIP44(privateKey, pubKey)
return decryptNIP24(encryptedInfo, sharedSecret) return decryptNIP44(encryptedInfo, sharedSecret)
} }
fun decryptNIP24(encryptedInfo: EncryptedInfo, sharedSecret: ByteArray): String? { fun decryptNIP44(encryptedInfo: EncryptedInfo, sharedSecret: ByteArray): String? {
return cryptoStreamXChaCha20Xor( return cryptoStreamXChaCha20Xor(
libSodium = libSodium, libSodium = libSodium,
messageBytes = encryptedInfo.ciphertext, messageBytes = encryptedInfo.ciphertext,
@@ -174,20 +174,20 @@ object CryptoUtils {
/** /**
* @return 32B shared secret * @return 32B shared secret
*/ */
fun getSharedSecretNIP24(privateKey: ByteArray, pubKey: ByteArray): ByteArray { fun getSharedSecretNIP44(privateKey: ByteArray, pubKey: ByteArray): ByteArray {
val hash = combinedHashCode(privateKey, pubKey) val hash = combinedHashCode(privateKey, pubKey)
val preComputed = sharedKeyCache24[hash] val preComputed = sharedKeyCache44[hash]
if (preComputed != null) return preComputed if (preComputed != null) return preComputed
val computed = computeSharedSecretNIP24(privateKey, pubKey) val computed = computeSharedSecretNIP44(privateKey, pubKey)
sharedKeyCache24.put(hash, computed) sharedKeyCache44.put(hash, computed)
return computed return computed
} }
/** /**
* @return 32B shared secret * @return 32B shared secret
*/ */
fun computeSharedSecretNIP24(privateKey: ByteArray, pubKey: ByteArray): ByteArray = fun computeSharedSecretNIP44(privateKey: ByteArray, pubKey: ByteArray): ByteArray =
sha256(secp256k1.pubKeyTweakMul(h02 + pubKey, privateKey).copyOfRange(1, 33)) sha256(secp256k1.pubKeyTweakMul(h02 + pubKey, privateKey).copyOfRange(1, 33))
} }
@@ -196,7 +196,7 @@ data class EncryptedInfoString(val ciphertext: String, val nonce: String, val v:
enum class Nip44Version(val versionCode: Int) { enum class Nip44Version(val versionCode: Int) {
NIP04(0), NIP04(0),
NIP24(1) NIP44(1)
} }
@@ -234,10 +234,10 @@ fun decodeByteArray(base64: String): EncryptedInfo? {
fun encodeJackson(info: EncryptedInfo): String { fun encodeJackson(info: EncryptedInfo): String {
return Event.mapper.writeValueAsString( return Event.mapper.writeValueAsString(
EncryptedInfoString( EncryptedInfoString(
v = info.v, v = info.v,
nonce = Base64.getEncoder().encodeToString(info.nonce), nonce = Base64.getEncoder().encodeToString(info.nonce),
ciphertext = Base64.getEncoder().encodeToString(info.ciphertext) ciphertext = Base64.getEncoder().encodeToString(info.ciphertext)
) )
) )
} }

View File

@@ -51,7 +51,7 @@ class GiftWrapEvent(
return when (toDecrypt.v) { return when (toDecrypt.v) {
Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray()) Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray())
Nip44Version.NIP24.versionCode -> CryptoUtils.decryptNIP24(toDecrypt, privKey, pubKey.hexToByteArray()) Nip44Version.NIP44.versionCode -> CryptoUtils.decryptNIP44(toDecrypt, privKey, pubKey.hexToByteArray())
else -> null else -> null
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -71,10 +71,10 @@ class GiftWrapEvent(
createdAt: Long = TimeUtils.randomWithinAWeek() createdAt: Long = TimeUtils.randomWithinAWeek()
): GiftWrapEvent { ): GiftWrapEvent {
val privateKey = CryptoUtils.privkeyCreate() // GiftWrap is always a random key val privateKey = CryptoUtils.privkeyCreate() // GiftWrap is always a random key
val sharedSecret = CryptoUtils.getSharedSecretNIP24(privateKey, recipientPubKey.hexToByteArray()) val sharedSecret = CryptoUtils.getSharedSecretNIP44(privateKey, recipientPubKey.hexToByteArray())
val content = encodeNIP44( val content = encodeNIP44(
CryptoUtils.encryptNIP24( CryptoUtils.encryptNIP44(
toJson(event), toJson(event),
sharedSecret sharedSecret
) )

View File

@@ -53,7 +53,7 @@ class SealedGossipEvent(
return when (toDecrypt.v) { return when (toDecrypt.v) {
Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray()) Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray())
Nip44Version.NIP24.versionCode -> CryptoUtils.decryptNIP24(toDecrypt, privKey, pubKey.hexToByteArray()) Nip44Version.NIP44.versionCode -> CryptoUtils.decryptNIP44(toDecrypt, privKey, pubKey.hexToByteArray())
else -> null else -> null
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -81,10 +81,10 @@ class SealedGossipEvent(
privateKey: ByteArray, privateKey: ByteArray,
createdAt: Long = TimeUtils.randomWithinAWeek() createdAt: Long = TimeUtils.randomWithinAWeek()
): SealedGossipEvent { ): SealedGossipEvent {
val sharedSecret = CryptoUtils.getSharedSecretNIP24(privateKey, encryptTo.hexToByteArray()) val sharedSecret = CryptoUtils.getSharedSecretNIP44(privateKey, encryptTo.hexToByteArray())
val content = encodeNIP44( val content = encodeNIP44(
CryptoUtils.encryptNIP24( CryptoUtils.encryptNIP44(
Gossip.toJson(gossip), Gossip.toJson(gossip),
sharedSecret sharedSecret
) )