Bitcoin Forum
May 04, 2024, 01:34:58 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 [4] 5 6 7 8 »  All
  Print  
Author Topic: Proposal: Base58 encoded HD Wallet root key with optional encryption  (Read 20941 times)
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 22, 2013, 12:07:48 AM
Last edit: December 22, 2013, 11:24:43 AM by riplin
 #61

I just boarded a plane, so I can't look at I right now, but a quick question for gmaxwell and others about using the hash of the private key instead of the address: yes / no?
1714786498
Hero Member
*
Offline Offline

Posts: 1714786498

View Profile Personal Message (Offline)

Ignore
1714786498
Reply with quote  #2

1714786498
Report to moderator
1714786498
Hero Member
*
Offline Offline

Posts: 1714786498

View Profile Personal Message (Offline)

Ignore
1714786498
Reply with quote  #2

1714786498
Report to moderator
1714786498
Hero Member
*
Offline Offline

Posts: 1714786498

View Profile Personal Message (Offline)

Ignore
1714786498
Reply with quote  #2

1714786498
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714786498
Hero Member
*
Offline Offline

Posts: 1714786498

View Profile Personal Message (Offline)

Ignore
1714786498
Reply with quote  #2

1714786498
Report to moderator
callem
Member
**
Offline Offline

Activity: 130
Merit: 10


View Profile
December 22, 2013, 07:50:57 PM
 #62

Block number might be a reasonable alternative to a date? Less arbitrary?

wyager
Member
**
Offline Offline

Activity: 98
Merit: 10



View Profile
December 22, 2013, 08:11:13 PM
 #63

Block number might be a reasonable alternative to a date? Less arbitrary?

