-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeyDerivation.go
37 lines (33 loc) · 1.22 KB
/
keyDerivation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package rosetta
import (
"golang.org/x/crypto/scrypt"
"golang.org/x/crypto/sha3"
"github.com/polydawn/rosetta/cipher"
)
func DeriveKey(password []byte, keySize int) (cipher.Key, error) {
salt := deriveSalt(password)
// The constants for size and difficulty here are the defaults
// recommending in the docs: "The recommended parameters for interactive
// logins as of 2017 are N=32768, r=8 and p=1".
// See https://godoc.org/golang.org/x/crypto/scrypt#Key
key, err := scrypt.Key(password, salt, 1<<15, 8, 1, keySize)
if err != nil {
return nil, err
}
return key, nil
}
// As is typical in Rosetta, we'll be making the salt, like our nonces,
// deterministic on the user input. This fulfills all of the hardening
// purposes of a salt, without requiring a salt state to be kept around.
func deriveSalt(input []byte) cipher.Nonce {
// Keccak construction is used to do the heavy lifting again.
// This is not a keyed MAC, per se, though it looks similar.
// The purpose of the prefix bytes is not any critical security purpose;
// just a "why not" sort of shift of the space.
nonce := make([]byte, 24)
d := sha3.NewShake128()
d.Write([]byte{'r', 'o', 's', 'e', 't', 't', 'a'})
d.Write(input)
d.Read(nonce)
return nonce
}