Bitcoin Forum
May 06, 2024, 02:32:19 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: M-of-N passwords to generate wallet encryption key  (Read 2569 times)
etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
June 11, 2014, 09:32:11 PM
Last edit: June 11, 2014, 10:35:48 PM by etotheipi
 #1

Today I was thinking about the idea that you could implement a software-based multi-factor encryption key for a wallet.  What comes to mind is Shamir's Secret Sharing, but in reverse.  I'll explain what that means after I explain basic SSS.

Goal
Modify wallet encryption, which normally requires the user to enter a password, and then key stretches it into a symmetric encryption key (such as AES256) and uses that to encrypt the wallet private keys.  What I would like is:  during wallet setup, you can have 3 passwords entered, and any 2 of them would be sufficient for the system to compute the AES256 encryption key.   Of course, it would be nice to implement any M-of-N.

The idea is that 3 employees of an [wing of] an organization would be responsible for managing either a single-sig wallet, or a single key of a multi-sig wallet.  In order to gain access to the offline key to sign transactions, the wallet will need to be decrypted, but the decryption key can't be calculated from any single employee's password.  


Background
Shamir's Secret Sharing is a mechanism by which a secret piece of data is interpretted as the highest order coefficeint of a polynomial, and then points of that polynomial are distributed and stored separately.  For instance, you store the secret as the slope of a line, and then you write down three points of the line on separate pieces of paper.  If you have any two pieces of paper, you have two points on the line and can compute the slope--which recovers the secret.  This would be 2-of-3.  You can do this with any M and N, using N points on an (M-1)th order polynomial.

While this concept is easy to visualize like we did in high school, you can't use floating point numbers because of precision issues.  Instead, you do all operations on finite fields, which are really just modulo-arithmatic, cyclic groups.  You simply define all operations to be on integers between 1 and some large prime N, define division to be   a/b = a * bN-1, and then you can implement all the algebra identically.  I won't go into the details here, but this is how SSS is implemented in crypto systems.  However, usually the prime N is chosen ahead of time, and known by the device, so it knows which finite field to use to combine the points.  

Rephrased goal:  
Shamir's Secret Sharing is a process for converting a secret into M-of-N shares to be distributed.  What I want is a process for converting N shares (user passwords) into an M-of-N secret.  It's the inverse of the problem being solved by SSS.


Half-way there
If this was 2-of-2,  3-of-3, or M-of-M, stock SSS would work.  Say for 3-of-3:  the system collects all three passwords when the wallet is created, computes the highest-order coeffiicent of the parabola created by the hash of all three passwords (perhaps using the first four bytes of the hash as the X-value, and the remaining as the Y-value), then uses that as the encryption key for the wallet.  When all passwords are entered, the system can compute this value, decrypt the wallet, then destroy it.  This works, though there are simpler ways to combine mulitple passwords.   But how do you do arbitrary M-of-N?  


Discussion
But this doesn't work for M-of-N where M is not equal to N.  For 2-of-3:  you would like to compute a slope that could be computed from any two of the three points, but the three points are not co-linear in a pre-defined finite field.   One way would be to collect all the passwords first, and then figure out a set of finite field parameters for which all three points are colinear (for simple prime-based finite fields, try to find a prime N such that they are colinear).  Store the FF parameters in the wallet, and the wallet will use that data when two passwords are entered.    But this feels like a hack.

Unfortunately, my googling skills are failing me -- as I keep running into a bunch of unrelated things.   I feel like this must be a solved problem, and I just need to find the right documentation of it.


Alternatives
The best alternative is to simply not let users create passwords, but create a secure encryption key, then use SSS and put the shares onto smartcards.  In the institutional security world, this is at least how backups are made when using HSMs (and how Armory does fragmented backups of its wallets).  In this case, we're simply trying to expand on the user-password concept to be executed on consumer PCs.  At the moment, HSMs don't exist in the BTC world, and while they may, it would still be cool to have a solution for this problem here.

Another alternative, for small M and N is to simply store all N-choose-M multi-encrypted forms of the encryption key.  For instance, for 2-of-3, the encryption key will be randomly generated by the system, and then it will be stored 3 times in the wallet, each one encrypted with a different 2 keys.  Decrypting would simply be matter of trying to decrypt all three keys and picking the one that works (if any).  But this is an even bigger hack, and it doesn't scale very well (though modern computers could handle most use-cases pretty easily if there was no additional key stretching).