Good thinking, but that actually exacerbates the problem I brought up earlier (that some computers aren't internet connected). The block production time is actually a tad unpredictable, since sometimes (in fact, for the last few months) the network hash rate grows so fast that the difficulty adjustment algorithm can't compensate enough to keep the average block production time very close to 10 minutes. Therefore, it's effectively impossible for an offline wallet generator (which is probably one of the most common uses of these wallet encryption algorithms) to get an accurate, or even semi-accurate, block number. But date can trivially be mapped to block height on a networked machine, once the coins are being spent.

OTC-WoT: 1BWF66DuVqBCSFksUgkLtdYmHucpBgPmVm
StarfishPrime
Sr. Member
****
Offline Offline

Activity: 358
Merit: 250


View Profile
December 23, 2013, 12:59:12 AM
Last edit: December 23, 2013, 06:03:10 AM by StarfishPrime
 #64

Well, I certainly intend it to replace BIP38.  BIP38 was dropped onto the wiki without any public review or discussion and contains a number of unfortunate shortcomings which are corrected here.

The WRT third party generation, I think this proposal does accommodate that in a not-quite 1:1 manner... in that you can send someone off your encrypted key to transcribe.  Though even if it doesn't thats just a single use case— the fact that BIP38 can only accommodate a single address is a reason something should replace it even for that use case. Though I'm not sure how common that usecase will be in the future considering recent regulatory activity.

Regardless of how it found its way to the wiki (over a year ago), BIP38 has already become the defacto standard for single key encryption for off-line storage, possibly since there wasn't really anything else out there. Many (most?) paper wallets now support it, along with at least one major wallet (Blockchain).

To be sure it may have a few shortcomings like fixed scrypt parameters, but its actually pretty versatile and cryptographically sound for its intended use: Encrypting single private keys and third-party key generation - it appears that it was never really intended to create/backup deterministic wallets, so these aren't necessarily shortcomings anyway, since the standards probably don't have much overlap for most use cases.


                         
    ¦                     
  ¦    ¦¦¦               
¦¦  ¦¦¦¦                 
                             ¦¦  ¦¦¦¦
                          ¦ ¦¦ ¦¦¦¦                     
                         ¦¦¦¦¦¦¦¦
                        ¦¦¦¦¦¦¦
                        ¦¦¦¦¦¦
                  ¦¦¦  ¦¦¦¦¦¦
                   ¦ ¦¦¦¦¦¦

                    ¦¦  ¦ ¦¦¦¦
                    ¦¦    ¦¦¦¦
                    ¦¦  ¦ ¦¦¦¦
                   ¦¦¦  ¦ ¦¦¦¦¦
                ¦¦¦¦    ¦ ¦¦¦¦¦¦¦¦
             ¦¦¦¦¦    ¦ ¦¦ ¦¦¦¦¦¦¦¦¦¦
          ¦¦¦¦¦       ¦  ¦   ¦¦¦¦¦¦¦¦¦¦¦
        ¦¦¦¦         ¦        ¦¦¦¦¦¦¦¦¦¦¦¦
     ¦¦¦¦          ¦      ¦    ¦¦¦¦¦¦¦¦¦¦¦¦¦¦
    ¦¦¦         ¦¦         ¦   ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
   ¦¦        ¦¦         ¦¦  ¦   ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
  ¦¦       ¦          ¦ ¦¦   ¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
 ¦¦¦     ¦¦          ¦   ¦    ¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¦¦¦     ¦          ¦      ¦   ¦¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¦¦¦    ¦        ¦¦         ¦¦  ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¦¦¦   ¦¦     ¦¦         ¦   ¦  ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¦¦¦   ¦     ¦¦         ¦¦¦   ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
 ¦¦   ¦¦    ¦        ¦    ¦  ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
 ¦¦    ¦   ¦        ¦¦    ¦  ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
  ¦¦    ¦  ¦¦       ¦     ¦  ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
   ¦¦    ¦  ¦      ¦      ¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
    ¦¦¦   ¦ ¦¦     ¦¦     ¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
     ¦¦¦   ¦ ¦¦     ¦¦    ¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
       ¦¦¦¦  ¦ ¦¦    ¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
          ¦¦¦¦¦¦  ¦¦  ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
             ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
                        ¦¦

.
TorCoin.....
¦
¦
¦
¦
  Fully Anonymous TOR-integrated Crypto
               ¦ Windows     ¦ Linux     ¦ GitHub     ¦ macOS
     ¦
     ¦
     ¦
     ¦
.
   ANN THREAD
     ¦
     ¦
     ¦
     ¦
[/center]
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 26, 2013, 11:41:35 AM
 #65

I've changed the checksum to be a double SHA256 of the private key instead of the address string and I changed the hashing so it can be outsourced to a 3rd party.

apetersson
Hero Member
*****
Offline Offline

Activity: 668
Merit: 501



View Profile
December 26, 2013, 03:46:26 PM
 #66

would it be possible to modify the checksum to a bloom filter so that you can do plausible deniability with multiple passwords?
wyager
Member
**
Offline Offline

Activity: 98
Merit: 10



View Profile
December 26, 2013, 08:55:13 PM
Last edit: December 26, 2013, 09:28:23 PM by wyager
 #67

I've changed the checksum to be a double SHA256 of the private key instead of the address string and I changed the hashing so it can be outsourced to a 3rd party.

Great. I'm working to update my reference implementation.

I'm a little confused on the 3rd party thing, though. What is the need for this?

Also, a few questions on the implementation side of things:

Quote
8. Derive hash preH from the passphrase and the salt using HMAC-SHA512(key = salt, msg = passphrase).
9. Derive hash strongH from preH using the selected KDF + parameters, where preH is both salt and message. This step can optionally be outsourced to a 3rd party.
10. Derive hash postH from the salt and the passphrase using HMAC-SHA512(key = passphrase, msg = salt).
11. Derive a hash H from the strongH and the postH using scrypt, where message = postH and salt = strongH and parameters n = 210, r = 1, p = 1. The output length = root key length + 32.

1. Why do we use key=salt, msg=passphrase in 8. but key=passphrase, msg=salt in 10.?

2. Can you please expand on step 9.? If we're using scrypt, we also need to provide an output length parameter. What should that be? Why do we use preH for both salt and message? Is that safe?

OTC-WoT: 1BWF66DuVqBCSFksUgkLtdYmHucpBgPmVm
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 26, 2013, 09:51:50 PM
 #68

I've changed the checksum to be a double SHA256 of the private key instead of the address string and I changed the hashing so it can be outsourced to a 3rd party.

Great. I'm working to update my reference implementation.

Great! Make sure you can parse the test vectors. Smiley Also, apetersson's suggestion of changing the checksum to a bloom filter is interesting. The only thing I worry about is losing entropy, so anyone here that knows how to construct a sufficiently obfuscated bloom filter that's both useful and doesn't affect entropy too much, please let us know.

I'm a little confused on the 3rd party thing, though. What is the need for this?

On page 2 in this thread, there's discussion on having 3rd party KDF support added.

Also, a few questions on the implementation side of things:

Quote
8. Derive hash preH from the passphrase and the salt using HMAC-SHA512(key = salt, msg = passphrase).
9. Derive hash strongH from preH using the selected KDF + parameters, where preH is both salt and message. This step can optionally be outsourced to a 3rd party.
10. Derive hash postH from the salt and the passphrase using HMAC-SHA512(key = passphrase, msg = salt).
11. Derive a hash H from the strongH and the postH using scrypt, where message = postH and salt = strongH and parameters n = 210, r = 1, p = 1. The output length = root key length + 32.

1. Why do we use key=salt, msg=passphrase in 8. but key=passphrase, msg=salt in 10.?

If the 3rd party that does the key stretching for us is malicious, and preH and postH are the same, he has all he needs to decrypt our root key (should he ever get his hands on it). By using a different salt in step 11, that's no longer the case and he'll have to brute force it.

2. Can you please expand on step 9.? If we're using scrypt, we also need to provide an output length parameter. What should that be? Why do we use preH for both salt and message? Is that safe?

Oops, you're right. Length of strongH = 64 bytes. I'll update the spec. Using preH as salt and message is perfectly fine. It's basically the same as not having a salt like SHA256.

wyager
Member
**
Offline Offline

Activity: 98
Merit: 10



View Profile
December 26, 2013, 10:56:02 PM
 #69

Thanks. Some small suggested changes:

1. Specify endianness of the each field. In your examples, the prefix is big-endian, but the date is little-endian. I recommend big-endian for all fields (since in many scripting languages, it's easier to go from an integer to a big-endian string than a little-endian string).

2. Recommend that client implementers check the blockchain, say, a day before the beginning of the "recorded" date to account for slightly incorrect date calculations. Either that or specify that the date code should be based on date minus one day.

OTC-WoT: 1BWF66DuVqBCSFksUgkLtdYmHucpBgPmVm
wyager
Member
**
Offline Offline

Activity: 98
Merit: 10



View Profile
December 27, 2013, 12:17:28 AM
 #70

All test vectors passed in my implementation!

Please specify that unicode passwords (like the chinese one you gave in the test vectors) should be converted to UTF-8.

OTC-WoT: 1BWF66DuVqBCSFksUgkLtdYmHucpBgPmVm
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 27, 2013, 07:56:38 AM
 #71

Thanks. Some small suggested changes:

1. Specify endianness of the each field. In your examples, the prefix is big-endian, but the date is little-endian. I recommend big-endian for all fields (since in many scripting languages, it's easier to go from an integer to a big-endian string than a little-endian string).

Bitcoin is little endian, with exception of big int math. BIP 38 is also little endian, with exception of prefix. I've clarified that the date field is little endian.

2. Recommend that client implementers check the blockchain, say, a day before the beginning of the "recorded" date to account for slightly incorrect date calculations. Either that or specify that the date code should be based on date minus one day.

Done.

All test vectors passed in my implementation!

Yay!

Please specify that unicode passwords (like the chinese one you gave in the test vectors) should be converted to UTF-8.

Done.
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 27, 2013, 03:30:28 PM
 #72

I've been doing some tests with the bloom code in the qt client, and if I understand it correctly, when set to 4 expected elements and a 1% false positive rate, the bloom filter is 4 bytes in size with 5 hash functions.

So that would generate up to 20 random bits of data in the 4 byte field. I think that's sufficient to keep the entropy up. Also, since it's 4 elements, that's 4 potential passwords that could be used.

In other words, I could modify the spec to encode up to 4 passwords into the checksum instead of the double SHA256 of the private key. Any less than 4 passwords would be filled with 5 random bits of data in the checksum for obfuscation.

What do you guys think?
grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 04:21:16 PM
 #73

For plausible deniability it should be possible to mine an alternate password that create a key that passes the checksum as is.
grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 04:24:09 PM
 #74

Created an implementation in Java that passes all test vectors:

https://github.com/bitsofproof/supernode/blob/master/api/src/main/java/com/bitsofproof/supernode/wallet/EncryptedHDRoot.java

The test cases are converted to JSON:

https://github.com/bitsofproof/supernode/blob/master/api/src/test/resources/EncryptedHDRoot.json
and were run with this unit test:
https://github.com/bitsofproof/supernode/blob/master/api/src/test/java/com/bitsofproof/supernode/api/EncryptedHDRootTest.java
riplin (OP)
Member
**
Offline Offline

Activity: 116
Merit: 10


View Profile
December 27, 2013, 04:33:50 PM
 #75

For plausible deniability it should be possible to mine an alternate password that create a key that passes the checksum as is.

If you mean mining a password on the current checksum (as currently defined in the spec), then you've got quite a bit of work ahead of you. Matching a 32bit checksum is a lot of work and the resulting password could be total gibberish and pretty hard to remember, not to mention that you're basically brute forcing the KDF, which is was chosen to resist such attacks. Or am I misunderstanding what you mean?


Awesome! Smiley
grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 05:16:55 PM
 #76

For plausible deniability it should be possible to mine an alternate password that create a key that passes the checksum as is.

If you mean mining a password on the current checksum (as currently defined in the spec), then you've got quite a bit of work ahead of you. Matching a 32bit checksum is a lot of work and the resulting password could be total gibberish and pretty hard to remember, not to mention that you're basically brute forcing the KDF, which is was chosen to resist such attacks. Or am I misunderstanding what you mean?

Yes, its a lot of work, but doable and the denial is then rather plausible. If you think that is too big of a hurdle then reduce the checksum length.


Storing the HD root is useful.
Recreating the keys that are used on the block chain needs however further conventions, so it can be done in a scalable manner.

Let's call the keys generated by the root key(0), key(1), key (3)....

Now let us assume that if key (n) is first used in block b, then there should be no reference to key(m) (m > n) in any block before b. With this rule one can efficiently scan the block chain in a single pass using a look ahead window of w:

Assume key(s) is used after block b (identified by the birth date of the root) and scan subsequent blocks. If any key (m) (s<=m<s+w) is used then continue scanning with w := w + m - s; from that block on.

Note that the search window increases during the scan. A good HD wallet software would further optimize the use of keys such that it seeks to reduce the search window by spending outputs on keys earlier in the key sequence. It would seek to re-set first key index s with a new birth date.

Therefore I suggest to extend the proposal with a start key index (4 bytes) and a look ahead window (4 bytes).




grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 05:32:29 PM
 #77

Therefore I suggest to extend the proposal with a start key index (4 bytes) and a look ahead window (4 bytes).
Actually 2 bytes should be more than enough for look ahead.
wyager
Member
**
Offline Offline

Activity: 98
Merit: 10



View Profile
December 27, 2013, 06:29:41 PM
 #78

Grau, if I'm understanding you correctly, you say that we could optimize blockchain scan times by only using keys serially? So the root key is used in the blockchain before any derivative keys, and those are used before any of their derivative keys, etc.

How do you propose to enforce this? Prevent users from choosing which address they'd like to use? It seems like that would put some annoying limitations on flexibility.


I agree with riplin that brute forcing a 32 bit hash is not a viable solution. Not only would the plausibly deniable passwords be very hard to remember, but it would take forever!

The bloom filter is interesting. You could choose arbitrary passwords to use for plausible deniability.

OTC-WoT: 1BWF66DuVqBCSFksUgkLtdYmHucpBgPmVm
grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 07:16:54 PM
 #79

A HD root can generate 2^32-1 keys and any of these keys might be the root for a further derivation. Now assume you get a HD root and would want to determine the funds associated with it. It is not feasible to find them in absence of assumptions. I suggested some assumptions I keep while developing HD wallets.

Assumptions:

1. : the root you have identifies leafs of the hierarchy. If not then use the same assumptions on the sub-levels on-by-one.
2. : if key(n) derivable from the current root is first used in block b then key(m) | m>n is not used in block d | d < b.
3. : if you do not find a use for key (n) then there is no use of any key (m) | m > n + w.

You might not like to have the assumptions, but I think they are sensible. I can not see how you implement scaleable discovery of funds associated with a root without these or similar assumptions.

If brute forcing the checksum for an alternate password is not feasible with 4 bytes then reduce the checksum length instead of introducing a more complex concept.
grau
Hero Member
*****
Offline Offline

Activity: 836
Merit: 1021


bits of proof


View Profile WWW
December 27, 2013, 07:36:48 PM
 #80

I think that the HD root is actually useless in absence of limiting assumption on its key use that allow efficient discovery of associated funds.

Assume you get a HD root where random child keys are used to store funds with, and even random child keys were used to start an other hierarchy level.. and so on. Now write an algorithm that finds the funds associated with that root in human timescale.
Pages: « 1 2 3 [4] 5 6 7 8 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!