static bool compare_serialized_prv(const struct hd_extended_key *ek, const struct hd_extended_key_serialized *ser) { struct hd_extended_key_serialized ek_prv; if (write_ek_ser_prv(&ek_prv, ek)) { return 0 == memcmp(ek_prv.data, ser->data, sizeof(ser->data)); } return false; }
wallet_for_each_mkey(wlt, hdkey) { struct hd_extended_key_serialized hdraw; bool rc = write_ek_ser_prv(&hdraw, hdkey); assert(rc == true); cstring *recdata = message_str(wlt->chain->netmagic, "hdmaster", hdraw.data, sizeof(hdraw.data) - 1); assert(recdata != NULL); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); }
static void test_serialize() { printf("TEST: test_serialize\n"); const char seed[] = "picocoin test seed"; struct hd_extended_key m; struct hd_extended_key_serialized m_xpub; struct hd_extended_key_serialized m_xprv; { assert(hd_extended_key_init(&m)); assert(hd_extended_key_generate_master(&m, seed, sizeof(seed))); assert(0 == m.depth); assert(0 == m.index); assert(write_ek_ser_pub(&m_xpub, &m)); assert(write_ek_ser_prv(&m_xprv, &m)); } // Check that there are no gaps in serialized data { struct hd_extended_key_serialized m_xpub_A; struct hd_extended_key_serialized m_xpub_B; memset(m_xpub_A.data, 0xff, sizeof(m_xpub_A.data)); assert(write_ek_ser_pub(&m_xpub_A, &m)); memset(m_xpub_B.data, 0x00, sizeof(m_xpub_B.data)); assert(write_ek_ser_pub(&m_xpub_B, &m)); assert(0 == memcmp(m_xpub_A.data, m_xpub_B.data, sizeof(m_xpub_B.data))); } { struct hd_extended_key_serialized m_xprv_A; struct hd_extended_key_serialized m_xprv_B; memset(m_xprv_A.data, 0xff, sizeof(m_xprv_A.data)); assert(write_ek_ser_prv(&m_xprv_A, &m)); memset(m_xprv_B.data, 0x00, sizeof(m_xprv_B.data)); assert(write_ek_ser_prv(&m_xprv_B, &m)); assert(0 == memcmp(m_xprv_A.data, m_xprv_B.data, sizeof(m_xprv_B.data))); } // generate child keys 1 and 2H, keep serialized version for // comparison struct hd_extended_key m_1; struct hd_extended_key_serialized m_1_xpub; struct hd_extended_key_serialized m_1_xprv; struct hd_extended_key m_2H; struct hd_extended_key_serialized m_2H_xpub; struct hd_extended_key_serialized m_2H_xprv; { assert(hd_extended_key_init(&m_1)); assert(hd_extended_key_generate_child(&m, 1, &m_1)); assert(write_ek_ser_pub(&m_1_xpub, &m_1)); assert(write_ek_ser_prv(&m_1_xprv, &m_1)); assert(hd_extended_key_init(&m_2H)); assert(hd_extended_key_generate_child(&m, 0x80000002, &m_2H)); assert(write_ek_ser_pub(&m_2H_xpub, &m_2H)); assert(write_ek_ser_prv(&m_2H_xprv, &m_2H)); } // read back in, re-serialize and check the memory { struct hd_extended_key m_1_; struct hd_extended_key_serialized m_1_xpub_; struct hd_extended_key_serialized m_1_xprv_; assert(hd_extended_key_init(&m_1_)); assert(hd_extended_key_deser(&m_1_, m_1_xprv.data, sizeof(m_1_xprv))); assert(write_ek_ser_pub(&m_1_xpub_, &m_1_)); assert(write_ek_ser_prv(&m_1_xprv_, &m_1_)); assert(0 == memcmp(&m_1_xpub, &m_1_xpub_, sizeof(m_1_xpub_))); assert(0 == memcmp(&m_1_xprv, &m_1_xprv_, sizeof(m_1_xprv_))); hd_extended_key_free(&m_1_); } { struct hd_extended_key m_2H_; struct hd_extended_key_serialized m_2H_xpub_; struct hd_extended_key_serialized m_2H_xprv_; assert(hd_extended_key_init(&m_2H_)); assert(hd_extended_key_deser(&m_2H_, m_2H_xprv.data, sizeof(m_2H_xprv))); assert(write_ek_ser_pub(&m_2H_xpub_, &m_2H_)); assert(write_ek_ser_prv(&m_2H_xprv_, &m_2H_)); assert(0 == memcmp(&m_2H_xpub, &m_2H_xpub_, sizeof(m_2H_xpub_))); assert(0 == memcmp(&m_2H_xprv, &m_2H_xprv_, sizeof(m_2H_xprv_))); hd_extended_key_free(&m_2H_); } // read back master, generate child, check prv and pub { struct hd_extended_key m_; struct hd_extended_key m_1_; struct hd_extended_key m_2H_; assert(hd_extended_key_init(&m_)); assert(hd_extended_key_deser(&m_, m_xprv.data, sizeof(m_xprv))); assert(hd_extended_key_init(&m_1_)); assert(hd_extended_key_generate_child(&m_, 1, &m_1_)); assert(check_keys_match(&m_1, &m_1_)); assert(hd_extended_key_init(&m_2H_)); assert(hd_extended_key_generate_child(&m_, 0x80000002, &m_2H_)); assert(check_keys_match(&m_2H, &m_2H_)); hd_extended_key_free(&m_2H_); hd_extended_key_free(&m_1_); hd_extended_key_free(&m_); } // read back master from xpub and generate child. ensure prv keys // can't be retrieved but public keys match. { struct hd_extended_key m_; struct hd_extended_key m_1_; uint8_t priv[32]; assert(hd_extended_key_init(&m_)); assert(hd_extended_key_deser(&m_, m_xpub.data, sizeof(m_xpub))); assert(!bp_key_secret_get(&priv[0], sizeof(priv), &m_.key)); assert(hd_extended_key_init(&m_1_)); assert(hd_extended_key_generate_child(&m_, 1, &m_1_)); assert(!bp_key_secret_get(&priv[0], sizeof(priv), &m_1_.key)); assert(check_keys_match(&m_1, &m_1_)); hd_extended_key_free(&m_1_); hd_extended_key_free(&m_); } // read back child from xpub. ensure no hardened children can be // generated. { struct hd_extended_key m_2H_; struct hd_extended_key m_2H_3H_; assert(hd_extended_key_init(&m_2H_)); assert(hd_extended_key_deser(&m_2H_, m_2H_xpub.data, sizeof(m_2H_xpub))); assert(hd_extended_key_init(&m_2H_3H_)); assert(!hd_extended_key_generate_child(&m_2H_, 0x80000003, &m_2H_)); hd_extended_key_free(&m_2H_3H_); hd_extended_key_free(&m_2H_); } hd_extended_key_free(&m_2H); hd_extended_key_free(&m_1); hd_extended_key_free(&m); }