Skip to content

Commit 85b4bf8

Browse files
committed
giftwraps working!
Signed-off-by: William Casarin <[email protected]>
1 parent ef6cea6 commit 85b4bf8

File tree

3 files changed

+119
-46
lines changed

3 files changed

+119
-46
lines changed

src/nip44.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,6 @@ nip44_encrypt(void *secp, const unsigned char *sender_seckey,
471471
return NIP44_ERR_BUFFER_TOO_SMALL;
472472

473473
ciphertext_len = cursor.p - ciphertext;
474-
printf("plaintext_size %d ciphertext '%.*s'\n", plaintext_size,
475-
plaintext_size, plaintext);
476474

477475
/*
478476
5. Encrypt padded content

src/nostrdb.c

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,17 +2860,16 @@ int ndb_note_verify(void *ctx, unsigned char *scratch, size_t scratch_size,
28602860
// first, we ensure the id is valid by calculating the id independently
28612861
// from what is given to us
28622862
if (!ndb_calculate_id(note, scratch, scratch_size, id)) {
2863-
ndb_debug("ndb_note_verify: scratch buffer size too small");
2863+
ndb_debug("ndb_note_verify: scratch buffer size too small\n");
28642864
return 0;
28652865
}
28662866

28672867
if (memcmp(id, note->id, 32)) {
2868-
ndb_debug("ndb_note_verify: note id does not match!");
2868+
ndb_debug("ndb_note_verify: note id does not match!\n");
28692869
return 0;
28702870
}
28712871

28722872
// id is ok, let's check signature
2873-
28742873
ok = secp256k1_xonly_pubkey_parse((secp256k1_context*)ctx,
28752874
&xonly_pubkey,
28762875
ndb_note_pubkey(note)) != 0;
@@ -3372,6 +3371,7 @@ static int ndb_ingester_process_note(secp256k1_context *secp,
33723371
ndb_note_content_length(note),
33733372
&meta);
33743373
} else if (note->kind == 1059) {
3374+
ndb_debug("processing giftwrap\n");
33753375
ndb_process_giftwrap(secp, ingester, note, keys, nkeys, relay,
33763376
scratch, scratch_size);
33773377
}
@@ -6242,8 +6242,10 @@ static int ndb_ingest_rumor(secp256k1_context *secp,
62426242

62436243
rc = ndb_note_from_json_custom(rumor_json, json_len, &rumor,
62446244
scratch, scratch_size, parse_cond);
6245-
if (!rc)
6245+
if (!rc) {
6246+
ndb_debug("failed to parse rumor json\n");
62466247
return 0;
6248+
}
62476249

62486250
sig = ndb_note_sig(rumor);
62496251

@@ -6296,24 +6298,36 @@ static int ndb_process_seal(secp256k1_context *secp,
62966298
int note_size;
62976299
size_t payload_len;
62986300
uint16_t decrypted_len;
6301+
unsigned char *old_scratch;
62996302
enum ndb_decrypt_result rc;
63006303

63016304
note_size = ndb_note_from_json(seal_json, json_len, &seal, scratch,
63026305
scratch_size);
63036306

6304-
if (!note_size)
6307+
if (!note_size) {
6308+
ndb_debug("seal json parse failed (%ld scratch_size)\n",
6309+
scratch_size);
63056310
return 0;
6311+
}
63066312

6307-
if (ndb_note_kind(seal) != 13)
6313+
if (ndb_note_kind(seal) != 13) {
6314+
ndb_debug("seal kind != 13: %d\n", ndb_note_kind(seal));
63086315
return 0;
6316+
}
63096317

6310-
if ((scratch_size - note_size) <= 0)
6318+
if ((scratch_size - note_size) <= 0) {
6319+
ndb_debug("process seal scratch size too small\n");
63116320
return 0;
6321+
}
6322+
6323+
scratch += note_size;
6324+
scratch_size -= note_size;
63126325

63136326
if (ndb_note_verify(secp,
6314-
scratch + note_size, scratch_size - note_size,
6327+
scratch, scratch_size,
63156328
seal) == 0) {
63166329
/* seal is not valid, reject */
6330+
ndb_debug("seal signature was invalid\n");
63176331
return 0;
63186332
}
63196333

