mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2024-09-30 00:40:49 +00:00
Send Private Zaps
This commit is contained in:
parent
eab202f721
commit
ff490a2b14
@ -72,7 +72,7 @@ class LnZapEvent(
|
||||
|
||||
enum class ZapType() {
|
||||
PUBLIC,
|
||||
PRIVATE, // not yet implemented
|
||||
PRIVATE,
|
||||
ANONYMOUS,
|
||||
NONZAP
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
package com.vitorpamplona.amethyst.service.model
|
||||
|
||||
import com.vitorpamplona.amethyst.model.HexKey
|
||||
import com.vitorpamplona.amethyst.model.toHexKey
|
||||
import com.vitorpamplona.amethyst.model.*
|
||||
import nostr.postr.Bech32
|
||||
import nostr.postr.Utils
|
||||
import java.util.Date
|
||||
import java.nio.charset.Charset
|
||||
import java.security.SecureRandom
|
||||
import java.util.*
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.spec.IvParameterSpec
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
class LnZapRequestEvent(
|
||||
id: HexKey,
|
||||
@ -28,7 +33,7 @@ class LnZapRequestEvent(
|
||||
zapType: LnZapEvent.ZapType,
|
||||
createdAt: Long = Date().time / 1000
|
||||
): LnZapRequestEvent {
|
||||
val content = message
|
||||
var content = message
|
||||
var privkey = privateKey
|
||||
var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
|
||||
var tags = listOf(
|
||||
@ -46,12 +51,65 @@ class LnZapRequestEvent(
|
||||
tags = tags + listOf(listOf("anon", ""))
|
||||
privkey = Utils.privkeyCreate()
|
||||
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
|
||||
} else if (zapType == LnZapEvent.ZapType.PRIVATE) {
|
||||
var enc_prkey = create_private_key(privateKey, originalNote.id(), createdAt)
|
||||
var noteJson = (create(privkey, 9733, listOf(tags[0], tags[1]), message)).toJson()
|
||||
var privreq = encrypt_privatezap_message(noteJson, enc_prkey, originalNote.pubKey().toByteArray())
|
||||
tags = tags + listOf(listOf("anon", privreq))
|
||||
content = ""
|
||||
privkey = enc_prkey
|
||||
pubKey = Utils.pubkeyCreate(enc_prkey).toHexKey()
|
||||
}
|
||||
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||
val sig = Utils.sign(id, privkey)
|
||||
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
|
||||
}
|
||||
|
||||
fun create_private_key(privkey: ByteArray, id: String, createdAt: Long): ByteArray {
|
||||
var str = privkey.toHexKey() + id + createdAt.toString()
|
||||
var strbyte = str.toByteArray(Charset.forName("utf-8"))
|
||||
return sha256.digest(strbyte)
|
||||
}
|
||||
|
||||
fun encrypt_privatezap_message(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
|
||||
var sharedSecret = Utils.getSharedSecret(privkey, pubkey)
|
||||
val iv = ByteArray(16)
|
||||
SecureRandom().nextBytes(iv)
|
||||
|
||||
val keySpec = SecretKeySpec(sharedSecret, "AES")
|
||||
val ivSpec = IvParameterSpec(iv)
|
||||
|
||||
var utf8_message = msg.toByteArray(Charset.forName("utf-8"))
|
||||
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
|
||||
val encryptedMsg = cipher.doFinal(utf8_message)
|
||||
|
||||
val encryptedMsgBech32 = Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32)
|
||||
val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32)
|
||||
|
||||
return encryptedMsgBech32 + "_" + ivBech32
|
||||
}
|
||||
|
||||
fun decrypt_privatezap_message(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
|
||||
var sharedSecret = Utils.getSharedSecret(privkey, pubkey)
|
||||
val parts = msg.split("_")
|
||||
val iv = parts[1].run { Bech32.decode(this) }
|
||||
val encryptedMsg = parts.first().run { Bech32.decode(this) }
|
||||
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
||||
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec(Bech32.five2eight(iv.second, 0)))
|
||||
return String(cipher.doFinal(Bech32.five2eight(encryptedMsg.second, 0)))
|
||||
}
|
||||
|
||||
fun test_decrypt(privateKey: ByteArray, event: Event): String {
|
||||
val anonTag = event.tags.firstOrNull { t -> t.count() >= 2 && t[0] == "anon" }
|
||||
var encnote = anonTag?.elementAt(1)
|
||||
if (encnote != null) {
|
||||
var enc_prkey2 = create_private_key(privateKey, event.id(), event.createdAt)
|
||||
return decrypt_privatezap_message(encnote, enc_prkey2, event.pubKey().toByteArray())
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
fun create(
|
||||
userHex: String,
|
||||
relays: Set<String>,
|
||||
@ -60,7 +118,7 @@ class LnZapRequestEvent(
|
||||
zapType: LnZapEvent.ZapType,
|
||||
createdAt: Long = Date().time / 1000
|
||||
): LnZapRequestEvent {
|
||||
val content = message
|
||||
var content = message
|
||||
var privkey = privateKey
|
||||
var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
|
||||
var tags = listOf(
|
||||
@ -68,18 +126,24 @@ class LnZapRequestEvent(
|
||||
listOf("relays") + relays
|
||||
)
|
||||
if (zapType == LnZapEvent.ZapType.ANONYMOUS) {
|
||||
tags = tags + listOf(listOf("anon", ""))
|
||||
privkey = Utils.privkeyCreate()
|
||||
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
|
||||
tags = tags + listOf(listOf("anon", ""))
|
||||
} else if (zapType == LnZapEvent.ZapType.PRIVATE) {
|
||||
var enc_prkey = create_private_key(privateKey, userHex, createdAt)
|
||||
var noteJson = (create(privkey, 9733, listOf(tags[0], tags[1]), message)).toJson()
|
||||
var privreq = encrypt_privatezap_message(noteJson, enc_prkey, userHex.toByteArray())
|
||||
tags = tags + listOf(listOf("anon", privreq))
|
||||
content = ""
|
||||
privkey = enc_prkey
|
||||
pubKey = Utils.pubkeyCreate(enc_prkey).toHexKey()
|
||||
}
|
||||
|
||||
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||
val sig = Utils.sign(id, privkey)
|
||||
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"pubkey": "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
|
||||
|
@ -67,6 +67,7 @@ fun ZapCustomDialog(onClose: () -> Unit, account: Account, accountViewModel: Acc
|
||||
|
||||
val zapTypes = listOf(
|
||||
Pair(LnZapEvent.ZapType.PUBLIC, "Public"),
|
||||
Pair(LnZapEvent.ZapType.PRIVATE, "Private"),
|
||||
Pair(LnZapEvent.ZapType.ANONYMOUS, "Anonymous"),
|
||||
Pair(LnZapEvent.ZapType.NONZAP, "Non-Zap")
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user