Skip to content

Commit

Permalink
crypto: add a crypto.pbkdf2 module (vlang#22047)
Browse files Browse the repository at this point in the history
  • Loading branch information
sibkod authored Aug 15, 2024
1 parent 4bce71e commit eb314c9
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
58 changes: 58 additions & 0 deletions vlib/crypto/pbkdf2/pbkdf2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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 {
fun = sha256.sum256
block_size = sha256.block_size
size = sha256.size
}
sha512.Digest {
fun = sha512.sum512
block_size = sha512.block_size
size = sha512.size
}
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 << 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]
}
18 changes: 18 additions & 0 deletions vlib/crypto/pbkdf2/pbkdf2_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import crypto.sha512
import crypto.sha256
import crypto.pbkdf2

const data = 'test'
const password = '123456'

fn test_sha512() {
// vfmt off
assert pbkdf2.key(data.bytes(), password.bytes(), 1000, 64, sha512.new())! == [u8(149) 155 168 16 77 243 26 192 128 222 29 139 38 173 131 82 73 152 197 253 66 64 11 103 32 110 95 116 143 4 104 70 176 24 99 48 224 77 47 184 193 59 98 191 18 172 4 119 83 93 198 101 118 131 223 150 215 172 170 166 205 187 247 160]
// vfmt on
}

fn test_sha256() {
// vfmt off
assert pbkdf2.key(data.bytes(), password.bytes(), 1000, 32, sha256.new())! == [u8(110) 95 68 212 254 34 114 21 43 19 155 141 36 158 236 51 16 244 85 107 245 172 219 25 128 109 111 18 25 14 9 149]
// vfmt on
}

0 comments on commit eb314c9

Please sign in to comment.