Packages

A replacement for gleam_crypto that works on all targets.

Current section

Files

Jump to
munch src munch@internal@hmac.erl
Raw

src/munch@internal@hmac.erl

-module(munch@internal@hmac).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/munch/internal/hmac.gleam").
-export([new/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-file("src/munch/internal/hmac.gleam", 44).
?DOC(false).
-spec xor_each_byte(bitstring(), integer(), list(bitstring())) -> bitstring().
xor_each_byte(Bytes, Mask, Accumulator) ->
case Bytes of
<<Byte:8, Rest/bitstring>> ->
xor_each_byte(
Rest,
Mask,
[<<(munch@internal@bitwise:'xor'(Byte, Mask)):8>> | Accumulator]
);
_ ->
_pipe = Accumulator,
_pipe@1 = lists:reverse(_pipe),
gleam_stdlib:bit_array_concat(_pipe@1)
end.
-file("src/munch/internal/hmac.gleam", 36).
?DOC(false).
-spec masked_key_block(bitstring(), integer(), integer()) -> bitstring().
masked_key_block(Key, Mask, Block_size) ->
Zero_bits = (Block_size - erlang:byte_size(Key)) * 8,
Key_block = <<Key/bitstring, 0:(erlang:max(0, Zero_bits))>>,
xor_each_byte(Key_block, Mask, []).
-file("src/munch/internal/hmac.gleam", 10).
?DOC(false).
-spec new(fun(() -> munch@internal@hash:hash()), integer(), bitstring()) -> munch@internal@hash:hash().
new(Hash, Block_size, Key) ->
Key@1 = gleam_stdlib:bit_array_pad_to_bytes(Key),
Key@2 = case erlang:byte_size(Key@1) > Block_size of
true ->
_pipe = Hash(),
_pipe@1 = munch@internal@hash:update(_pipe, Key@1),
munch@internal@hash:finish(_pipe@1);
false ->
Key@1
end,
Inner = masked_key_block(Key@2, 16#36, Block_size),
Outer = masked_key_block(Key@2, 16#5C, Block_size),
State = begin
_pipe@2 = Hash(),
munch@internal@hash:update(_pipe@2, Inner)
end,
Finish = fun(State@1) ->
Inner_digest = munch@internal@hash:finish(State@1),
_pipe@3 = Hash(),
_pipe@4 = munch@internal@hash:update(_pipe@3, Outer),
_pipe@5 = munch@internal@hash:update(_pipe@4, Inner_digest),
munch@internal@hash:finish(_pipe@5)
end,
munch@internal@hash:from(State, fun munch@internal@hash:update/2, Finish).