class SHA3::CSHAKE
CSHAKE
(Customizable SHAKE) is a family of functions that allow for domain separation and customization of the output. It is based on the cSHAKE algorithm defined in NIST SP800-185.
Public Class Methods
Source
static VALUE rb_sha3_cshake_init(int argc, VALUE *argv, VALUE self) { VALUE algorithm, length, keywords; rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS, argc, argv, "2:", &algorithm, &length, &keywords); if (NIL_P(algorithm)) { rb_raise(rb_eArgError, "missing keyword: algorithm"); } Check_Type(algorithm, T_SYMBOL); if (NIL_P(length)) { rb_raise(rb_eArgError, "missing keyword: length"); } Check_Type(length, T_FIXNUM); if (NUM2INT(length) < 0) { rb_raise(rb_eArgError, "output length must be non-negative"); } ID table[] = { rb_intern("name"), rb_intern("customization"), }; VALUE values[3]; rb_get_kwargs(keywords, table, 0, 3, values); VALUE name_str = values[0] == Qundef ? rb_str_new2("") : values[0]; StringValue(name_str); VALUE customization = values[1] == Qundef ? rb_str_new2("") : values[1]; StringValue(customization); sha3_cshake_context_t *context; TypedData_Get_Struct(self, sha3_cshake_context_t, &sha3_cshake_data_type, context); // Store the output length in bits context->base.output_length = NUM2INT(length) * 8; context->base.error_class = _sha3_cshake_error_class; // Find the appropriate function table based on the algorithm if (algorithm == ID2SYM(_cshake_128_id)) { context->base.functions = &sp800_185_functions[SP800_185_CSHAKE_128]; } else if (algorithm == ID2SYM(_cshake_256_id)) { context->base.functions = &sp800_185_functions[SP800_185_CSHAKE_256]; } else { rb_raise(rb_eArgError, "invalid algorithm: %s", rb_id2name(SYM2ID(algorithm))); } // Initialize the state using the function table int result = context->base.functions->cshake.init( context->base.state, context->base.output_length, (BitSequence *)RSTRING_PTR(name_str), RSTRING_LEN(name_str) * 8, (BitSequence *)RSTRING_PTR(customization), RSTRING_LEN(customization) * 8); if (result != 0) { rb_raise(_sha3_cshake_error_class, "failed to initialize %s algorithm", context->base.functions->name); } return self; }
Initializes a new CSHAKE
instance with the specified algorithm and output length.
algorithm
-
The
CSHAKE
algorithm to use (as a Symbol) - :cshake_128 or :cshake_256 output_length
-
The length of the output in bytes. Set to 0 for an arbitrarily-long output using “squeeze” (XOF) methods.
name
-
optional The name string to use for domain separation
customization
-
optional The customization string to use
example¶ ↑
# Initialize instance for fix-ed-length operation cshake = SHA3::CSHAKE.new(:cshake_128, 32, name: 'my-app') cshake << 'data...' cshake.hexdigest # Initialize instance for XOF operation (arbitrary-long output) cshake = SHA3::CSHAKE.new(:cshake_256, 0, customization: 'Email Signature') cshask.update('data...') cshake.squeeze(64)
Public Instance Methods
Source
static VALUE rb_sha3_cshake_digest(int argc, VALUE *argv, VALUE self) { sp800_185_context_t *context; get_cshake_context(self, &context); VALUE data = argc > 0 ? argv[0] : Qnil; return sp800_185_digest(context, data); }
Returns the digest of the CSHAKE
instance.
data
-
optional Additional data to include in the digest.
example¶ ↑
cshake.digest cshake.digest("final chunk")
Source
static VALUE rb_sha3_cshake_hex_squeeze(VALUE self, VALUE length) { sp800_185_context_t *context; get_cshake_context(self, &context); return sp800_185_hex_squeeze(context, length); }
Returns the hexadecimal CSHAKE
digest with the specified length.
length
-
The length of the output in bytes.
example¶ ↑
cshake.hex_squeeze(32)
Source
static VALUE rb_sha3_cshake_hexdigest(int argc, VALUE *argv, VALUE self) { sp800_185_context_t *context; get_cshake_context(self, &context); VALUE data = argc > 0 ? argv[0] : Qnil; return sp800_185_hexdigest(context, data); }
Returns the hexadecimal digest of the CSHAKE
instance.
data
-
optional Additional data to include in the digest.
example¶ ↑
cshake.hexdigest cshake.hexdigest("final chunk")
Source
static VALUE rb_sha3_cshake_copy(VALUE self, VALUE other) { sha3_cshake_context_t *context, *other_context; rb_check_frozen(self); if (self == other) { return self; } if (!rb_obj_is_kind_of(other, _sha3_cshake_class)) { rb_raise(rb_eTypeError, "wrong argument (%s)! (expected %s)", rb_obj_classname(other), rb_class2name(_sha3_cshake_class)); } TypedData_Get_Struct(other, sha3_cshake_context_t, &sha3_cshake_data_type, other_context); TypedData_Get_Struct(self, sha3_cshake_context_t, &sha3_cshake_data_type, 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 CSHAKE
instance.
other
-
The
CSHAKE
instance to copy.
example¶ ↑
cshake2 = cshake.dup
Source
static VALUE rb_sha3_cshake_name(VALUE self) { sp800_185_context_t *context; get_cshake_context(self, &context); return rb_str_new2(sp800_185_name(context)); }
Returns the name of the CSHAKE
instance.
Source
Source
static VALUE rb_sha3_cshake_update(VALUE self, VALUE data) { sp800_185_context_t *context; get_cshake_context(self, &context); sp800_185_update(context, data); return self; }
Updates the CSHAKE
instance with the provided string.
string
-
The string to update the
CSHAKE
with.
example¶ ↑
cshake.update("more data") cshake << "more data" # alias for update
Private Instance Methods
Source
static VALUE rb_sha3_cshake_finish(int argc, VALUE *argv, VALUE self) { sp800_185_context_t *context; get_cshake_context(self, &context); VALUE output = argc > 0 ? argv[0] : Qnil; return sp800_185_finish(context, output); }
Returns the final CSHAKE
digest as a binary string.
message
-
optional Output buffer to receive the final
CSHAKE
value.
example¶ ↑
cshake.finish