Skip to content
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

Draft
wants to merge 17 commits into
base: seraphis_wallet
Choose a base branch
from

Conversation

ghostway0
Copy link

@ghostway0 ghostway0 commented Nov 3, 2023

depends on #14
would love feedback
cc @rbrunner7

Copy link
Member

@rbrunner7 rbrunner7 left a 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);
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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.

Copy link
Author

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

src/seraphis_wallet/jamtis_keys.h Outdated Show resolved Hide resolved
///
struct jamtis_keys
{
crypto::secret_key k_m; //master
Copy link
Member

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.

Copy link

@j-berman j-berman Nov 6, 2023

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.

Copy link
Author

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

Copy link

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.

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

Copy link
Member

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.

src/seraphis_wallet/jamtis_keys.h Outdated Show resolved Hide resolved
{
//-------------------------------------------------------------------------------------------------------------------
// INTERNAL
static jamtis_keys ser_keys_to_jamtis(ser_jamtis_keys const &keys)
Copy link
Member

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?

Copy link
Author

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

Copy link

@DangerousFreedom1984 DangerousFreedom1984 left a 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?

src/seraphis_wallet/jamtis_keys.h Outdated Show resolved Hide resolved
src/seraphis_wallet/jamtis_keys.cpp Outdated Show resolved Hide resolved
///
struct jamtis_keys
{
crypto::secret_key k_m; //master

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/key_container.h Outdated Show resolved Hide resolved
user_address_out);
}
//-------------------------------------------------------------------------------------------------------------------
void jamtis_keys::encrypt(const crypto::chacha_key &key, const crypto::chacha_iv &iv)

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.

DangerousFreedom and others added 2 commits January 11, 2024 07:10
Copy link

@SNeedlewoods SNeedlewoods left a 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.

tests/unit_tests/encrypted_file.cpp Outdated Show resolved Hide resolved
Comment on lines +21 to +25
BEGIN_SERIALIZE_OBJECT()
VERSION_FIELD(0)
FIELD(encrypted_data)
FIELD(iv)
END_SERIALIZE()

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.

Copy link
Author

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/jamtis_keys.cpp Outdated Show resolved Hide resolved
src/seraphis_wallet/jamtis_keys.h Outdated Show resolved Hide resolved
src/seraphis_wallet/jamtis_keys.h Outdated Show resolved Hide resolved
Comment on lines 60 to 68
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)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent.

Comment on lines 79 to 81
FIELD(keys)
FIELD(encryption_iv)
FIELD(encrypted)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent.

Comment on lines +13 to +19
BEGIN_SERIALIZE()
FIELD(data)
END_SERIALIZE()

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(data)
END_KV_SERIALIZE_MAP()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent fields.

tests/unit_tests/encrypted_file.cpp Outdated Show resolved Hide resolved
tests/unit_tests/key_container.cpp Outdated Show resolved Hide resolved
@ghostway0
Copy link
Author

last question: to indent, or not to indent?
indenting those FIELDs is what happened until now, but it also means that we're going against the new clang-format file. wdyt?

Copy link

@DangerousFreedom1984 DangerousFreedom1984 left a 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>

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?

Copy link
Author

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))

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.

Copy link
Author

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

src/seraphis_wallet/jamtis_keys.cpp Outdated Show resolved Hide resolved
src/seraphis_wallet/jamtis_keys.h Show resolved Hide resolved
@rbrunner7
Copy link
Member

@ghostway0, will you have opportunity to bring this to a conclusion anytime soon, what do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants