| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Crypt::Mac::KMAC; |
|
2
|
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
91905
|
use strict; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
58
|
|
|
4
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
110
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.088_005'; |
|
6
|
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
7
|
use base qw(Crypt::Mac Exporter); |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
662
|
|
|
8
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( all => [qw( kmac kmac_hex kmac_b64 kmac_b64u )] ); |
|
9
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
|
10
|
|
|
|
|
|
|
our @EXPORT = qw(); |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
1; |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=pod |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Crypt::Mac::KMAC - Message authentication code KMAC (NIST SP 800-185) |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
### Functional interface: |
|
23
|
|
|
|
|
|
|
use Crypt::Mac::KMAC qw( kmac kmac_hex kmac_b64 kmac_b64u ); |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# KMAC128 / KMAC256 - fixed-length output committed in advance |
|
26
|
|
|
|
|
|
|
my $mac_raw = kmac('KMAC128', 32, $key, '', 'data buffer'); |
|
27
|
|
|
|
|
|
|
my $mac_hex = kmac_hex('KMAC256', 64, $key, $custom, 'data buffer'); |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# KMACXOF128 / KMACXOF256 - extendable-output variant |
|
30
|
|
|
|
|
|
|
my $bytes = kmac('KMACXOF128', 100, $key, '', 'data buffer'); |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
### OO interface: |
|
33
|
|
|
|
|
|
|
use Crypt::Mac::KMAC; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my $d = Crypt::Mac::KMAC->new('KMAC256', $key, $custom); |
|
36
|
|
|
|
|
|
|
$d->add('any data'); |
|
37
|
|
|
|
|
|
|
my $result_hex = $d->hexmac(64); # finalizes the object |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# XOF mode - same API, just a different variant |
|
40
|
|
|
|
|
|
|
my $d = Crypt::Mac::KMAC->new('KMACXOF128', $key); |
|
41
|
|
|
|
|
|
|
$d->add('any data'); |
|
42
|
|
|
|
|
|
|
my $result_b64 = $d->b64mac(100); |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
I |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
Provides an interface to KMAC, the keyed message authentication code based on |
|
49
|
|
|
|
|
|
|
cSHAKE (NIST SP 800-185 section4). Four variants are exposed: |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=over |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=item * C / C - fixed-output KMAC. The requested output |
|
54
|
|
|
|
|
|
|
length C is encoded into the input, so re-running KMAC with a different |
|
55
|
|
|
|
|
|
|
output length produces an unrelated MAC, even with identical key, customization, |
|
56
|
|
|
|
|
|
|
and message. |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item * C / C - extendable-output KMAC (KMACXOF in |
|
59
|
|
|
|
|
|
|
SP 800-185). The encoded length is set to C<0>, so any prefix of the squeezed |
|
60
|
|
|
|
|
|
|
output is a valid KMAC of the same key/customization/message; you can request |
|
61
|
|
|
|
|
|
|
arbitrarily many bytes. |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=back |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
The customization string C is optional and is used for domain separation. |
|
66
|
|
|
|
|
|
|
When unused it is encoded as an empty string. |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head1 EXPORT |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Nothing is exported by default. |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
You can export selected functions: |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
use Crypt::Mac::KMAC qw( kmac kmac_hex kmac_b64 kmac_b64u ); |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Or all of them at once: |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
use Crypt::Mac::KMAC ':all'; |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head2 kmac |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Joins all data arguments into a single string and returns its KMAC encoded as a |
|
85
|
|
|
|
|
|
|
binary string. |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
my $mac = kmac($variant, $size, $key, $cust, 'data buffer'); |
|
88
|
|
|
|
|
|
|
#or |
|
89
|
|
|
|
|
|
|
my $mac = kmac($variant, $size, $key, $cust, 'data', 'more data', 'even more'); |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# $variant .. [string] 'KMAC128', 'KMAC256', 'KMACXOF128' or 'KMACXOF256' |
|
92
|
|
|
|
|
|
|
# $size .... [integer] requested output length in bytes (>0) |
|
93
|
|
|
|
|
|
|
# $key ..... [binary string] secret key (any length, including empty) |
|
94
|
|
|
|
|
|
|
# $cust .... [binary string] customization string (may be empty); undef is treated as empty |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head2 kmac_hex |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a lowercase hexadecimal string. |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
my $mac_hex = kmac_hex($variant, $size, $key, $cust, 'data buffer'); |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head2 kmac_b64 |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a Base64 string. |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
my $mac_b64 = kmac_b64($variant, $size, $key, $cust, 'data buffer'); |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head2 kmac_b64u |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a Base64 URL-safe string |
|
111
|
|
|
|
|
|
|
(see RFC 4648 section 5). |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
my $mac_b64u = kmac_b64u($variant, $size, $key, $cust, 'data buffer'); |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head1 METHODS |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Unless noted otherwise, assume C<$d> is an existing MAC object created via |
|
118
|
|
|
|
|
|
|
C, for example: |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
my $d = Crypt::Mac::KMAC->new('KMAC256', $key, $cust); |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 new |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
my $d = Crypt::Mac::KMAC->new($variant, $key); |
|
125
|
|
|
|
|
|
|
#or |
|
126
|
|
|
|
|
|
|
my $d = Crypt::Mac::KMAC->new($variant, $key, $cust); |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# $variant .. [string] 'KMAC128', 'KMAC256', 'KMACXOF128' or 'KMACXOF256' |
|
129
|
|
|
|
|
|
|
# $key ..... [binary string] secret key (any length, including empty) |
|
130
|
|
|
|
|
|
|
# $cust .... [binary string] customization string (optional, defaults to empty) |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=head2 clone |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
$d->clone(); |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 add |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Appends data to the message. Returns the object itself (for chaining). |
|
139
|
|
|
|
|
|
|
Croaks if the object has already been finalized by C, C, |
|
140
|
|
|
|
|
|
|
C, or C. |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
$d->add('any data'); |
|
143
|
|
|
|
|
|
|
#or |
|
144
|
|
|
|
|
|
|
$d->add('any data', 'more data', 'even more data'); |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head2 addfile |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
Reads the file content and appends it to the message. Returns the object itself |
|
149
|
|
|
|
|
|
|
(for chaining). Croaks if the object has already been finalized. |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
$d->addfile('filename.dat'); |
|
152
|
|
|
|
|
|
|
#or |
|
153
|
|
|
|
|
|
|
my $filehandle = ...; # existing binary-mode filehandle |
|
154
|
|
|
|
|
|
|
$d->addfile($filehandle); |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 mac |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Returns the binary MAC (raw bytes) and finalizes the object. After the first |
|
159
|
|
|
|
|
|
|
call to C, C, C, or C, later calls to C, |
|
160
|
|
|
|
|
|
|
C, or any MAC getter croak. |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
my $result_raw = $d->mac($size); |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# $size .. [integer] requested output length in bytes (>0) |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
For C / C the requested length is committed via right_encode |
|
167
|
|
|
|
|
|
|
into the cSHAKE input as defined in SP 800-185 section4.3.1; for C / |
|
168
|
|
|
|
|
|
|
C the encoded length is C<0> and the same C<$size> bytes are |
|
169
|
|
|
|
|
|
|
squeezed from the XOF (section4.3.2). |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head2 hexmac |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a lowercase hexadecimal string. |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
my $result_hex = $d->hexmac($size); |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head2 b64mac |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a Base64 string with trailing |
|
180
|
|
|
|
|
|
|
C<=> padding. |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
my $result_b64 = $d->b64mac($size); |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=head2 b64umac |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Like L but returns the MAC encoded as a Base64 URL-safe string (no |
|
187
|
|
|
|
|
|
|
trailing C<=>). |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
my $result_b64url = $d->b64umac($size); |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=over |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=item * L |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=item * L - NIST SP 800-185 (KMAC, cSHAKE, TupleHash, ParallelHash) |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=back |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=cut |