kdf/pbkdf2.go
func DerivePBKDF2(password, salt []byte, iterationCount, keyBitLength int, h hash.Hash) []byte {

	prf := hmac.New(func() hash.Hash { return h }, password)
	hLen := prf.Size()
	dkLen := keyBitLength >> 3 //size of derived key in bytes

	l := int(math.Ceil(float64(dkLen) / float64(hLen))) // l = CEIL (dkLen / hLen)
	r := dkLen - (l-1)*hLen

	// 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
	if dkLen > MaxInt {
		panic(fmt.Sprintf("kdf.DerivePBKDF2: expects derived key size to be not more that (2^32-1) bits, but was requested %v bits.", keyBitLength))
	}

	dk := make([]byte, 0, dkLen)

	for i := 0; i < l; i++ {

		t := f(salt, iterationCount, i+1, prf) // T_l = F (P, S, c, l)

		if i == (l - 1) {
			t = t[:r]
		} // truncate last block to r bits

		dk = append(dk, t...) // DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
	}

	return dk
}
func DerivePBKDF2(password, salt []byte, iterationCount, keyBitLength int, h hash.Hash) []byte {

	prf := hmac.New(func() hash.Hash { return h }, password)
	hLen := prf.Size()
	dkLen := keyBitLength >> 3 //size of derived key in bytes

	l := int(math.Ceil(float64(dkLen) / float64(hLen))) // l = CEIL (dkLen / hLen)
	r := dkLen - (l-1)*hLen

	// 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
	if dkLen > MaxInt {
		panic(fmt.Sprintf("kdf.DerivePBKDF2: expects derived key size to be not more that (2^32-1) bits, but was requested %v bits.", keyBitLength))
	}

	dk := make([]byte, 0, dkLen)

	for i := 0; i < l; i++ {

		t := f(salt, iterationCount, i+1, prf) // T_l = F (P, S, c, l)

		if i == (l - 1) {
			t = t[:r]
		} // truncate last block to r bits

		dk = append(dk, t...) // DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
	}

	return dk
}
func DerivePBKDF2 ( password , salt [ ] byte , iterationCount , keyBitLength int , h hash . Hash ) [ ] byte { prf := hmac . New ( func ( ) hash . Hash { return h } , password ) hLen := prf . Size ( ) dkLen := keyBitLength >> 3 //size of derived key in bytes l := int ( math . Ceil ( float64 ( dkLen ) / float64 ( hLen ) ) ) // l = CEIL (dkLen / hLen) r := dkLen - ( l - 1 ) * hLen // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. if dkLen > MaxInt { panic ( fmt . Sprintf ( " " , keyBitLength ) ) } dk := make ( [ ] byte , 0 , dkLen ) for i := 0 ; i < l ; i ++ { t := f ( salt , iterationCount , i + 1 , prf ) // T_l = F (P, S, c, l) if i == ( l - 1 ) { t = t [ : r ] } // truncate last block to r bits dk = append ( dk , t ... ) // DK = T_1 || T_2 ||  ...  || T_l<0..r-1> } return dk }
// DerivePBKDF2 implements Password Based Key Derivation Function 2, RFC 2898. Derives key of keyBitLength size, given password, salt, iteration count and hash function
DerivePBKDF2 implements Password Based Key Derivation Function 2 RFC 2898 . Derives key of keyBitLength size given password salt iteration count and hash function