pass

Paddy 2014-11-11 Child:22ce15152c43

0:b394d1d58b85 Go to Latest

pass/pass.go

First commit. First untested, uncommented iteration of the library, based on feedback from Jan Lehnardt, who really _is_ the perfect person. We at least have a README, though. TODO: golint, go vet, tests, comments

History
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/pass.go	Tue Nov 11 19:26:25 2014 -0500
     1.3 @@ -0,0 +1,51 @@
     1.4 +package pass
     1.5 +
     1.6 +import (
     1.7 +	"crypto/rand"
     1.8 +	"crypto/subtle"
     1.9 +	"hash"
    1.10 +	"time"
    1.11 +
    1.12 +	"code.google.com/p/go.crypto/pbkdf2"
    1.13 +)
    1.14 +
    1.15 +func Create(h func() hash.Hash, iters int, passphrase []byte) (result, salt []byte, err error) {
    1.16 +	salt = make([]byte, 32)
    1.17 +	_, err = rand.Read(salt)
    1.18 +	if err == nil {
    1.19 +		return []byte{}, []byte{}, err
    1.20 +	}
    1.21 +	result = Check(h, iters, passphrase, salt)
    1.22 +	return result, salt, err
    1.23 +}
    1.24 +
    1.25 +func CalculateIterations(h func() hash.Hash) (int, error) {
    1.26 +	hashInstance := h()
    1.27 +	salt := make([]byte, 32)
    1.28 +	_, err := rand.Read(salt)
    1.29 +	if err != nil {
    1.30 +		return 0, err
    1.31 +	}
    1.32 +	iter := 2048
    1.33 +	var duration time.Duration
    1.34 +	for duration < time.Second {
    1.35 +		iter = iter * 2
    1.36 +		timeStart := time.Now()
    1.37 +		pbkdf2.Key([]byte("password1"), salt, iter, hashInstance.Size(), h)
    1.38 +		duration = time.Since(timeStart)
    1.39 +	}
    1.40 +	return iter, nil
    1.41 +}
    1.42 +
    1.43 +func Check(h func() hash.Hash, iters int, passphrase, salt []byte) []byte {
    1.44 +	hashInstance := h()
    1.45 +	return pbkdf2.Key(passphrase, salt, iters, hashInstance.Size(), h)
    1.46 +}
    1.47 +
    1.48 +func Compare(candidate, expectation []byte) bool {
    1.49 +	candidateConsistent := make([]byte, len(candidate))
    1.50 +	expectationConsistent := make([]byte, len(candidate))
    1.51 +	subtle.ConstantTimeCopy(1, candidateConsistent, candidate)
    1.52 +	subtle.ConstantTimeCopy(1, expectationConsistent, expectation)
    1.53 +	return subtle.ConstantTimeCompare(candidateConsistent, expectationConsistent) == 1
    1.54 +}