Skip to content

use the crypto library native call pbkdf2_hmac if available#110

Merged
prefiks merged 3 commits intoprocessone:masterfrom
fdie:pbkdf2
Mar 19, 2026
Merged

use the crypto library native call pbkdf2_hmac if available#110
prefiks merged 3 commits intoprocessone:masterfrom
fdie:pbkdf2

Conversation

@fdie
Copy link
Contributor

@fdie fdie commented Mar 19, 2026

The crypto library since OTP 24.2 contains a pbkdf2_hmac/5 method.
The significant performance benefit of this nif (see the execution sample below) on server side may be used to increase the number of iterations as requested by @tmolitor-stud-tu for good reasons.

Sample parameters

Algo = sha512.
Pass = <<"c477272edab242bba3fec995fa68f2c1">>.
Salt = <<20,80,86,171,183,106,121,6,234,82,4,108,242,162,157,16>>.
Iterations = 10000.

scram:hi/5 legacy algorithm

Cost(fun() -> scram:hi_legacy(Algo, Pass, Salt, Iterations) end).
[{reductions,161906},
 {duration,{t,0.038362},{sec,0},{millisec,38},{microsec,362}},
 {result,<<26,229,188,159,43,102,5,255,38,178,137,9,180,
           164,53,121,58,187,17,145,101,101,161,109,214,
           67,158,16,148,102,230,4,240,12,183,6,66,107,
           175,157,6,156,21,221,170,11,137,67,35,36,211,
           53,214,202,144,204,93,16,30,230,7,152,72,238>>}]

scram:hi/5 algorithm based on the native call pbkdf2_hmac/5

Cost(fun() -> scram:hi(Algo, Pass, Salt, Iterations) end).
[{reductions,25753},
 {duration,{t,0.006241},{sec,0},{millisec,6},{microsec,241}},
 {result,<<26,229,188,159,43,102,5,255,38,178,137,9,180,
           164,53,121,58,187,17,145,101,101,161,109,214,
           67,158,16,148,102,230,4,240,12,183,6,66,107,
           175,157,6,156,21,221,170,11,137,67,35,36,211,
           53,214,202,144,204,93,16,30,230,7,152,72,238>>}]

Improvements

~5 times less reductions
~6 times faster

Given the cost measure function

Cost = fun(F) ->
    {reductions, Red0} = process_info(self(), reductions),
    {MS0, Res} = timer:tc(fun() -> F() end),
    {reductions, Red} = process_info(self(), reductions),
    Sec = MS0 div 1000000,
    MS = (MS0 - 1000000 * Sec),
    MilliSec = MS div 1000,
    [
        {reductions, Red - Red0}, 
        {duration, 
            {t, MS0 / 1000000.0}, 
            {sec, Sec}, 
            {millisec, MS div 1000}, 
            {microsec, MS - 1000 * MilliSec}
        }, 
        {result, Res}
     ]
end.

Copy link
Member

@prefiks prefiks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except that one thing, rest looks ok

rebar.config Outdated
{erl_opts, [debug_info, {src_dirs, ["asn1", "src"]},
nowarn_export_all,
{platform_define, "^(R|1|2[012])", 'USE_OLD_CRYPTO_HMAC'},
{platform_define, "^(R|1|2[0123])", 'NO_PBKDF2_HMAC'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change that to "^(R|1|2[0123]|24.[01])", looks like this was added in 24.2

@fdie
Copy link
Contributor Author

fdie commented Mar 19, 2026

You are right, OTP 24.0 and 24.1 should be discarded, thanks

@prefiks prefiks merged commit 595b476 into processone:master Mar 19, 2026
5 of 6 checks passed
@prefiks
Copy link
Member

prefiks commented Mar 19, 2026

Merged, thank you for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants