class SHA3::KMAC
KMAC (Keccak Message Authentication Code) is a MAC algorithm based on the Keccak permutation. It is defined in NIST SP800-185 and provides both fixed-length and XOF (arbitrary-length) output modes.
Public Class Methods
Source
static VALUE rb_sha3_kmac_self_digest(int argc, VALUE *argv, VALUE klass) {
VALUE algorithm, data, output_length, key, customization;
rb_scan_args(argc, argv, "41", &algorithm, &data, &output_length, &key, &customization);
Check_Type(output_length, T_FIXNUM);
if (!NIL_P(output_length) && output_length <= INT2FIX(0)) {
rb_raise(rb_eArgError, "class method digest does not support XOF mode");
}
VALUE kmac = rb_funcall(klass, rb_intern("new"), 4, algorithm, output_length, key, customization);
return rb_funcall(kmac, rb_intern("digest"), 1, data);
}
One-shot operation to return the binary KMAC digest without explicitly creating an instance.
algorithm-
The
KMACalgorithm to use (as a Symbol) - :kmac_128 or :kmac_256 data-
The data to digest
output_length-
The length of the output in bytes
key-
The key to use for the
KMAC customization-
optional The customization string to use
example¶ ↑
SHA3::KMAC.digest(:kmac_128, "data", 32, "key") SHA3::KMAC.digest(:kmac_128, "data", 32, "key", "customization")
Source
static VALUE rb_sha3_kmac_self_hexdigest(int argc, VALUE *argv, VALUE klass) {
VALUE algorithm, data, output_length, key, customization;
rb_scan_args(argc, argv, "41", &algorithm, &data, &output_length, &key, &customization);
Check_Type(output_length, T_FIXNUM);
if (!NIL_P(output_length) && output_length <= INT2FIX(0)) {
rb_raise(rb_eArgError, "class method hexdigest does not support XOF mode");
}
VALUE kmac = rb_funcall(klass, rb_intern("new"), 4, algorithm, output_length, key, customization);
return rb_funcall(kmac, rb_intern("hexdigest"), 1, data);
}
One-shot operation to return the hexadecimal KMAC digest without explicitly creating an instance.
algorithm-
The
KMACalgorithm to use (as a Symbol) - :kmac_128 or :kmac_256 data-
The data to digest
output_length-
The length of the output in bytes
key-
The key to use for the
KMAC customization-
optional The customization string to use
example¶ ↑
SHA3::KMAC.hexdigest(:kmac_128, "data", 32, "key") SHA3::KMAC.hexdigest(:kmac_128, "data", 32, "key", "customization")
Source
static VALUE rb_sha3_kmac_init(int argc, VALUE *argv, VALUE self) {
VALUE algorithm, output_length, key, customization;
rb_scan_args(argc, argv, "31", &algorithm, &output_length, &key, &customization);
// Check and convert arguments
if (NIL_P(algorithm)) {
rb_raise(rb_eArgError, "missing keyword: algorithm");
}
Check_Type(algorithm, T_SYMBOL);
if (NIL_P(output_length)) {
rb_raise(rb_eArgError, "missing keyword: output_length");
}
Check_Type(output_length, T_FIXNUM);
if (NIL_P(key)) {
rb_raise(rb_eArgError, "missing keyword: key");
}
StringValue(key);
if (!NIL_P(customization)) {
StringValue(customization);
} else {
customization = rb_str_new2("");
}
sha3_kmac_context_t *context;
TypedData_Get_Struct(self, sha3_kmac_context_t, &sha3_kmac_data_type_t, context);
// Store the output length in bits
context->base.output_length = NUM2ULONG(output_length) * 8;
context->base.error_class = _sha3_kmac_error_class;
// Find the appropriate function table based on the algorithm
ID sym_id = SYM2ID(algorithm);
sp800_185_algorithm_t alg_type;
if (sym_id == _kmac_128_id) {
alg_type = SP800_185_KMAC_128;
} else if (sym_id == _kmac_256_id) {
alg_type = SP800_185_KMAC_256;
} else {
rb_raise(rb_eArgError, "invalid algorithm: %s", rb_id2name(sym_id));
}
context->base.functions = sp800_185_get_algorithm(alg_type);
if (!context->base.functions) {
rb_raise(_sha3_kmac_error_class, "algorithm not available: %s", rb_id2name(sym_id));
}
// Initialize using the safe accessor function
size_t key_len = RSTRING_LEN(key) * 8;
size_t customization_len = RSTRING_LEN(customization) * 8;
int result = sp800_185_init_kmac(context->base.functions, context->base.state,
(const BitSequence *)RSTRING_PTR(key), key_len, context->base.output_length,
(const BitSequence *)RSTRING_PTR(customization), customization_len);
if (result != 0) {
rb_raise(_sha3_kmac_error_class, "failed to initialize %s", context->base.functions->name);
}
return self;
}
Creates a new KMAC object.
algorithm-
The
KMACalgorithm to use (as a Symbol). Valid algorithms are:-
:kmac_128
-
:kmac_256
-
output_length-
The length of the output in bytes. Set to 0 for an arbitrarily-long output using “squeeze” (XOF) methods.
key-
The key to use for the
KMAC. customization-
optional The customization string to use.
example¶ ↑
SHA3::KMAC.new(:kmac_128, 32, "key") SHA3::KMAC.new(:kmac_256, 64, "key", "customization") SHA3::KMAC.new(:kmac_128, 0, "key", "customization")
Public Instance Methods
Source
static VALUE rb_sha3_kmac_digest(int argc, VALUE *argv, VALUE self) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
VALUE data = argc > 0 ? argv[0] : Qnil;
return sp800_185_digest(context, data);
}
Returns the binary representation of the KMAC. This method creates a copy of the current instance so that the original state is preserved for future updates.
data-
optional Update state with additional data before returning
KMAC.
example¶ ↑
kmac.digest kmac.digest('final chunk')
Source
static VALUE rb_sha3_kmac_hex_squeeze(VALUE self, VALUE length) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
return sp800_185_hex_squeeze(context, length);
}
Returns the squeezed output as a hexadecimal string. This method creates a copy of the current instance so that the original state is preserved for future updates.
note¶ ↑
The KMAC instance must be initialized with 0 output length before calling this method.
example¶ ↑
kmac.hex_squeeze(128)
Source
static VALUE rb_sha3_kmac_hexdigest(int argc, VALUE *argv, VALUE self) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
VALUE data = argc > 0 ? argv[0] : Qnil;
return sp800_185_hexdigest(context, data);
}
Returns the hexadecimal representation of the KMAC. This method creates a copy of the current instance so that the original state is preserved for future updates.
data-
optional Update state with additional data before returning
KMAC.
example¶ ↑
kmac.hexdigest kmac.hexdigest('final chunk')
Source
static VALUE rb_sha3_kmac_copy(VALUE self, VALUE other) {
sha3_kmac_context_t *context, *other_context;
rb_check_frozen(self);
if (self == other) {
return self;
}
if (!rb_obj_is_kind_of(other, _sha3_kmac_class)) {
rb_raise(rb_eTypeError, "wrong argument (%s)! (expected %s)", rb_obj_classname(other),
rb_class2name(_sha3_kmac_class));
}
TypedData_Get_Struct(other, sha3_kmac_context_t, &sha3_kmac_data_type_t, other_context);
TypedData_Get_Struct(self, sha3_kmac_context_t, &sha3_kmac_data_type_t, context);
// Copy the base context attributes
context->base.functions = other_context->base.functions;
context->base.output_length = other_context->base.output_length;
// Copy the algorithm-specific state
memcpy(context->base.state, other_context->base.state, context->base.functions->state_size);
return self;
}
Creates a copy of the KMAC instance.
other-
The
KMACto copy the state from.
example¶ ↑
new_kmac = kmac.dup
Source
Source
static VALUE rb_sha3_kmac_squeeze(VALUE self, VALUE length) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
return sp800_185_squeeze(context, length);
}
Returns the squeezed output as a binary string. This method creates a copy of the current instance so that the original state is preserved for future updates.
note¶ ↑
The KMAC instance must be initialized with 0 output length before calling this method.
example¶ ↑
kmac.squeeze(128)
Source
static VALUE rb_sha3_kmac_update(VALUE self, VALUE data) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
sp800_185_update(context, data);
return self;
}
Updates the KMAC with the given string.
string-
The string to update the
KMACwith.
example¶ ↑
kmac.update("more data") kmac << "more data" # alias for update
Private Instance Methods
Source
static VALUE rb_sha3_kmac_finish(int argc, VALUE *argv, VALUE self) {
sp800_185_context_t *context;
get_kmac_context(self, &context);
VALUE output = argc > 0 ? argv[0] : Qnil;
return sp800_185_finish(context, output);
}
Returns the final KMAC as a binary string.
message-
optional Output buffer to receive the final
KMACvalue.
example¶ ↑
kmac.finish