Module: Digest

Defined in:
ext/digest/digest.c,
ext/digest/digest.c,
ext/digest/lib/digest.rb,
ext/digest/md5/md5init.c,
ext/digest/sha1/sha1init.c,
ext/digest/sha2/sha2init.c,
ext/digest/sha2/lib/sha2.rb,
ext/digest/rmd160/rmd160init.c,
ext/digest/lib/digest/version.rb,
ext/digest/bubblebabble/bubblebabble.c

Overview

This module provides a framework for message digest libraries.

You may want to look at OpenSSL::Digest as it supports more algorithms.

A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as digest. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.

Examples

require 'digest'

# Compute a complete digest
Digest::SHA256.digest 'message'       #=> "\xABS\n\x13\xE4Y..."

sha256 = Digest::SHA256.new
sha256.digest 'message'               #=> "\xABS\n\x13\xE4Y..."

# Other encoding formats
Digest::SHA256.hexdigest 'message'    #=> "ab530a13e459..."
Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."

# Compute digest by chunks
md5 = Digest::MD5.new
md5.update 'message1'
md5 << 'message2'                     # << is an alias for update

md5.hexdigest                         #=> "94af09c09bb9..."

# Compute digest for a file
sha256 = Digest::SHA256.file 'testfile'
sha256.hexdigest

Additionally digests can be encoded in “bubble babble” format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.

require 'digest/bubblebabble'

Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."

See the bubble babble specification at web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.

Digest algorithms

Different digest algorithms (or hash functions) are available:

MD5

See RFC 1321 The MD5 Message-Digest Algorithm

RIPEMD-160

As Digest::RMD160. See homes.esat.kuleuven.be/~bosselae/ripemd160.html.

SHA1

See FIPS 180 Secure Hash Standard.

SHA2 family

See FIPS 180 Secure Hash Standard which defines the following algorithms:

  • SHA512

  • SHA384

  • SHA256

The latest versions of the FIPS publications can be found here: csrc.nist.gov/publications/PubsFIPS.html.

Defined Under Namespace

Modules: Instance Classes: Base, Class, DigestError, MD5, RMD160, SHA1, SHA2, SHA256, SHA384, SHA512

Constant Summary collapse

REQUIRE_MUTEX =

A mutex for Digest().

Thread::Mutex.new
VERSION =
"3.1.1"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.bubblebabble(str) ⇒ Object

call-seq:

Digest.bubblebabble(string) -> bubblebabble_string

Returns a BubbleBabble encoded version of a given string.



88
89
90
91
92
# File 'ext/digest/bubblebabble/bubblebabble.c', line 88

static VALUE
rb_digest_s_bubblebabble(VALUE klass, VALUE str)
{
    return bubblebabble_str_new(str);
}

.const_missing(name) ⇒ Object

:nodoc:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'ext/digest/lib/digest.rb', line 22

def self.const_missing(name) # :nodoc:
  case name
  when :SHA256, :SHA384, :SHA512
    lib = 'digest/sha2'
  else
    lib = File.join('digest', name.to_s.downcase)
  end

  begin
    require lib
  rescue LoadError
    raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1)
  end
  unless Digest.const_defined?(name)
    raise NameError, "uninitialized constant Digest::#{name}", caller(1)
  end
  Digest.const_get(name)
end

.hexencode(string) ⇒ Object

Generates a hex-encoded version of a given string.



138
139
140
141
142
# File 'ext/digest/digest.c', line 138

static VALUE
rb_digest_s_hexencode(VALUE klass, VALUE str)
{
    return hexencode_str_new(str);
}

Instance Method Details

#block_lengthInteger

Returns the block length of the digest algorithm, i.e. the length in bytes of an individual block. Most modern algorithms partition a message to be digested into a sequence of fix-sized blocks that are processed consecutively.

Example

digest = OpenSSL::Digest.new('SHA1')
puts digest.block_length # => 64

Returns:



300
301
302
303
304
305
306
307
308
# File 'ext/openssl/ossl_digest.c', line 300

static VALUE
ossl_digest_block_length(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_block_size(ctx));
}

#digest_lengthInteger

Returns the output size of the digest, i.e. the length in bytes of the final message digest result.

Example

digest = OpenSSL::Digest.new('SHA1')
puts digest.digest_length # => 20

Returns:



277
278
279
280
281
282
283
284
285
# File 'ext/openssl/ossl_digest.c', line 277

static VALUE
ossl_digest_size(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_size(ctx));
}

#new(string[, data]) ⇒ Digest

Creates a Digest instance based on string, which is either the ln (long name) or sn (short name) of a supported digest algorithm.

If data (a String) is given, it is used as the initial input to the Digest instance, i.e.

digest = OpenSSL::Digest.new('sha256', 'digestdata')

is equivalent to

digest = OpenSSL::Digest.new('sha256')
digest.update('digestdata')

Returns:



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'ext/openssl/ossl_digest.c', line 118

static VALUE
ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_MD_CTX *ctx;
    const EVP_MD *md;
    VALUE type, data;

    rb_scan_args(argc, argv, "11", &type, &data);
    md = ossl_evp_get_digestbyname(type);
    if (!NIL_P(data)) StringValue(data);

    TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx);
    if (!ctx) {
	RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new();
	if (!ctx)
	    ossl_raise(eDigestError, "EVP_MD_CTX_new");
    }

    if (!EVP_DigestInit_ex(ctx, md, NULL))
	ossl_raise(eDigestError, "Digest initialization failed");

    if (!NIL_P(data)) return ossl_digest_update(self, data);
    return self;
}

#initialize_copy(other) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'ext/openssl/ossl_digest.c', line 143

static VALUE
ossl_digest_copy(VALUE self, VALUE other)
{
    EVP_MD_CTX *ctx1, *ctx2;

    rb_check_frozen(self);
    if (self == other) return self;

    TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1);
    if (!ctx1) {
	RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new();
	if (!ctx1)
	    ossl_raise(eDigestError, "EVP_MD_CTX_new");
    }
    GetDigest(other, ctx2);

    if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
	ossl_raise(eDigestError, NULL);
    }
    return self;
}

#nameString

Returns the sn of this Digest algorithm.

Example

digest = OpenSSL::Digest.new('SHA512')
puts digest.name # => SHA512

Returns:



255
256
257
258
259
260
261
262
263
# File 'ext/openssl/ossl_digest.c', line 255

static VALUE
ossl_digest_name(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx)));
}

#resetself

Resets the Digest in the sense that any Digest#update that has been performed is abandoned and the Digest is set to its initial state again.

Returns:

  • (self)


173
174
175
176
177
178
179
180
181
182
183
184
# File 'ext/openssl/ossl_digest.c', line 173

static VALUE
ossl_digest_reset(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) {
	ossl_raise(eDigestError, "Digest initialization failed.");
    }

    return self;
}

#update(string) ⇒ aString Also known as: <<

Not every message digest can be computed in one single pass. If a message digest is to be computed from several subsequent sources, then each may be passed individually to the Digest instance.

Example

digest = OpenSSL::Digest.new('SHA256')
digest.update('First input')
digest << 'Second input' # equivalent to digest.update('Second input')
result = digest.digest

Returns:

  • (aString)


201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'ext/openssl/ossl_digest.c', line 201

VALUE
ossl_digest_update(VALUE self, VALUE data)
{
    EVP_MD_CTX *ctx;

    StringValue(data);
    GetDigest(self, ctx);

    if (!EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)))
	ossl_raise(eDigestError, "EVP_DigestUpdate");

    return self;
}