Caveats
I recognize we're still talking about a single piece of consumer hardware that could be compromised by malware, or someone with DMA could swipe the key from RAM once all passwords are entered, etc.  The goal is to provide a mechanism whereby multiple people are required to access the system, and together they monitor all interactions with the system and verify that no one is tampering/manipulating it.  Is it failproof?  No.  But it still prevents one person who temporarily gains access from pulling the key off the disk, even if they have one password.  If proper access control is exercised, this might provide another tool for implementing segregation of duties, in-place-of or in-addition-to multi-sig transactions.  

In the future, this might be moot, since orgs will move to HSMs which are all tamper-proof, destroy the private keys if you try to open, implement similar M-of-N access control, etc.  But for consumer hardware, I think this could be pretty strong.


Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
1715005939
Hero Member
*
Offline Offline

Posts: 1715005939

View Profile Personal Message (Offline)

Ignore
1715005939
Reply with quote  #2

1715005939
Report to moderator
You get merit points when someone likes your post enough to give you some. And for every 2 merit points you receive, you can send 1 merit point to someone else!
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715005939
Hero Member
*
Offline Offline

Posts: 1715005939

View Profile Personal Message (Offline)

Ignore
1715005939
Reply with quote  #2

1715005939
Report to moderator
Crowex
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
June 11, 2014, 10:24:01 PM
 #2

 Can't Shamir's secret sharing scheme already do the same sort of thing?

 If you want a (k,n) threshold scheme where at least k out of n are required to reveal the secret then you construct a polynomial of degree k-1.
Calculate any n points (x,y) on this curve (n must be less than P where P is the order of the finite field) and distribute these to the participants.
Any subset k of these points will allow you to use Lagrange interpolation to calculate the coefficients of the curve and calculate the constant term (which is the secret).

 Your key creating software would have to choose (pseudo) random coefficients for the curve and calculate the n points to give to the participants. The wallet is encrypted with the constant term of the curve. The wallet software (that has no knowledge of the coefficients of the curve) could recreate the encryption key (the constant term) given k out of n points on the curve.

 Perhaps I've misunderstood your problem. I'm not sure if that's exactly what you require?

 

 

 

 
jonald_fyookball
Legendary
*
Offline Offline

Activity: 1302
Merit: 1004


Core dev leaves me neg feedback #abuse #political


View Profile
June 11, 2014, 10:27:13 PM
 #3

Very interesting etotheipi.

I always assumed SSS was m of n already... its not?
 
Would this simply be another implementation of multisig? 
What would be the advantage over the current one?

etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
June 11, 2014, 10:27:51 PM
 #4

Can't Shamir's secret sharing scheme already do the same sort of thing?

 If you want a (k,n) threshold scheme where at least k out of n are required to reveal the secret then you construct a polynomial of degree k-1.
Calculate any n points (x,y) on this curve (n must be less than P where P is the order of the finite field) and distribute these to the participants.
Any subset k of these points will allow you to use Lagrange interpolation to calculate the coefficients of the curve and calculate the constant term (which is the secret).

 Your key creating software would have to choose (pseudo) random coefficients for the curve and calculate the n points to give to the participants. The wallet is encrypted with the constant term of the curve. The wallet software (that has no knowledge of the coefficients of the curve) could recreate the encryption key (the constant term) given k out of n points on the curve.

 Perhaps I've misunderstood your problem. I'm not sure if that's exactly what you require?

Yeah, I should've been more clear in my post.  Rephrasing what you said:

Shamir's Secret Sharing usually starts with a secret, and then you split it into M-of-N shares.   The participants receiving the shares get no say in the data contained in the shares.   You start with the secret and get M-of-N shares.

What I want is that your N participants each produce their own shares indpendently (their passwords), and then some calculation is performed on all of them to produce an encryption key that is only computable with M of them.   You start with the shares, and get an M-of-N secret.  It is okay if this process produces a piece of non-sensitive data that needs to be stored with the encrypted data to complete the computation.

When phrased that way, it's just an inverse of the problem that SSS solves

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
June 11, 2014, 10:41:45 PM
Last edit: June 12, 2014, 12:14:24 AM by DeathAndTaxes
 #5

One way to achieve this would be to generate a random AES key, use SSS to split it and then encrypt the each of the pieces with their corresponding passwords.

So AES_MasterKey -> SSS(2 of 3) -> {S1, S2, S3}

Encrypt(S1, PBKDF2(password1)) = Encrypted_S1
Encrypt(S2, PBKDF2(password2)) = Encrypted_S2
Encrypt(S3, PBKDF2(password3)) = Encrypted_S3

