-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[seraphis_wallet]: key container #15
base: seraphis_wallet
Are you sure you want to change the base?
[seraphis_wallet]: key container #15
Conversation
…is_lib_hist_05_15_23 branch for commit history
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.
For me this class leads to a surprising number of quite "deep" questions about the architecture of the wallet and the schemes that the wallet code will use. I will invite other team members to leave opinions and comments in the Matrix room.
In any case I think it may take some time to disuss this all and get this into a merge-ready state ...
sp::jamtis::make_jamtis_ciphertag_secret(test_keys.s_ga, test_keys.s_ct); | ||
sp::make_seraphis_spendkey(test_keys.k_vb, test_keys.k_m, test_keys.K_1_base); | ||
sp::jamtis::make_jamtis_unlockamounts_pubkey(test_keys.xk_ua, test_keys.xK_ua); | ||
sp::jamtis::make_jamtis_findreceived_pubkey(test_keys.xk_fr, test_keys.xK_ua, test_keys.xK_fr); |
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.
Already one more of these quite general questions that I ask myself when going through this code, but can't arrive at an answer: If it's so easy to derive all keys from the one base one, why would we still read and write all of them? Why not just write the spend key and then re-generate all the other keys when deserializing?
{ | ||
} | ||
//------------------------------------------------------------------------------------------------------------------- | ||
boost::optional<KeyContainer> KeyContainer::load_from(const std::string &path, const crypto::chacha_key &key) |
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.
Right now I don't think that we will ever have to support this use case in the final code, i.e. reading and writing a key container alone in and out of files. Maybe it's a good idea to move such capabilities into the unit tests.
return write_encrypted_file(path, key, view_only_keys); | ||
} | ||
//------------------------------------------------------------------------------------------------------------------- | ||
bool KeyContainer::write_view_balance(const std::string &path, const crypto::chacha_key &key) |
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.
I think it's a quite difficult question to decide how to implement different wallet types, like full wallet, read-only wallet, address-generation wallet, multisig wallet, whatever. I am not sure at all whether finally the way to go will be to have a set of different read and write methods in the key container class here. Maybe leave those away for the time being? But seems to me I should not decide this alone, eager to read what other people are thinking.
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.
I think these are convenient for the tiers that make sense to share around
/// | ||
struct jamtis_keys | ||
{ | ||
crypto::secret_key k_m; //master |
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.
I don't know the Seraphis lib that closely yet. Are very short and at first sight quite cryptic names like k_m
the norm there? Do tons of comments refer to this key as k_m
so it would not be a good idea to give this a more "speaking" name like master_key
?
Paging @jeffro256, @jberman and @DangerousFreedom1984 for their opinions as well.
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.
I agree with this. Imo the key names should be more descriptive (and not abbreviated like this) everywhere they're used.
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.
it's from jamtis.md iirc
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.
I'm still more a proponent of descriptive names in the code; imo it makes it easier to follow without keeping so much in your head. I think it's fine for the spec (math papers usually use one letter notation). I also think matching the spec is ok, so I'm fine with either way.
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.
I'm still more a proponent of descriptive names in the code
+1
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.
After thinking about it again, one more vote to switch to the usual descriptive names for things. Devs shouldn't have to deal with names like xk_fr
or even mixed-case K_1_base
for so fundamental things. Descriptive names trump having names that are identical with the spec, IMHO.
{ | ||
//------------------------------------------------------------------------------------------------------------------- | ||
// INTERNAL | ||
static jamtis_keys ser_keys_to_jamtis(ser_jamtis_keys const &keys) |
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.
As far as I remember we never properly discussed this issue I wrote back in summer whether we really use the Seraphis library scheme of pairs of classes, one "normal" and one ser_
class, for serialization of wallet classes. Maybe now it's the time to come back to this?
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.
I don't think they should be here
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.
The idea and implementation of the key container looks like going in the right direction to me. I like the idea of not being dependent on the generate_chacha_key
function in these classes. But maybe would be better to have something to replace it?
/// | ||
struct jamtis_keys | ||
{ | ||
crypto::secret_key k_m; //master |
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.
I'm still more a proponent of descriptive names in the code
+1
src/seraphis_wallet/jamtis_keys.cpp
Outdated
user_address_out); | ||
} | ||
//------------------------------------------------------------------------------------------------------------------- | ||
void jamtis_keys::encrypt(const crypto::chacha_key &key, const crypto::chacha_iv &iv) |
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.
Wallet2 is doing that to (re)store a private key in this order:
- from password uses cn_slow_hash to get chacha key.
- from chacha key use encrypt/decrypt function.
- from encrypt/decrypt function uses cn_slow_hash to get derived chacha key.
- from derived chacha key uses chacha20 to encrypt data.
Here you are proposing to encrypt/decrypt the keys directly using chacha20 without using a derived key or another round of the generate_chacha_key
which is based on a hashing algorithm (cn_slow_hash) in this case. So from my understanding we would be removing one layer of security here. Maybe it could be added later when generating the chacha key that will feed these functions. Do you have any comments here?
I don't like the idea of using cn_slow_hash but I also dont like to remove this another layer of hashing.
add comments and modify some functions in the key_container
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.
This is my first review, so take it with a grain of salt. My intention was to be diligent, sorry if it comes off as nitpicking.
From my POV, except the small things I commented on, this looks complete.
BEGIN_SERIALIZE_OBJECT() | ||
VERSION_FIELD(0) | ||
FIELD(encrypted_data) | ||
FIELD(iv) | ||
END_SERIALIZE() |
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.
I'd say indent fields between BEGIN_SERIALIZE and END_SERIALIZE for consistency, but then realized this file was already merged, so not sure.
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.
sure. it's just that clang-format doesn't understand this format, so I'm hesitant
src/seraphis_wallet/key_container.h
Outdated
FIELD(k_m) | ||
FIELD(k_vb) | ||
FIELD(xk_ua) | ||
FIELD(xk_fr) | ||
FIELD(s_ga) | ||
FIELD(s_ct) | ||
FIELD(K_1_base) | ||
FIELD(xK_ua) | ||
FIELD(xK_fr) |
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.
Indent.
src/seraphis_wallet/key_container.h
Outdated
FIELD(keys) | ||
FIELD(encryption_iv) | ||
FIELD(encrypted) |
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.
Indent.
BEGIN_SERIALIZE() | ||
FIELD(data) | ||
END_SERIALIZE() | ||
|
||
BEGIN_KV_SERIALIZE_MAP() | ||
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(data) | ||
END_KV_SERIALIZE_MAP() |
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.
Indent fields.
last question: to indent, or not to indent? |
e2ca1aa
to
bf95191
Compare
bf95191
to
e651e0b
Compare
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.
Could you rebase your branch with the most updated seraphis_wallet branch and then force push your last changes?
#include "seraphis_wallet/key_container.h" | ||
#include <cassert> | ||
#include <openssl/crypto.h> | ||
#include <sodium/crypto_verify_32.h> |
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.
What functions do you need from these libraries?
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.
crypto.h from openssl I don't think I need
I think we should include a clang-tidy to tell us about these issues.
return seraphis_wallet::WalletType::PaymentValidator; | ||
} | ||
|
||
if (is_one(keys.d_fa) && is_one(keys.s_ga)) |
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.
Why they have to be equal to the identity? They should be different from zero, right?
You can use keys.d_fa == x25519_secret_key{}
for example to compare the private x25519 keys to zero.
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.
right, will fix
that will not be constant time :) if that matters even
@ghostway0, will you have opportunity to bring this to a conclusion anytime soon, what do you think? |
depends on #14
would love feedback
cc @rbrunner7