Documentation ¶
Overview ¶
Package horcrux provides security question style password recovery while preserving end-to-end cryptographic security.
Given N pairs of security questions and answers, the secret is split using Shamir's Secret Sharing algorithm into N shares, one for each question. A 256-bit key is derived from the answer to each question using scrypt, and the share is then encrypted with that key using ChaCha20Poly1305.
To recover the secret given K of N answers, the secret keys are re-derived and the shares are decrypted and combined.
This package has not been audited by cryptography or security professionals.
Example ¶
secret := []byte("my favorite password") questions := map[string]string{ "What's your first pet's name?": "Spot", "What's your least favorite food?": "broccoli", "What's your mother's maiden name?": "Hernandez", "What's your real name?": "Rumplestiltskin", } // Split into four fragments, any two of which can be combined to recover // the secret. frags, err := Split(secret, questions, 2, 2<<14, 8, 1) if err != nil { fmt.Println(err) return } // Answer two of the security questions. answers := make([]Answer, 2) for i := range answers { answers[i] = Answer{ Fragment: frags[i], Answer: questions[frags[i].Question], } } // Recover the original secret. s, err := Recover(answers) if err != nil { fmt.Println(err) return } fmt.Println(string(s))
Output: my favorite password
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Answer ¶
type Answer struct { Fragment // Fragment is the previously-encrypted fragment. Answer string // Answer is the answer to the security question. }
Answer is an encrypted fragment of the secret, plus the answer to the security question.
type Fragment ¶
type Fragment struct { ID byte // ID is a unique identifier for the fragment. K int // K is the number of fragments required to recover the secret. N int // N is the scrypt iteration parameter. R int // R is the scrypt memory parameter. P int // P is the scrypt parallelism parameter. Question string // Question is the security question. Nonce []byte // Nonce is the random nonce used for encryption. Salt []byte // Salt is the random salt used for scrypt. Value []byte // Value is the encrypted share. }
Fragment is an encrypted fragment of the secret associated with a security question.
func Split ¶
Split splits the given secret into encrypted fragments based on the given security questions. k is the number of fragments required to recover the secret. n is the scrypt iteration parameter, and should be set fairly high due to the low entropy of most security question answers (recommended: 2<<14). r is the scrypt memory parameter (recommended: 8). p is the scrypt parallelism parameter (recommended: 1). Returns either a slice of fragments or an error.