Store Encrypted_S1, Encrypted_S2, & Encrypted_S3 in the wallet file.

You need at least two of the passwords and the wallet file to recover the master key.

Crowex
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
June 11, 2014, 11:54:56 PM
 #6

there are versions of SSS where the participants can use their own passwords to create the secret
google 'secret sharing without a dealer' - https://eprint.iacr.org/2011/241.pdf
and you can construct m of n threshold schemes
these schemes need to be 'verifiable' so that you know that all of the participants are being honest

But if you want to use a symmetric encryption scheme you have to get round the problem that you have to reconstruct the secret in order to encrypt the wallet and not just to decrypt it.

this paper was discussed a while ago

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.67.9913&rep=rep1&type=pdf

if you use the 'no dealer' scheme here then you can let the participants choose their own 'passwords' and use it to construct a public key (which can be verified) and then m of n participants can produce a signature.
 So in a DSA only the person (or the m of n people) with the private key can 'encrypt' or 'sign' a document and anybody with the public key can 'decrypt' or verify the signature.

 So, by reversing this, maybe you could sort of use this to achieve what (I think) you are suggesting. You encrypt the wallet with the public key and need the 'm of n' participants to decrypt but you are using  asymmetric encryption so that you don't have to construct the secret in order to encrypt the wallet.

 The main problem with a lot of these schemes is that you need secure 'point to point' communication between individual participants and this can make things get complicated. As if they weren't complicated enough already. Smiley
 

etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
June 12, 2014, 05:01:29 PM
Last edit: June 15, 2014, 05:11:43 AM by etotheipi
 #7

One way to achieve this would be to generate a random AES key, use SSS to split it and then encrypt the each of the pieces with their corresponding passwords.

So AES_MasterKey -> SSS(2 of 3) -> {S1, S2, S3}

Encrypt(S1, PBKDF2(password1)) = Encrypted_S1
Encrypt(S2, PBKDF2(password2)) = Encrypted_S2
Encrypt(S3, PBKDF2(password3)) = Encrypted_S3

Store Encrypted_S1, Encrypted_S2, & Encrypted_S3 in the wallet file.

You need at least two of the passwords and the wallet file to recover the master key.

I think this is the right answer!  Rather, it securely gets me what I want without too much implementation complexity.

@Crowex:  this is cool stuff.  I'm glad I finally know what to search for.   I'm a mathematician, so I am still intrigued by these theoretical solutions, and I'd love to find some math that does this naturally instead of the solution D&T posted above.  Though, if I put these features into Armory it will be D&T's solution for obvious reasons.   But I'm happy to continue discussing the math in this thread.

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
July 21, 2014, 05:13:36 AM
 #8

FYI, this feature slid quite nicely into the new wallet format I'm working on.  One thing I wanted to mention for completeness, is the necessity to make sure that you cannot verify passwords individually.  I am storing key-stretching info with each fragment, so that Armory knows how to decrypt it, but all it decrypts is an opaque 32-byte chunk of data, with no clear indication of whether the result is valid.  The only way to know is if a quorum of passwords is present to restore the master encryption key, which then can be checked for accuracy.   

This is important, because it means that you are exponentially increasing the effective entropy of the master key encryption, not linear.  For instance, let's say you have a 3-of-5 password and each of the 5 participants chooses a password with 40 bits of entropy.  If you can verify each password independently then the effective brute-force time is:

Code:
3 * bruteForceTime(40bits)

Instead, I'm making sure that only the final reconstucted key can be verified, which means brute-force time is:

Code:
bruteForceTime(3 * 40bits)

Quite literally, the first one is brute-forceable while the second one is not.  The downside is that if one person types their password incorrectly, there's no way to know without everyone re-typing their passwords.  I think the CONOPS can be extended so that when the passwords are initially set, each participant ALSO inserts a USB key and gets a 3-of-5 fragment of the wallet backup (unencrypted) copied to it.   They can then protect that however they see fit, such that you need either:

(A)  Encrypted wallet file + 3-of-5 passwords
(B)  3-of-5 fragments to restore a lost wallet file

However, if three people lose the USB drive and three people forget their password, the wallet would not be recoverable despite having 4 "pieces" (2 passwords + 2 fragments).   Perhaps the unencrypted password fragment should be copied along with the unencrypted backup shard.   Either way, this seems to have all the right properties for multi-user protection of a wallet or a piece of a multi-sig wallet.  You could also print out this data onto paper, but there would probably be some OPSEC issues having 5 people in a room all being exposed/flashed to fragments getting printed. 


Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
Pages: [1]
  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!