mirror of
https://github.com/vlang/v.git
synced 2025-09-15 07:22:27 +03:00
67 lines
1.4 KiB
V
67 lines
1.4 KiB
V
// Based off: https://golang.org/x/crypto/pbkdf2
|
|
module pbkdf2
|
|
|
|
import crypto.hmac
|
|
import crypto.sha256
|
|
import crypto.sha512
|
|
import hash
|
|
|
|
// key derives a key from the password, salt and iteration count
|
|
// example pbkdf2.key('test'.bytes(), '123456'.bytes(), 1000, 64, sha512.new())
|
|
pub fn key(password []u8, salt []u8, count int, key_length int, h hash.Hash) ![]u8 {
|
|
mut fun := fn (b []u8) []u8 {
|
|
return []u8{}
|
|
}
|
|
mut block_size := 0
|
|
mut size := 0
|
|
match h {
|
|
sha256.Digest {
|
|
block_size = h.block_size()
|
|
size = h.size()
|
|
if size == sha256.size224 {
|
|
fun = sha256.sum224
|
|
} else {
|
|
fun = sha256.sum256
|
|
}
|
|
}
|
|
sha512.Digest {
|
|
block_size = h.block_size()
|
|
size = h.size()
|
|
if size == sha512.size384 {
|
|
fun = sha512.sum384
|
|
} else {
|
|
fun = sha512.sum512
|
|
}
|
|
}
|
|
else {
|
|
panic('Unsupported hash')
|
|
}
|
|
}
|
|
|
|
hash_length := size
|
|
block_count := (key_length + hash_length - 1) / hash_length
|
|
mut output := []u8{}
|
|
mut last := []u8{}
|
|
mut buf := []u8{len: 4}
|
|
for i := 1; i <= block_count; i++ {
|
|
last.clear()
|
|
last << salt
|
|
|
|
buf[0] = u8(i >> 24)
|
|
buf[1] = u8(i >> 16)
|
|
buf[2] = u8(i >> 8)
|
|
buf[3] = u8(i)
|
|
|
|
last << buf
|
|
mut xorsum := hmac.new(password, last, fun, block_size)
|
|
mut last_hash := xorsum.clone()
|
|
for j := 1; j < count; j++ {
|
|
last_hash = hmac.new(password, last_hash, fun, block_size)
|
|
for k in 0 .. xorsum.len {
|
|
xorsum[k] ^= last_hash[k]
|
|
}
|
|
}
|
|
output << xorsum
|
|
}
|
|
return output[..key_length]
|
|
}
|