.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "Crypt::Mac::KMAC 3" .TH Crypt::Mac::KMAC 3 2026-06-18 "perl v5.42.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Crypt::Mac::KMAC \- Message authentication code KMAC (NIST SP 800\-185) .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 2 \& ### Functional interface: \& use Crypt::Mac::KMAC qw( kmac kmac_hex kmac_b64 kmac_b64u ); \& \& # KMAC128 / KMAC256 \- fixed\-length output committed in advance \& my $mac_raw = kmac(\*(AqKMAC128\*(Aq, 32, $key, \*(Aq\*(Aq, \*(Aqdata buffer\*(Aq); \& my $mac_hex = kmac_hex(\*(AqKMAC256\*(Aq, 64, $key, $custom, \*(Aqdata buffer\*(Aq); \& \& # KMACXOF128 / KMACXOF256 \- extendable\-output variant \& my $bytes = kmac(\*(AqKMACXOF128\*(Aq, 100, $key, \*(Aq\*(Aq, \*(Aqdata buffer\*(Aq); \& \& ### OO interface: \& use Crypt::Mac::KMAC; \& \& my $d = Crypt::Mac::KMAC\->new(\*(AqKMAC256\*(Aq, $key, $custom); \& $d\->add(\*(Aqany data\*(Aq); \& my $result_hex = $d\->hexmac(64); # finalizes the object \& \& # XOF mode \- same API, just a different variant \& my $d = Crypt::Mac::KMAC\->new(\*(AqKMACXOF128\*(Aq, $key); \& $d\->add(\*(Aqany data\*(Aq); \& my $result_b64 = $d\->b64mac(100); .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" \&\fISince: CryptX\-0.090\fR .PP Provides an interface to KMAC, the keyed message authentication code based on cSHAKE (NIST SP 800\-185 section4). Four variants are exposed: .IP \(bu 4 \&\f(CW\*(C`KMAC128\*(C'\fR / \f(CW\*(C`KMAC256\*(C'\fR \- fixed\-output KMAC. The requested output length \f(CW\*(C`L\*(C'\fR is encoded into the input, so re\-running KMAC with a different output length produces an unrelated MAC, even with identical key, customization, and message. .IP \(bu 4 \&\f(CW\*(C`KMACXOF128\*(C'\fR / \f(CW\*(C`KMACXOF256\*(C'\fR \- extendable\-output KMAC (KMACXOF in SP 800\-185). The encoded length is set to \f(CW0\fR, so any prefix of the squeezed output is a valid KMAC of the same key/customization/message; you can request arbitrarily many bytes. .PP The customization string \f(CW\*(C`S\*(C'\fR is optional and is used for domain separation. When unused it is encoded as an empty string. .SH EXPORT .IX Header "EXPORT" Nothing is exported by default. .PP You can export selected functions: .PP .Vb 1 \& use Crypt::Mac::KMAC qw( kmac kmac_hex kmac_b64 kmac_b64u ); .Ve .PP Or all of them at once: .PP .Vb 1 \& use Crypt::Mac::KMAC \*(Aq:all\*(Aq; .Ve .SH FUNCTIONS .IX Header "FUNCTIONS" .SS kmac .IX Subsection "kmac" Joins all data arguments into a single string and returns its KMAC encoded as a binary string. .PP .Vb 3 \& my $mac = kmac($variant, $size, $key, $cust, \*(Aqdata buffer\*(Aq); \& #or \& my $mac = kmac($variant, $size, $key, $cust, \*(Aqdata\*(Aq, \*(Aqmore data\*(Aq, \*(Aqeven more\*(Aq); \& \& # $variant .. [string] \*(AqKMAC128\*(Aq, \*(AqKMAC256\*(Aq, \*(AqKMACXOF128\*(Aq or \*(AqKMACXOF256\*(Aq \& # $size .... [integer] requested output length in bytes (>0) \& # $key ..... [binary string] secret key (any length, including empty) \& # $cust .... [binary string] customization string (may be empty); undef is treated as empty .Ve .SS kmac_hex .IX Subsection "kmac_hex" Like "kmac" but returns the MAC encoded as a lowercase hexadecimal string. .PP .Vb 1 \& my $mac_hex = kmac_hex($variant, $size, $key, $cust, \*(Aqdata buffer\*(Aq); .Ve .SS kmac_b64 .IX Subsection "kmac_b64" Like "kmac" but returns the MAC encoded as a Base64 string. .PP .Vb 1 \& my $mac_b64 = kmac_b64($variant, $size, $key, $cust, \*(Aqdata buffer\*(Aq); .Ve .SS kmac_b64u .IX Subsection "kmac_b64u" Like "kmac" but returns the MAC encoded as a Base64 URL\-safe string (see RFC 4648 section 5). .PP .Vb 1 \& my $mac_b64u = kmac_b64u($variant, $size, $key, $cust, \*(Aqdata buffer\*(Aq); .Ve .SH METHODS .IX Header "METHODS" Unless noted otherwise, assume \f(CW$d\fR is an existing MAC object created via \&\f(CW\*(C`new\*(C'\fR, for example: .PP .Vb 1 \& my $d = Crypt::Mac::KMAC\->new(\*(AqKMAC256\*(Aq, $key, $cust); .Ve .SS new .IX Subsection "new" .Vb 3 \& my $d = Crypt::Mac::KMAC\->new($variant, $key); \& #or \& my $d = Crypt::Mac::KMAC\->new($variant, $key, $cust); \& \& # $variant .. [string] \*(AqKMAC128\*(Aq, \*(AqKMAC256\*(Aq, \*(AqKMACXOF128\*(Aq or \*(AqKMACXOF256\*(Aq \& # $key ..... [binary string] secret key (any length, including empty) \& # $cust .... [binary string] customization string (optional, defaults to empty) .Ve .SS clone .IX Subsection "clone" .Vb 1 \& $d\->clone(); .Ve .SS add .IX Subsection "add" Appends data to the message. Returns the object itself (for chaining). Croaks if the object has already been finalized by \f(CW\*(C`mac\*(C'\fR, \f(CW\*(C`hexmac\*(C'\fR, \&\f(CW\*(C`b64mac\*(C'\fR, or \f(CW\*(C`b64umac\*(C'\fR. .PP .Vb 3 \& $d\->add(\*(Aqany data\*(Aq); \& #or \& $d\->add(\*(Aqany data\*(Aq, \*(Aqmore data\*(Aq, \*(Aqeven more data\*(Aq); .Ve .SS addfile .IX Subsection "addfile" Reads the file content and appends it to the message. Returns the object itself (for chaining). Croaks if the object has already been finalized. .PP .Vb 4 \& $d\->addfile(\*(Aqfilename.dat\*(Aq); \& #or \& my $filehandle = ...; # existing binary\-mode filehandle \& $d\->addfile($filehandle); .Ve .SS mac .IX Subsection "mac" Returns the binary MAC (raw bytes) and finalizes the object. After the first call to \f(CW\*(C`mac\*(C'\fR, \f(CW\*(C`hexmac\*(C'\fR, \f(CW\*(C`b64mac\*(C'\fR, or \f(CW\*(C`b64umac\*(C'\fR, later calls to \f(CW\*(C`add\*(C'\fR, \&\f(CW\*(C`addfile\*(C'\fR, or any MAC getter croak. .PP .Vb 1 \& my $result_raw = $d\->mac($size); \& \& # $size .. [integer] requested output length in bytes (>0) .Ve .PP For \f(CW\*(C`KMAC128\*(C'\fR / \f(CW\*(C`KMAC256\*(C'\fR the requested length is committed via right_encode into the cSHAKE input as defined in SP 800\-185 section4.3.1; for \f(CW\*(C`KMACXOF128\*(C'\fR / \&\f(CW\*(C`KMACXOF256\*(C'\fR the encoded length is \f(CW0\fR and the same \f(CW$size\fR bytes are squeezed from the XOF (section4.3.2). .SS hexmac .IX Subsection "hexmac" Like "mac" but returns the MAC encoded as a lowercase hexadecimal string. .PP .Vb 1 \& my $result_hex = $d\->hexmac($size); .Ve .SS b64mac .IX Subsection "b64mac" Like "mac" but returns the MAC encoded as a Base64 string with trailing \&\f(CW\*(C`=\*(C'\fR padding. .PP .Vb 1 \& my $result_b64 = $d\->b64mac($size); .Ve .SS b64umac .IX Subsection "b64umac" Like "mac" but returns the MAC encoded as a Base64 URL\-safe string (no trailing \f(CW\*(C`=\*(C'\fR). .PP .Vb 1 \& my $result_b64url = $d\->b64umac($size); .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP \(bu 4 CryptX .IP \(bu 4 \- NIST SP 800\-185 (KMAC, cSHAKE, TupleHash, ParallelHash)