lib/stribog/create_hash.rb in stribog-0.1.2 vs lib/stribog/create_hash.rb in stribog-0.1.3
- old
+ new
@@ -1,24 +1,49 @@
-require 'byebug'
module Stribog
- # Hash function
+ # CreateHash
#
+ # Class, which creates digests.
# @author WildDima
class CreateHash
- attr_reader :binary_vector, :message_adapter, :message, :digest_length, :message_vector
+ # Original message
+ #
+ # @api public
+ # @example
+ # hash.message
+ # @return [String] contains original message
+ attr_reader :message
+ # Length of digest. Should be equal to 256 or 512.
+ #
+ # @api public
+ # @example
+ # digest.digest_length
+ # @return [Fixnum] binary representation of digest
+ attr_reader :digest_length
+
+ # Contain message as instance of BinaryVector
+ #
+ # @api public
+ # @example
+ # digest.message_vector
+ # @return [BinaryVector] binary representation of message
+ attr_reader :message_vector
+
HASH_LENGTH = 512
- def initialize(message, binary_vector: BinaryVector)
- @binary_vector = binary_vector
- @message = binary_vector.from_hex(message)
- @n = binary_vector_field_by
- @sum = binary_vector_field_by
+ def initialize(message)
+ @message = message
end
+ # Create digest of {#message}. Default equal to 512.
+ #
+ # @example
+ # Stribog::CreateHash.new('ruby').call(256)
+ # Stribog::CreateHash.new('ruby').call(512)
+ # @author WildDima
def call(digest_length = HASH_LENGTH)
- create_hash_params!(digest_length: digest_length)
+ prepare_hash_params!(digest_length: digest_length)
return_hash(
final_compression(
core_hashing(
compact_message(
@@ -32,16 +57,20 @@
)
end
private
- def create_hash_params!(digest_length:)
+ # Create instance vars for hashing
+ def prepare_hash_params!(digest_length:)
+ @n = binary_vector_field_by
+ @sum = binary_vector_field_by
@digest_length = digest_length
@hash_vector = create_hash_vector
- @message_vector = message.dup
+ @message_vector = binary_vector.from_hex(message)
end
+ # Create hash_vector for hashing
def create_hash_vector
case digest_length
when 512
binary_vector_field_by(size: 512)
when 256
@@ -50,13 +79,14 @@
raise ArgumentError,
"digest length must be equal to 256 or 512, not #{digest_length}"
end
end
+ # Method, which slices longer messages, and hashings them by parts.
def compact_message(sum:, n:, message_vector:, hash_vector:, message_head: nil)
current_vector = message_head || message_vector
- if message_vector.size < HASH_LENGTH || !message_head.nil? && message_head.size < HASH_LENGTH
+ if current_vector.size < HASH_LENGTH
return { sum: sum, n: n, message_vector: current_vector,
hash_vector: hash_vector }
end
compact_message(
@@ -67,18 +97,21 @@
hash_vector: hash_vector),
message_head: slice_message_head(current_vector)
)
end
+ # Method, which slices head of message
def slice_message_head(message_vector)
binary_vector_from_array(message_vector.vector[0...-HASH_LENGTH])
end
+ # Method, which slices head of tail
def slice_message_tail(message_vector)
binary_vector_from_array(message_vector.vector[-HASH_LENGTH..-1])
end
+ # Method, which implements main hashing
def core_hashing(sum:, n:, message_vector:, hash_vector:)
new_sum = addition_in_ring_to_binary(sum.to_dec,
message_vector
.addition_bit_padding(size: HASH_LENGTH)
.to_dec)
@@ -90,42 +123,62 @@
hash_vector: hash_vector)
{ sum: new_sum, n: new_n, hash_vector: new_hash_vector }
end
+ # Method, which implements final compression
def final_compression(sum:, n:, hash_vector:)
compress(message: sum, hash_vector: compress(message: n, hash_vector: hash_vector))
end
+ # Method, which return digest, dependent on them length
def return_hash(final_vector)
case digest_length
when 512
- final_vector
+ create_digest(final_vector)
when 256
- binary_vector_from_array(final_vector[0..255])
+ create_digest(binary_vector_from_array(final_vector[0..255]))
else
raise ArgumentError,
"digest length must be equal to 256 or 512, not #{digest_length}"
end
end
+ # Method implements addition in ring
def addition_in_ring(first, second, ring)
(first + second) % ring
end
+ # Method implements addition in ring and creates binary vector
def addition_in_ring_to_binary(first, second, ring = 2**HASH_LENGTH, size: HASH_LENGTH)
binary_vector.from_byte(addition_in_ring(first, second, ring), size: size)
end
+ # Compression method
def compress(message:, hash_vector:, n: binary_vector_field_by)
Compression.new(n, message, hash_vector).call
end
+ # Method creates binary vector from array
def binary_vector_from_array(vector)
binary_vector.new(vector)
end
+ # Method creates binary vector and fields it by passed values
def binary_vector_field_by(size: HASH_LENGTH, value: 0)
binary_vector_from_array(Array.new(size, value))
+ end
+
+ # Create new instance of Digest
+ def create_digest(binary_vector)
+ digest.new(binary_vector: binary_vector)
+ end
+
+ def binary_vector
+ @binary_vector ||= BinaryVector
+ end
+
+ def digest
+ @digest ||= Digest
end
end
end