Merge 3bb67b682d38f59d078d2e7b12c22791f554c3ae into 9a399cc3332157ab340b18cc9c115a98bb760ebb

This commit is contained in:
Toan Wizard 2026-09-07 12:07:01 +03:00 committed by GitHub
commit 40d857f4b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 3 deletions

View File

@ -13,6 +13,7 @@ import kotlinx.coroutines.withContext
object NostrProtocol {
private const val TAG = "NostrProtocol"
private const val NIP17_IOS_COMPATIBLE_LOOKBACK_SECONDS = 86_400 - 600
private val gson = Gson()
/**
@ -37,7 +38,8 @@ object NostrProtocol {
val rumorId = rumorBase.computeEventIdHex()
val rumor = rumorBase.copy(id = rumorId)
// 2. Seal the rumor (kind 13) signed by sender, timestamp randomized up to 2 days
// 2. Seal the rumor (kind 13) signed by sender, timestamp randomized within the
// receiver subscription window used by iOS.
val sealedEvent = createSeal(
rumor = rumor,
recipientPubkey = recipientPubkey,
@ -231,7 +233,9 @@ object NostrProtocol {
val seal = NostrEvent(
pubkey = senderPublicKey,
createdAt = NostrCrypto.randomizeTimestampUpToPast(),
createdAt = NostrCrypto.randomizeTimestampUpToPast(
NIP17_IOS_COMPATIBLE_LOOKBACK_SECONDS
),
kind = NostrKind.SEAL,
tags = emptyList(),
content = encrypted
@ -260,7 +264,9 @@ object NostrProtocol {
val giftWrap = NostrEvent(
pubkey = wrapPublicKey,
createdAt = NostrCrypto.randomizeTimestampUpToPast(),
createdAt = NostrCrypto.randomizeTimestampUpToPast(
NIP17_IOS_COMPATIBLE_LOOKBACK_SECONDS
),
kind = NostrKind.GIFT_WRAP,
tags = listOf(listOf("p", recipientPubkey)), // Tag recipient
content = encrypted

View File

@ -3,10 +3,12 @@ package com.bitchat.android.nostr
import com.google.gson.Gson
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
class NostrProtocolTest {
private val gson = Gson()
private val nip17IosCompatibleLookbackSeconds = 86_400 - 600
@Test
fun decryptPrivateMessage_acceptsAuthenticatedSeal() {
@ -41,6 +43,23 @@ class NostrProtocolTest {
assertNull(decrypted)
}
@Test
fun createPrivateMessage_keepsGiftWrapTimestampInsideIosLookbackWindow() {
val sender = NostrIdentity.generate()
val recipient = NostrIdentity.generate()
val before = (System.currentTimeMillis() / 1000).toInt()
val giftWrap = NostrProtocol.createPrivateMessage(
content = "bitchat1:timestamp-window",
recipientPubkey = recipient.publicKeyHex,
senderIdentity = sender
).single()
val after = (System.currentTimeMillis() / 1000).toInt()
assertTrue(giftWrap.createdAt <= after)
assertTrue(giftWrap.createdAt >= before - nip17IosCompatibleLookbackSeconds)
}
private fun forgedGiftWrap(
content: String,
claimedSender: NostrIdentity,