-
Notifications
You must be signed in to change notification settings - Fork 0
glk/mmcrypt
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
mmcrypt -- password-based key derivation function.
Interface supports arbitrary input parameters and arbitrary length
output:
- mmcrypt_absorb(data) -- input data, may be called arbitrary number of
times with arguments like salt, password, service tag, secret salt,
etc;
- mmcrypt_stretch(iter, m, s) -- key stretch procedure;
- mmcrypt_squeeze() => key -- produce cryptographic key based on
current state, may be called arbitrary number of times.
Two primitives are used: Duplex construction on top of 512-bit Keccak
(as in SHA-3) and Galois field multiplication.
Pseudo-code:
sm, s1, s2 - Duplex constructions. s.Duplexing is stateful operation.
MSB(A, N) -- get N most significant bits of A
LSB(A, N) -- get N least significant bits of A
LSB_WRAP(A, i) -- LSB(A, floor(log2(i))) + i - (2 ** floor(log2(i)))
mmcrypt_abosrb(data) --
sm.Duplexing(data)
mmcrypt_squeeze() --
return sm.Duplexing(NULL)
mmcrypt_stretch(iter, c, s) --
/* Create 64-bit big-endian array with 8 elements */
sm.Duplexing((be64){MMCRYPT_FRATE, iter, c, s, 0, 0, 0, 0})
for i 0 to iter - 1
mmcrypt_stretch'(c, s)
mmcrypt_stretch'(c, s) --
fcount = 0
s1.Duplexing(sm.Duplexing(NULL))
s2.Duplexing(sm.Duplexing(NULL))
/* Choose start positions k[i], should not be 0 */
for i in 0 to s - 1
k[i] = MSB(sm.Duplexing(NULL), c * 2) | 1;
/* Create T1 and T2 tables. */
/* Ti[[x]] := Ti[x / s][x % s] */
T1[[0]] = s1.Duplexing(NULL)
T2[[0]] = s2.Duplexing(NULL)
for i in 1 to 2^c * s - 1
j = LSB_WRAP(T2[[i - 1]], i)
T1[[i]] = s1.Duplexing(T2[[j]])
j = LSB_WRAP(T1[[i - 1]], i)
T2[[i]] = s2.Duplexing(T1[[j]])
/* Traverse all (T1[k1][i], T2[k2][i]) pairs. */
/* (T1[0], T2[0]) pair is skipped. */
k0 = k[0]
do
for i in 0 to s - 1
/* Multiplication in GF(2^(c * 2)) */
k[i] = k[i] (*) alpha
k1 = MSB(k[i], c)
k2 = LSB(k[i], c)
if MSB(T1[k1][i], c) != MSB(T2[k2][i], c)
feedback ^= T1[k1][i] ^ T2[k2][i]
/* Multiplication in GF(2^512) */
feedback = feedback (*) alpha
if MSB(feedback) == 1
tmp = (T1[k1][i] ^ T2[k2][i]) (*) alpha
T1[k1][(i + 1) % s] ^= tmp
T2[k2][(i + 1) % s] ^= tmp
swap T1[k1][(i + 1) % s], T2[k2][(i + 1) % s]
if ++fcount % MMCRYPT_FRATE == 0
feedback = sm.Duplexing(feedback)
while k[0] != k0
sm.Duplexing(feedback)
swap s1, s2
Notes:
Always perform the same non data dependent sequence of operations, but
start at position that depends on user provided data.
Make memory access pattern unpredictable for cache hierarchy in order to
achieve higher memory pressure.
Duplex construction is equivalent to sponge construction (see
Duplexing-sponge lemma in "Duplexing the sponge: single-pass
authenticated encryption and other applications") with padded inputs.
Sponge is SHA-3 in our case.
Keccak authors suggest Sponge(password || {0}n) with large n as a
password-based key derivation function (see "Cryptographic sponge
functions").
The problem may be reformulated as meet-in-the-middle attack:
Find A = {(i, j)} such as MSB(H1(i), c) = MSB(H2(j), c).
where H(i) requires i Keccak-f operations for known inputs. E.g. it
gives us 2^(c-1) operations on average for H(i) calculation.
About
mmcrypt -- password-based key derivation function
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published