-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,9 @@ | ||
import 'dart:convert'; | ||
import 'dart:typed_data'; | ||
import 'package:bip340/bip340.dart' as bip340; | ||
import 'package:convert/convert.dart'; | ||
import 'package:pointycastle/export.dart'; | ||
|
||
import 'nips/nip_004/crypto.dart'; | ||
import 'utils.dart'; | ||
import 'settings.dart'; | ||
import 'package:bip340/bip340.dart' as bip340; | ||
import 'package:nostr/src/utils.dart'; | ||
|
||
/// The only object type that exists is the event, which has the following format on the wire: | ||
/// | ||
|
@@ -49,11 +46,6 @@ class Event { | |
/// subscription_id is a random string that should be used to represent a subscription. | ||
String? subscriptionId; | ||
|
||
/// Nip04: If event is of kind 4, then `decrypted` flag indicates whether `content` was | ||
/// successfully decrypted. Unsuccessful decryption on a valid event is typically caused | ||
/// by missing or mismatched private key. | ||
bool decrypted = false; | ||
|
||
/// Default constructor | ||
/// | ||
/// verify: ensure your event isValid() –> id, signature, timestamp… | ||
|
@@ -262,14 +254,11 @@ class Event { | |
throw Exception('invalid input'); | ||
} | ||
|
||
if (json['tags'] is String) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ntheden
Contributor
|
||
json['tags'] = jsonDecode(json['tags']); | ||
} | ||
List<List<String>> tags = (json['tags'] as List<dynamic>) | ||
var tags = (json['tags'] as List<dynamic>) | ||
.map((e) => (e as List<dynamic>).map((e) => e as String).toList()) | ||
.toList(); | ||
|
||
Event event = Event( | ||
return Event( | ||
json['id'], | ||
json['pubkey'], | ||
json['created_at'], | ||
|
@@ -280,24 +269,6 @@ class Event { | |
subscriptionId: subscriptionId, | ||
verify: verify, | ||
); | ||
if (event.kind == 4) { | ||
event.nip04Decrypt(); | ||
} | ||
return event; | ||
} | ||
|
||
factory Event.newEvent( | ||
String content, | ||
String privkey, | ||
) { | ||
Event event = Event.partial(); | ||
event.kind = 1; | ||
event.content = content; | ||
event.createdAt = currentUnixTimestampSeconds(); | ||
event.pubkey = bip340.getPublicKey(privkey).toLowerCase(); | ||
event.id = event.getEventId(); | ||
event.sig = event.getSignature(privkey); | ||
return event; | ||
} | ||
|
||
/// To obtain the event.id, we sha256 the serialized event. | ||
|
@@ -331,7 +302,7 @@ class Event { | |
String content, | ||
) { | ||
List data = [0, pubkey.toLowerCase(), createdAt, kind, tags, content]; | ||
String serializedEvent = jsonEncode(data); | ||
String serializedEvent = json.encode(data); | ||
Uint8List hash = SHA256Digest() | ||
.process(Uint8List.fromList(utf8.encode(serializedEvent))); | ||
return hex.encode(hash); | ||
|
@@ -357,14 +328,6 @@ class Event { | |
/// Verify if event checks such as id, signature, non-futuristic are valid | ||
/// Performances could be a reason to disable event checks | ||
bool isValid() { | ||
if (decrypted) { | ||
// isValid() check was already performed when the Event was created at | ||
// deserialization off of the input stream. Post-decryption, id check will | ||
// fail as the content has changed. | ||
// Alternatively, getEventId() could compute id from a `plaintext` field | ||
// when `decrypted` is true. | ||
return true; | ||
} | ||
String verifyId = getEventId(); | ||
if (createdAt.toString().length == 10 && | ||
id == verifyId && | ||
|
@@ -374,21 +337,4 @@ class Event { | |
return false; | ||
} | ||
} | ||
|
||
bool nip04Decrypt() { | ||
int ivIndex = content.indexOf("?iv="); | ||
if (ivIndex <= 0) { | ||
print("Invalid content for dm, could not get ivIndex: $content"); | ||
return false; | ||
} | ||
String iv = content.substring(ivIndex + "?iv=".length, content.length); | ||
String encString = content.substring(0, ivIndex); | ||
try { | ||
content = Nip04.decrypt(userPrivateKey, "02$pubkey", encString, iv); | ||
decrypted = true; | ||
} catch (e) { | ||
//print("Fail to decrypt: ${e}"); | ||
} | ||
return decrypted; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ class Message { | |
switch (type) { | ||
case "EVENT": | ||
message = Event.deserialize(data); | ||
if (message.kind == 4) message = EncryptedDirectMessage(message); | ||
This comment has been minimized.
Sorry, something went wrong.
ethicnology
Author
Owner
|
||
break; | ||
case "REQ": | ||
message = Request.deserialize(data); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,59 @@ | ||
import 'package:bip340/bip340.dart' as bip340; | ||
|
||
import '../../event.dart'; | ||
import '../../utils.dart'; | ||
import 'crypto.dart'; | ||
import 'package:nostr/src/event.dart'; | ||
import 'package:nostr/src/nips/nip_004/crypto.dart'; | ||
import 'package:nostr/src/utils.dart'; | ||
|
||
class EncryptedDirectMessage extends Event { | ||
late String peerPubkey; | ||
late String? plaintext; | ||
late String? referenceEventId; | ||
|
||
EncryptedDirectMessage( | ||
this.peerPubkey, | ||
id, | ||
pubkey, | ||
createdAt, | ||
kind, | ||
tags, | ||
content, | ||
sig, { | ||
subscriptionId, | ||
bool verify = false, | ||
this.plaintext, | ||
this.referenceEventId, | ||
}) : super( | ||
id, | ||
pubkey, | ||
createdAt, | ||
kind, | ||
tags, | ||
content, | ||
sig, | ||
subscriptionId: subscriptionId, | ||
verify: verify, | ||
) { | ||
kind = 4; | ||
plaintext = content; | ||
} | ||
static Map<String, List<List<int>>> gMapByteSecret = {}; | ||
|
||
factory EncryptedDirectMessage.partial({ | ||
peerPubkey = "", | ||
id = "", | ||
pubkey = "", | ||
createdAt = 0, | ||
kind = 4, | ||
tags = const <List<String>>[], | ||
content = "", | ||
sig = "", | ||
plaintext, | ||
referenceEventId, | ||
subscriptionId, | ||
bool verify = false, | ||
}) { | ||
return EncryptedDirectMessage( | ||
peerPubkey, | ||
id, | ||
pubkey, | ||
createdAt, | ||
kind, | ||
tags, | ||
content, | ||
sig, | ||
plaintext: plaintext, | ||
referenceEventId: referenceEventId, | ||
subscriptionId: subscriptionId, | ||
verify: verify, | ||
); | ||
} | ||
EncryptedDirectMessage(Event event) | ||
: super( | ||
event.id, | ||
event.pubkey, | ||
event.createdAt, | ||
4, | ||
event.tags, | ||
event.content, | ||
event.sig, | ||
subscriptionId: event.subscriptionId, | ||
verify: true, | ||
); | ||
|
||
factory EncryptedDirectMessage.newEvent( | ||
String peerPubkey, | ||
String plaintext, | ||
String privkey, { | ||
String? referenceEventId, | ||
}) { | ||
EncryptedDirectMessage event = EncryptedDirectMessage.partial(); | ||
event.content = Nip04.encryptMessage(privkey, '02$peerPubkey', plaintext); | ||
event.kind = 4; | ||
factory EncryptedDirectMessage.quick( | ||
String senderPrivkey, | ||
String receiverPubkey, | ||
String message, | ||
) { | ||
var event = Event.partial(); | ||
event.pubkey = bip340.getPublicKey(senderPrivkey).toLowerCase(); | ||
event.createdAt = currentUnixTimestampSeconds(); | ||
event.pubkey = bip340.getPublicKey(privkey).toLowerCase(); | ||
event.kind = 4; | ||
event.tags = [ | ||
['p', peerPubkey], | ||
['p', receiverPubkey] | ||
]; | ||
event.peerPubkey = peerPubkey; | ||
event.plaintext = plaintext; | ||
if (referenceEventId != null) { | ||
event.tags.add(['e', referenceEventId]); | ||
} | ||
event.content = Nip4.cipher(senderPrivkey, '02$receiverPubkey', message); | ||
event.id = event.getEventId(); | ||
event.sig = event.getSignature(privkey); | ||
return event; | ||
event.sig = event.getSignature(senderPrivkey); | ||
return EncryptedDirectMessage(event); | ||
} | ||
|
||
String? get receiverPubkey => findPubkey(); | ||
|
||
String getCiphertext(String senderPrivkey, String receiverPubkey) { | ||
String ciphertext = | ||
Nip4.cipher(senderPrivkey, '02$receiverPubkey', content); | ||
return ciphertext; | ||
} | ||
|
||
String getPlaintext(String receiverPrivkey, String senderPubkey) { | ||
This comment has been minimized.
Sorry, something went wrong.
ntheden
Contributor
|
||
return Nip4.decipher(receiverPrivkey, senderPubkey, content); | ||
} | ||
|
||
String? findPubkey() { | ||
String prefix = "p"; | ||
for (List<String> tag in tags) { | ||
if (tag.isNotEmpty && tag[0] == prefix && tag.length > 1) return tag[1]; | ||
} | ||
return null; | ||
} | ||
} |
This file was deleted.
2 comments
on commit 385f211
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be some bug, I can't get the code in this commit to decrypt events without errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be some bug, I can't get the code in this commit to decrypt events without errors.
I fixed the receive issue in PR #26 . I created it to show the change, still need to add in the unit tests though.
I had this change in there because a python relay I was talking to escaped the
"
character in nested json objects so jsonDecode left it as a string in first pass.