From 34d0413e1bf9c8d5ccc42391da5c92d16c595f74 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Fri, 29 Sep 2017 00:26:25 -0700 Subject: [PATCH] scrypt: update recommended parameters for 2017 Previously we documented recommended parameters for scrypt from 2009, which was eight years ago. Update those parameters and also provide some guidance to users for configuring those settings in 2017. On my late 2015 Macbook Pro, the scrypt benchmark with N=1<<15, r=8, p=1 completes in 91 milliseconds. Add an Example with a salt. Fixes golang/go#22082. Change-Id: I23e3920db67583c9fce093768a32e67ab9c979f5 Reviewed-on: https://go-review.googlesource.com/67070 Reviewed-by: Adam Langley --- scrypt/example_test.go | 22 ++++++++++++++++++++++ scrypt/scrypt.go | 7 ++++--- scrypt/scrypt_test.go | 4 +++- 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 scrypt/example_test.go diff --git a/scrypt/example_test.go b/scrypt/example_test.go new file mode 100644 index 0000000000..b6a8ccbd22 --- /dev/null +++ b/scrypt/example_test.go @@ -0,0 +1,22 @@ +package scrypt_test + +import ( + "encoding/base64" + "fmt" + "log" + + "golang.org/x/crypto/scrypt" +) + +func Example() { + // DO NOT use this salt value; generate your own random salt. 8 bytes is + // a good length. + salt := []byte{0xc8, 0x28, 0xf2, 0x58, 0xa7, 0x6a, 0xad, 0x7b} + + dk, err := scrypt.Key([]byte("some password"), salt, 1<<15, 8, 1, 32) + if err != nil { + log.Fatal(err) + } + fmt.Println(base64.StdEncoding.EncodeToString(dk)) + // Output: lGnMz8io0AUkfzn6Pls1qX20Vs7PGN6sbYQ2TQgY12M= +} diff --git a/scrypt/scrypt.go b/scrypt/scrypt.go index 14375c5098..ff28aaef6f 100644 --- a/scrypt/scrypt.go +++ b/scrypt/scrypt.go @@ -220,9 +220,10 @@ func smix(b []byte, r, N int, v, xy []uint32) { // // dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32) // -// The recommended parameters for interactive logins as of 2009 are N=16384, -// r=8, p=1. They should be increased as memory latency and CPU parallelism -// increases. Remember to get a good random salt. +// The recommended parameters for interactive logins as of 2017 are N=32768, r=8 +// and p=1. The parameters N, r, and p should be increased as memory latency and +// CPU parallelism increases; consider setting N to the highest power of 2 you +// can derive within 100 milliseconds. Remember to get a good random salt. func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { if N <= 1 || N&(N-1) != 0 { return nil, errors.New("scrypt: N must be > 1 and a power of 2") diff --git a/scrypt/scrypt_test.go b/scrypt/scrypt_test.go index e096c3a31a..766ed8d905 100644 --- a/scrypt/scrypt_test.go +++ b/scrypt/scrypt_test.go @@ -153,8 +153,10 @@ func TestKey(t *testing.T) { } } +var sink []byte + func BenchmarkKey(b *testing.B) { for i := 0; i < b.N; i++ { - Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64) + sink, _ = Key([]byte("password"), []byte("salt"), 1<<15, 8, 1, 64) } }