@@ -6324,21 +6338,24 @@ static int ndb_process_seal(secp256k1_context *secp,
63246338
/* decrypt the seal contents */
63256339
rc = nip44_decrypt(secp, sender_pubkey, unwrap_key->seckey,
63266340
payload, payload_len,
6327-
scratch + note_size, scratch_size - note_size,
6341+
scratch, scratch_size,
63286342
&decrypted, &decrypted_len);
63296343

6330-
if (rc != NIP44_OK)
6344+
if (rc != NIP44_OK) {
6345+
ndb_debug("seal nip44 decrypt failed: %s\n", nip44_err_msg(rc));
63316346
return 0;
6347+
}
63326348

6333-
if (scratch_size - note_size - decrypted_len <= 0)
6334-
return 0;
6349+
old_scratch = scratch;
6350+
scratch = decrypted + decrypted_len;
6351+
scratch_size -= scratch - old_scratch;
63356352

63366353
/* ingest rumor */
63376354
return ndb_ingest_rumor(secp, ingester,
63386355
(const char*)decrypted, decrypted_len,
63396356
sender_pubkey, relay,
6340-
scratch + note_size + decrypted_len,
6341-
scratch_size - note_size - decrypted_len,
6357+
scratch,
6358+
scratch_size,
63426359
wrap_id, unwrap_key,
63436360
keys, nkeys);
63446361
}
@@ -6358,6 +6375,7 @@ int ndb_process_giftwrap(secp256k1_context *secp,
63586375
enum ndb_decrypt_result rc;
63596376
uint16_t decrypted_len;
63606377
size_t payload_len;
6378+
unsigned char *old_scratch;
63616379
int i;
63626380

63636381
wrap_id = ndb_note_id(note);
@@ -6393,6 +6411,9 @@ int ndb_process_giftwrap(secp256k1_context *secp,
63936411
continue;
63946412
}
63956413

6414+
old_scratch = scratch;
6415+
scratch = decrypted + decrypted_len;
6416+
scratch_size -= scratch - old_scratch;
63966417

63976418
/* decrypt success */
63986419
rc = ndb_process_seal(secp, ingester,
@@ -7385,7 +7406,7 @@ static inline int ndb_json_parser_init(struct ndb_json_parser *p,
73857406
// the more important stuff gets a larger chunk and then it spirals
73867407
// downward into smaller chunks. Thanks for coming to my TED talk.
73877408

7388-
if (!ndb_builder_init(&p->builder, buf, half))
7409+
if (!ndb_builder_init(&p->builder, buf, half))
73897410
return 0;
73907411

73917412
jsmn_init(&p->json_parser);
@@ -7398,6 +7419,7 @@ static inline int ndb_json_parser_parse(struct ndb_json_parser *p,
73987419
{
73997420
jsmntok_t *tok;
74007421
int cap = ((unsigned char *)p->toks_end - (unsigned char*)p->toks)/sizeof(*p->toks);
7422+
74017423
int res =
74027424
jsmn_parse(&p->json_parser, p->json, p->json_len, p->toks, cap, cb != NULL);
74037425

@@ -8214,7 +8236,10 @@ int ndb_client_event_from_json(const char *json, int len, struct ndb_fce *fce,
82148236
struct ndb_json_parser parser;
82158237
struct ndb_event *ev = &fce->event;
82168238

8217-
ndb_json_parser_init(&parser, json, len, buf, bufsize);
8239+
if (!ndb_json_parser_init(&parser, json, len, buf, bufsize)) {
8240+
ndb_debug("failed to init parser\n");
8241+
return 0;
8242+
}
82188243

82198244
if ((res = ndb_json_parser_parse(&parser, cb)) < 0)
82208245
return res;
@@ -8255,7 +8280,10 @@ int ndb_ws_event_from_json(const char *json, int len, struct ndb_tce *tce,
82558280
tce->subid_len = 0;
82568281
tce->subid = "";
82578282

8258-
ndb_json_parser_init(&parser, json, len, buf, bufsize);
8283+
if (!ndb_json_parser_init(&parser, json, len, buf, bufsize)) {
8284+
ndb_debug("ndb_ws_event_from_json: failed to init json parser\n");
8285+
return 0;
8286+
}
82598287

82608288
if ((res = ndb_json_parser_parse(&parser, cb)) < 0)
82618289
return res;
@@ -8680,20 +8708,26 @@ int ndb_parse_json_note_custom(struct ndb_json_parser *parser,
86808708
if (tok->type != JSMN_PRIMITIVE || tok_len <= 0)
86818709
return 0;
86828710
if (!parse_unsigned_int(start, toksize(tok),
8683-
&parser->builder.note->kind))
8711+
&parser->builder.note->kind)) {
8712+
ndb_debug("kind parse_unsigned_int failed\n");
86848713
return 0;
8714+
}
86858715
parsed |= NDB_PARSED_KIND;
86868716
} else if (start[0] == 'c') {
86878717
if (jsoneq(json, tok, tok_len, "created_at")) {
86888718
// created_at
86898719
tok = &parser->toks[i+1];
86908720
start = json + tok->start;
8691-
if (tok->type != JSMN_PRIMITIVE || tok_len <= 0)
8721+
if (tok->type != JSMN_PRIMITIVE || tok_len <= 0) {
8722+
ndb_debug("creatd_at parse failed\n");
86928723
return 0;
8724+
}
86938725
// TODO: update to int64 in 2106 ... xD
86948726
unsigned int bigi;
8695-
if (!parse_unsigned_int(start, toksize(tok), &bigi))
8727+
if (!parse_unsigned_int(start, toksize(tok), &bigi)) {
8728+
ndb_debug("parsed_unsigned_int failed\n");
86968729
return 0;
8730+
}
86978731
parser->builder.note->created_at = bigi;
86988732
parsed |= NDB_PARSED_CREATED_AT;
86998733
} else if (jsoneq(json, tok, tok_len, "content")) {
@@ -8721,9 +8755,11 @@ int ndb_parse_json_note_custom(struct ndb_json_parser *parser,
87218755
}
87228756
}
87238757

8724-
//ndb_debug("parsed %d = %d, &->%d", parsed, NDB_PARSED_ALL, parsed & NDB_PARSED_ALL);
8725-
if (parsed != parse_cond)
8758+
if ((parsed & parse_cond) != parse_cond) {
8759+
ndb_debug("json parse_cond failed, parsed(%d) != parse_cond(%d)\n",
8760+
parsed, parse_cond);
87268761
return 0;
8762+
}
87278763

87288764
return ndb_builder_finalize(&parser->builder, note, NULL);
87298765
}
@@ -8758,7 +8794,11 @@ int ndb_note_from_json_custom(const char *json, int len, struct ndb_note **note,
87588794
struct ndb_json_parser parser;
87598795
int res;
87608796

8761-
ndb_json_parser_init(&parser, json, len, buf, bufsize);
8797+
if (!ndb_json_parser_init(&parser, json, len, buf, bufsize)) {
8798+
ndb_debug("failed to init json parser in custom\n");
8799+
return 0;
8800+
}
8801+
87628802
if ((res = ndb_json_parser_parse(&parser, NULL)) < 0)
87638803
return res;
87648804

test.c

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static void test_nip44_test_vector()
221221
if (res != NIP44_OK) {
222222
fprintf(stderr, "nip44 error: %s\n", nip44_err_msg(res));
223223
}
224-
printf("# decrypted(%d) '%.*s'\n", decrypted_len, decrypted_len, (char*)decrypted);
224+
//printf("# decrypted(%d) '%.*s'\n", decrypted_len, decrypted_len, (char*)decrypted);
225225
assert(res == NIP44_OK);
226226
assert(memcmp(decrypted, plaintext, 1) == 0);
227227

@@ -315,7 +315,6 @@ static void test_nip44_round_trip()
315315
uint16_t plaintext_len;
316316
secp256k1_context *context;
317317

318-
319318
context = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
320319

321320
ok = nip44_encrypt(context, send_sec, recv_pub,
@@ -325,7 +324,6 @@ static void test_nip44_round_trip()
325324
if (ok != NIP44_OK)
326325
printf("nip44 encrypt err: %s\n", nip44_err_msg(ok));
327326
assert(ok == NIP44_OK);
328-
printf("encrypted '%.*s' out_len: %ld\n", (int)out_len, out, out_len);
329327

330328
ok = nip44_decrypt(context, send_pub, recv_sec,
331329
out, out_len,
@@ -334,54 +332,89 @@ static void test_nip44_round_trip()
334332

335333
if (ok != NIP44_OK)
336334
printf("nip44 decrypt err: %s\n", nip44_err_msg(ok));
335+
337336
assert(ok == NIP44_OK);
338-
printf("plaintext_len %d, sizeof plaintext(%ld)\n", plaintext_len, sizeof(plaintext));
339337
assert(plaintext_len == sizeof(plaintext)-1);
340-
341-
342338
assert(!strcmp(plaintext, plaintext_out));
343339

344340
secp256k1_context_destroy(context);
345341
}
346342

347343
static void test_giftwrap_unwrap()
348344
{
349-
/*
350345
struct ndb *ndb;
351346
struct ndb_filter filter;
352347
struct ndb_config config;
353348
struct ndb_txn txn;
354-
struct ndb_query_result results[10];
355-
int count;
349+
struct ndb_note *rumor;
350+
int ok;
356351
uint64_t subid;
357352
ndb_default_config(&config);
353+
const char *giftwrap;
354+
uint64_t note_ids[2];
358355

359-
unsigned char one[32] = {
360-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
356+
static unsigned char recv_sec[32] = {
357+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
361358
};
362359

363-
unsigned char two[32] = {
364-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
360+
static const unsigned char recv_pub[32] = {
361+
0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45,
362+
0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8, 0x5c, 0x77, 0x8e, 0x4b,
363+
0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70,
364+
0x9e, 0xe5
365+
};
366+
367+
static const unsigned char rumor_id[32] = {
368+
0x3e, 0x12, 0xe5, 0xc1, 0xc9, 0xa8, 0x9f, 0x3f, 0x08, 0x04,
369+
0x62, 0x3f, 0xd7, 0x61, 0x01, 0xcf, 0xff, 0xba, 0xdf, 0x0d,
370+
0x02, 0x59, 0x38, 0xdb, 0x64, 0x10, 0x55, 0xe6, 0x00, 0xdc,
371+
0x8f, 0x73
372+
};
373+
374+
static const unsigned char giftwrap_id[32] = {
375+
0x94, 0x1e, 0xaf, 0x4a, 0x9b, 0xd0, 0x09, 0x0a, 0xb5, 0xd4,
376+
0x14, 0xff, 0x5a, 0x68, 0x25, 0x4d, 0xa5, 0x78, 0x6f, 0x0b,
377+
0xf8, 0xb8, 0xe1, 0x56, 0xbc, 0x37, 0xa7, 0x7e, 0xa2, 0x68,
378+
0x0a, 0x92
365379
};
366380

367381
assert(ndb_init(&ndb, test_dir, &config));
368382

369-
ndb_add_key(ndb, one);
370-
ndb_add_key(ndb, two);
383+
//ndb_add_key(ndb, one);
384+
ndb_add_key(ndb, recv_sec);
371385

372386
ndb_filter_init(&filter);
373-
ndb_filter_start_field(&filter, NDB_FILTER_KINDS);
374-
ndb_filter_add_int_element(&filter, 1059);
387+
ndb_filter_start_field(&filter, NDB_FILTER_IDS);
388+
ndb_filter_add_id_element(&filter, rumor_id);
375389
ndb_filter_end_field(&filter);
376390
ndb_filter_end(&filter);
377391

378392
subid = ndb_subscribe(ndb, &filter, 1);
379393

380-
const char *giftwrap = "";
381-
ndb_process_event(giftwrap)
394+
giftwrap = "{\"id\":\"941eaf4a9bd0090ab5d414ff5a68254da5786f0bf8b8e156bc37a77ea2680a92\",\"pubkey\":\"5fac96633ffd0f68a037778dc40d7747ddf0ceaadb7986c23c0597a56b9ab6f6\",\"created_at\":1764513655,\"kind\":1059,\"tags\":[[\"p\",\"c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5\"]],\"content\":\"AmoRXHPZ6cYI2YR1PL1J2BpxY8onrJHUvt3cOhAe1IOIk6wnighedqyUqQsJ/Bnq0qAAkldMipUuHmr1TRNeu/3Rf3AZ1+4N6/eSJb2GcVaaWkqJ6DIIW+YHvQZRuS/1ef3lo41+2zOFqJMvLiz/Pw1kLdDdi5pKWy0QHJIKFPuIE9XNhFMTMo+rYSIlpfiAXtzpM6qETFBJxabmaZOMlgnxQG6Mm2gB3Y6rmj9gLgxsPCaOnvmfi5xhA+jRvz8FYQ+WIU1ij7SFsssz27fISRRIMEOoq7CHPcsdY2Ly/PSp1t+aLpSz1e8Chnhf3lq/Y0mumLDS/BzNaFm38wQqCoWbxrn+7iLTMfINXoDm7gY6Qb4eZc/Am/wjRJsHm4F37bPiCAupzYWOPdJWO3a4TPmGaHk6MmyrHRu4V20iZK+svdJ257RuwMrYk39xCWNG985t1acPc5Of+ZKDnUcL5jVw0ZUOTrV10uq/UVoOHwDkz0mcsJ0Adhc0fKgiE7CWZgKbaO0PIaAL0I+2hs350dcEK3Go8vzMfiN1Uc7NUUMpjQzIRJC1J6CVf6HkvvQ+JD52RhXsVZN8TTkrpxEDqvCm8eSpamqIZuMbrTh5jJ/J+S83dI8rHvyAcmGrRes5wMOiVaFPglreO/H//AgvcR+N/zYOrV4qCWboU+oTBz7A/ZzMGGt6mhL4dmDKDW3p/HT0l5dEfAn71fdx/VH+jXquVr/9rCw2F4kLzXiNB6E3OBxp7bjkgnmAWCXeNL8NRcOT2l6LaF1l+xi3+NJGxP6tdry+OYz/C12jAZ223HWtQv62fLS3wAuwJH3QjrYromeWU+MNyTdMEFRyuxMq9mpYno7tYF6FpVAR7w9oIZME7F36+1I2b7MERXsgioEBGJFWotC9v5nEKWLJJajZFPlsFQf96Y6Cwovd4moVNmDJ8s2riRDx9D9NxDJxNkz0l+JSLTloTI9p7uMPC6LJtP6qgNAdNtasrUnPo8z5h7kYJR0U8ClsZbOZcf13cSdZck9jZp0kqiSBREhVHGLQmqirXm7UEnoTZYn8U74l3wsetgGiQ3AOAQ94REbzt1obHtGj4JG9Fd3KydWNMcOv1hLODw==\",\"sig\":\"ee99080081a408aa2ce0e2372a44aa0eb1e8e60aa7b4330909d7c7a701d84076a7815412c83a7aa1b783ed0942b0f5e2e2f63efeee8aa0c69503971c65370c3d\"}";
382395

383-
assert(count == 10);
384-
*/
396+
ndb_process_event(ndb, giftwrap, strlen(giftwrap));
397+
398+
ok = ndb_wait_for_notes(ndb, subid, note_ids,
399+
sizeof(note_ids)/sizeof(note_ids[0]));
400+
assert(ok == 1);
401+
402+
ndb_begin_query(ndb, &txn);
403+
rumor = ndb_get_note_by_key(&txn, note_ids[0], NULL);
404+
405+
assert(ndb_note_is_rumor(rumor) == 1);
406+
assert(ndb_note_kind(rumor) == 1);
407+
assert(!strcmp(ndb_note_content(rumor), "hi"));
408+
assert(0 == memcmp(ndb_note_rumor_giftwrap_id(rumor), giftwrap_id, 32));
409+
assert(0 == memcmp(ndb_note_rumor_receiver_pubkey(rumor), recv_pub, 32));
410+
assert(ndb_get_note_by_id(&txn, giftwrap_id, NULL, NULL));
411+
412+
ndb_end_query(&txn);
413+
414+
415+
ndb_filter_destroy(&filter);
416+
ndb_destroy(ndb);
417+
printf("ok test_giftwrap_unwrap\n");
385418
}
386419

387420
static void test_metadata()
@@ -2421,6 +2454,7 @@ void test_replay_attack() {
24212454

24222455
const char *ok_note = "[\"EVENT\",\"blah\",{\"id\": \"1f5f21b22e4c87b1d7cf9271a1c8aeaf5b49061af2c03cab706bbe2ebb9fefd9\",\"pubkey\": \"73764df506728297a9c1f359024d2f9c895001f4afda2d0afa844ce7a94778ca\",\"created_at\": 1750785986,\"kind\": 1,\"tags\": [],\"content\": \"ok\",\"sig\": \"bde9ee6933b01c11a9881a3ea4730c6e7f7d952c165fb7ab3f77488c5f73e6d60ce25a32386f2e1d0244c24fd840f25af5d2d04dc6d229ec0f67c7782e8879d9\"}]";
24232456

2457+
delete_test_db();
24242458
ndb_default_config(&config);
24252459
assert(ndb_init(&ndb, test_dir, &config));
24262460

@@ -2452,6 +2486,7 @@ void test_replay_attack() {
24522486
int main(int argc, const char *argv[]) {
24532487
delete_test_db();
24542488

2489+
test_giftwrap_unwrap();
24552490
test_nip44_round_trip();
24562491
test_nip44_test_vector();
24572492
test_nip44_decrypt();

0 commit comments

Comments
 (0)