lib/stribog/create_hash.rb in stribog-0.1.0 vs lib/stribog/create_hash.rb in stribog-0.1.1
- old
+ new
@@ -2,99 +2,129 @@
module Stribog
# Hash function
#
# @author WildDima
class CreateHash
- attr_reader :vector_adapter, :message_adapter, :message, :digest_length
+ attr_reader :binary_vector, :message_adapter, :message, :digest_length, :message_vector
HASH_LENGTH = 512
- def initialize(message, vector_adapter: BinaryVector, message_adapter: Message)
- @vector_adapter = vector_adapter
- @message_adapter = message_adapter
- @message = message
- @n = new_binary_vector(Array.new(HASH_LENGTH, 0))
- @sum = new_binary_vector(Array.new(HASH_LENGTH, 0))
+ 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
end
- def call(digest_length: HASH_LENGTH)
- @digest_length = digest_length
- @hash_vector = create_hash_vector
+ def call(digest_length = HASH_LENGTH)
+ create_hash_params!(digest_length: digest_length)
- while message.size > HASH_LENGTH
- message = new_message_from_bin new_binary_vector(@message.vector[-HASH_LENGTH..-1])
- message_cut!(sum: @sum, n: @n, message: message, hash_vector: @hash_vector)
- @message = new_message_from_bin new_binary_vector(@message.vector[0...-HASH_LENGTH])
- end
+ return_hash(
+ final_compression(
+ core_hashing(
+ compact_message(
+ sum: @sum,
+ n: @n,
+ message_vector: message_vector,
+ hash_vector: @hash_vector
+ )
+ )
+ )
+ )
+ end
- core_hashing!(sum: @sum, n: @n, message: @message, hash_vector: @hash_vector)
+ private
- @hash_vector = compress(message: @n, hash_vector: @hash_vector)
-
- @hash_vector = compress(message: @sum, hash_vector: @hash_vector)
-
- hash_vector
+ def create_hash_params!(digest_length:)
+ @digest_length = digest_length
+ @hash_vector = create_hash_vector
+ @message_vector = message.dup
end
- # TODO: MORE DRY
- def hash_vector
+ def create_hash_vector
case digest_length
when 512
- @hash_vector
+ binary_vector_field_by(size: 512)
when 256
- new_binary_vector(@hash_vector[0..255])
+ binary_vector_from_array(Array.new(64, '00000001').join.chars.map(&:to_i))
else
raise ArgumentError,
"digest length must be equal to 256 or 512, not #{digest_length}"
end
end
- private
+ def compact_message(sum:, n:, message_vector:, hash_vector:, message_head: nil)
+ if message_vector.size < HASH_LENGTH || !message_head.nil? && message_head.size < HASH_LENGTH
+ return { sum: sum, n: n, message_vector: message_head || message_vector,
+ hash_vector: hash_vector }
+ end
- def create_hash_vector
+ compact_message(
+ sum: addition_in_ring_to_binary(sum.to_dec, message_vector.to_dec),
+ n: addition_in_ring_to_binary(n.to_dec, slice_message_tail(message_vector).size),
+ message_vector: message_vector,
+ hash_vector: compress(n: n, message: slice_message_tail(message_vector),
+ hash_vector: hash_vector),
+ message_head: slice_message_head(message_vector)
+ )
+ end
+
+ def slice_message_head(message_vector)
+ binary_vector_from_array(message_vector.vector[0...-HASH_LENGTH])
+ end
+
+ def slice_message_tail(message_vector)
+ binary_vector_from_array(message_vector.vector[-HASH_LENGTH..-1])
+ end
+
+ 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)
+
+ new_n = addition_in_ring_to_binary(n.to_dec, message_vector.size)
+
+ new_hash_vector = compress(n: n.addition_by_zeros(size: HASH_LENGTH),
+ message: message_vector.addition_bit_padding(size: HASH_LENGTH),
+ hash_vector: hash_vector)
+
+ { sum: new_sum, n: new_n, hash_vector: new_hash_vector }
+ end
+
+ def final_compression(sum:, n:, hash_vector:)
+ compress(message: sum, hash_vector: compress(message: n, hash_vector: hash_vector))
+ end
+
+ def return_hash(final_vector)
case digest_length
when 512
- new_binary_vector(Array.new(512, 0))
+ final_vector
when 256
- new_binary_vector(Array.new(64, '00000001').join.chars.map(&:to_i))
+ 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
- def message_cut!(sum:, n:, message:, hash_vector:)
- @hash_vector = compress(n: n, message: message.vector, hash_vector: hash_vector)
- @n = addition_in_ring_to_binary(n.to_dec, message.vector.size)
- @sum = addition_in_ring_to_binary(sum.to_dec, message.vector.to_dec)
- end
-
- def core_hashing!(sum:, n:, message:, hash_vector:)
- @hash_vector = compress(n: n.addition_to(size: HASH_LENGTH),
- message: message.addition_to(size: HASH_LENGTH),
- hash_vector: hash_vector)
- @n = addition_in_ring_to_binary(n.to_dec, message.size)
- @sum = addition_in_ring_to_binary(sum.to_dec, message.addition_to(size: HASH_LENGTH).to_dec)
- end
-
def addition_in_ring(first, second, ring)
(first + second) % ring
end
def addition_in_ring_to_binary(first, second, ring = 2**HASH_LENGTH, size: HASH_LENGTH)
- vector_adapter.from_byte(addition_in_ring(first, second, ring), size: size)
+ binary_vector.from_byte(addition_in_ring(first, second, ring), size: size)
end
- def compress(message:, hash_vector:, n: nil)
- n ||= new_binary_vector(Array.new(HASH_LENGTH, 0))
- Compression.new(n, message, hash_vector).start
+ def compress(message:, hash_vector:, n: binary_vector_field_by)
+ Compression.new(n, message, hash_vector).call
end
- def new_message_from_bin(bin)
- message_adapter.from_bin(bin)
+ def binary_vector_from_array(vector)
+ binary_vector.new(vector)
end
- def new_binary_vector(vector)
- vector_adapter.new(vector)
+ def binary_vector_field_by(size: HASH_LENGTH, value: 0)
+ binary_vector_from_array(Array.new(size, value))
end
end
end