mirror of
https://github.com/GaloisInc/cryptol.git
synced 2024-12-18 13:31:50 +03:00
74 lines
2.8 KiB
Plaintext
74 lines
2.8 KiB
Plaintext
/*
|
|
* Copyright (c) 2013-2016 Galois, Inc.
|
|
* Distributed under the terms of the BSD3 license (see LICENSE file)
|
|
*/
|
|
module PBKDF2 where
|
|
|
|
import SHA256
|
|
import HMAC
|
|
|
|
// PBKDF2 specialized to HMAC_SHA256 to avoid monomorphic type issues.
|
|
pbkdf2 : {pwBytes, saltBytes, dkLenBits, len, C}
|
|
( 32 >= width (pwBytes*8), len == (dkLenBits + 255)/256
|
|
, len >= 1, 32 >= width len, fin saltBytes, fin dkLenBits, fin pwBytes
|
|
, 64 >= width (8 * (pwBytes + (4 + saltBytes)))
|
|
, 64 >= width (8 * (pwBytes + 32))
|
|
, C >= 1, fin C, 64 >= width (8*(pwBytes + (2 + saltBytes))), 16 >= width C
|
|
, 16 >= width len
|
|
// cryptol < 2.3 can't math!
|
|
, dkLenBits == 256 * len // Cryptol 2.3 doesn't understand 'take'?
|
|
, max 6 (width pwBytes) >= width pwBytes
|
|
, max 6 (width pwBytes) >= 6
|
|
, max 7 (width pwBytes) >= 7
|
|
, max 7 (width pwBytes) >= width pwBytes
|
|
, max (width pwBytes) 7 >= 7
|
|
, max (width pwBytes) 7 >= width pwBytes
|
|
, 64 >= width (8 * pwBytes)
|
|
, 64 >= width (8 * (68 + saltBytes))
|
|
, 32 >= width (4 + saltBytes)
|
|
)
|
|
=> [pwBytes][8] -> [saltBytes][8] -> [dkLenBits]
|
|
pbkdf2 P S = take `{dkLenBits} (join Ts)
|
|
where
|
|
Ts : [_][256]
|
|
Ts = [ inner `{C=C} P (split (hmacSHA256 P (S # split i))) | i <- [1..len] : [_][32] ]
|
|
|
|
inner : {pwBytes, C}
|
|
( fin pwBytes
|
|
, 64 >= width (8 * (pwBytes + 32))
|
|
, fin C, C >= 1, 16 >= width C
|
|
// Cryptol < 2.3 can't math
|
|
, 64 >= width (8 * pwBytes)
|
|
, max 7 (width pwBytes) >= width pwBytes
|
|
, max 7 (width pwBytes) >= 7
|
|
, max (width pwBytes) 7 >= width pwBytes
|
|
, max (width pwBytes) 7 >= 7
|
|
, max 6 (width pwBytes) >= width pwBytes
|
|
, max 6 (width pwBytes) >= 6
|
|
)
|
|
=> [pwBytes][8] -> [32][8] -> [256]
|
|
inner P U0 = (Ts @ 0).0 // XXX should be ! 0
|
|
where
|
|
// Ts : [_][([256],[32][8])]
|
|
Ts = [(join U0, U0)] # [ F P t u | _ <- [1..C] : [_][16] | (t,u) <- Ts ]
|
|
|
|
F : {pwBytes} (fin pwBytes
|
|
, 64 >= width (8*(32+pwBytes))
|
|
// cryptol < 2.3 can't math
|
|
, 64 >= width (8 * pwBytes)
|
|
, max 7 (width pwBytes) >= width pwBytes
|
|
, max 7 (width pwBytes) >= 7
|
|
, max (width pwBytes) 7 >= width pwBytes
|
|
, max (width pwBytes) 7 >= 7
|
|
, max 6 (width pwBytes) >= width pwBytes
|
|
, max 6 (width pwBytes) >= 6
|
|
) => [pwBytes][8] -> [256] -> [32][8] -> ([256],[32][8])
|
|
F P Tprev Uprev = (Tnext,Unext)
|
|
where
|
|
Unext = split (hmacSHA256 P Uprev)
|
|
Tnext = Tprev ^ join Unext
|
|
|
|
|
|
test1 : Bit
|
|
property test1 = pbkdf2 `{C=1,dkLenBits=64*8} "passwd" "salt" == 0x55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783
|