stribog 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc696f1b18cb6ec04fce7cf3cc740be1eed204a6
4
- data.tar.gz: ad56184c6dae90af01b9edd83424e7ba1864e2d4
3
+ metadata.gz: 81cda8678e16f6f25d1cc99e89c31cae61c7e389
4
+ data.tar.gz: 414fe5e18f7909b12649582b18d4b0af7bb2cfcc
5
5
  SHA512:
6
- metadata.gz: e02b4f9c61c008e4d0a4b413c0739d8866d645d12152829fd6fda289c524e2baba94e787ba40c04a1734a80e33d9ad70f8c1df2378e493a6e885792902fadafa
7
- data.tar.gz: fde879defcd83fb2fb86910fe2c2b2c3177cde3c3580db70551573d6870073b5dcfeb863cd02a7b8854609adac733b4347f592a839cd9e0b9b20043e9109e8ac
6
+ metadata.gz: cdb8f9ff439e21593f0cc918e37141c0f2d31cca11123f61a257c313be5e86fb0d609bb6154334d2273f191eb14c3dac500c3192dd672b0c5d40f879b1e0145c
7
+ data.tar.gz: a53ade4b91a890313fedc0f0682f9a9888a0c181fe860effb3b7d854d1c5116234f2b79773d48293b26f8f5602183c27632863601aea4bdec603c5923d6f9f63
@@ -13,7 +13,7 @@ Metrics/MethodLength:
13
13
  Max: 13
14
14
 
15
15
  Metrics/AbcSize:
16
- Max: 20
16
+ Max: 25
17
17
 
18
18
  Metrics/ClassLength:
19
- Max: 120
19
+ Max: 120
@@ -28,10 +28,14 @@ Or install it yourself as:
28
28
  hash = Stribog::CreateHash.new('ruby')
29
29
 
30
30
  # for 256 bit
31
- hash.(256).to_hex #=> "cde7864b760a690f4ec24ffe5c66bd2c00db843e9cf1b82b6c467dba5a7846a7"
31
+ hash.(256).hex #=> "cde7864b760a690f4ec24ffe5c66bd2c00db843e9cf1b82b6c467dba5a7846a7"
32
+ hash.(256).base64
33
+ hash.(256).pack
32
34
 
33
35
  # for 512 bit
34
- hash.(512).to_hex #=> "f0dafc0703f801d1ecbe7ff246808d07507f67879eaacf887ba041336fd51e0a964f00470ed0eedb0378a39e019eb308876ea8c84bb89e2c35159fb6dbbdc598"
36
+ hash.(512).hex #=> "f0dafc0703f801d1ecbe7ff246808d07507f67879eaacf887ba041336fd51e0a964f00470ed0eedb0378a39e019eb308876ea8c84bb89e2c35159fb6dbbdc598"
37
+ hash.(512).base64
38
+ hash.(512).pack
35
39
 
36
40
  === Contributing
37
41
 
@@ -1,11 +1,23 @@
1
1
  require 'stribog/version'
2
+ # require 'pry'
3
+ # require 'pry-byebug'
2
4
  # Stribog gost
3
5
  #
4
6
  # @author WildDima
5
7
  module Stribog
6
8
  require_relative './stribog/create_hash'
7
9
  require_relative './stribog/hash_params'
8
- require_relative './stribog/compression'
9
- require_relative './stribog/binary_vector'
10
+ require_relative './stribog/compression_func'
10
11
  require_relative './stribog/digest'
12
+ require_relative './stribog/byte_vector'
13
+ require_relative './stribog/stage/base'
14
+ require_relative './stribog/stage/initial'
15
+ require_relative './stribog/stage/compression'
16
+ require_relative './stribog/stage/final'
17
+
18
+ HASH_LENGTH = 512
19
+
20
+ def self.vector
21
+ ByteVector
22
+ end
11
23
  end
@@ -0,0 +1,96 @@
1
+ module Stribog
2
+ # byte_array
3
+ #
4
+ # @author WildDima
5
+ class ByteVector
6
+ include Enumerable
7
+
8
+ attr_reader :vector
9
+
10
+ def self.convert(vector)
11
+ case vector
12
+ when String
13
+ new(vector.unpack('C*'))
14
+ when Numeric
15
+ # TODO: REFACTOR
16
+ bin = vector.to_s(2)
17
+ size = 2**Math.log2(vector.size * 8).ceil
18
+ new(['0' * (size - bin.size) + bin].pack('B*').unpack('C*'))
19
+ end
20
+ end
21
+
22
+ def initialize(vector)
23
+ @vector = vector
24
+ end
25
+
26
+ def ^(other)
27
+ vec = [other, self].sort_by(&:size).reverse.map(&:reverse)
28
+ self.class.new vec[0].map
29
+ .with_index { |bit, index| bit ^ (vec[1][index] || 0) }.reverse
30
+ end
31
+
32
+ def +(other)
33
+ self.class.new vector + other.to_a
34
+ end
35
+
36
+ def addition(size: 64)
37
+ return self if vector.size >= size
38
+ self.class.new(Array.new(size - vector.size, 0) + vector)
39
+ end
40
+
41
+ def padding(size: 64)
42
+ return self if vector.size >= size
43
+ # (self.class.new([1]) + vector).addition_by_zeros(size: 512)
44
+ self.class.new([1] + vector).addition(size: size)
45
+ end
46
+
47
+ def byte8
48
+ @byte8 ||= vector.pack('C*').unpack('Q*')
49
+ end
50
+
51
+ def bit64
52
+ @bit64 ||= byte8.map { |b| [b].pack('Q*').unpack('B*') }.flatten
53
+ end
54
+
55
+ def to_dec
56
+ # to_s.to_i(2)
57
+ vector.pack('C*').unpack('B*').first.to_i(2)
58
+ end
59
+
60
+ def to_hex
61
+ to_s.to_i(2).to_s(16)
62
+ end
63
+
64
+ def to_s
65
+ # vector.pack('C*')
66
+ vector
67
+ end
68
+
69
+ def size
70
+ @size ||= vector.size
71
+ end
72
+
73
+ def [](index)
74
+ vector[index]
75
+ end
76
+
77
+ def each
78
+ return vector.each unless block_given?
79
+ vector.each do |v|
80
+ yield(v)
81
+ end
82
+ end
83
+
84
+ def to_a
85
+ vector
86
+ end
87
+
88
+ def zero?
89
+ vector.any?(&:zero?)
90
+ end
91
+
92
+ def reverse
93
+ self.class.new vector.reverse
94
+ end
95
+ end
96
+ end
@@ -3,7 +3,7 @@ module Stribog
3
3
  #
4
4
  # Class implements compression function of GOST R 34.11-2012 algorithm.
5
5
  # @author WildDima
6
- class Compression
6
+ class CompressionFunc
7
7
  include HashParams
8
8
 
9
9
  def initialize(n, message, hash_vector)
@@ -32,36 +32,34 @@ module Stribog
32
32
  end
33
33
 
34
34
  def replacement_pi(vector)
35
- BinaryVector.from_byte_array vector.to_byte_array
36
- .map { |byte| PI[byte] }
35
+ ByteVector.new vector.map { |byte| PI[byte] }
37
36
  end
38
37
 
39
38
  # rubocop:disable Style/EachWithObject
40
39
  def permutation_t(vector)
41
- BinaryVector.from_byte_array(
42
- vector.to_byte_array
43
- .each.with_index.inject([]) do |b_arr, (byte, index)|
44
- b_arr[T[index]] = byte
45
- b_arr
46
- end
40
+ ByteVector.new(
41
+ vector.each.with_index.inject([]) do |b_arr, (byte, index)|
42
+ b_arr[T[index]] = byte
43
+ b_arr
44
+ end.map(&:to_i)
47
45
  )
48
46
  end
49
47
  # rubocop:enable Style/EachWithObject
50
48
 
51
49
  def linear_transformation(vector)
52
- BinaryVector.from_byte_array(
53
- vector.each_slice(64).map do |byte8|
54
- small_linear_transformation(BinaryVector.new(byte8)).to_dec
55
- end,
56
- size: 64
50
+ ByteVector.new(
51
+ vector.bit64.map do |byte8|
52
+ small_linear_transformation(byte8)
53
+ end.flatten
57
54
  )
58
55
  end
59
56
 
60
57
  def small_linear_transformation(vector)
61
- BinaryVector.from_byte(
58
+ # REFACTOR
59
+ ByteVector.convert(
62
60
  not_zeros_indexes(vector)
63
61
  .inject(0) { |acc, elem| acc ^ MATRIX_A[elem] }
64
- ).addition_by_zeros(size: 64)
62
+ ).to_a
65
63
  end
66
64
 
67
65
  # rubocop:disable Style/EachWithObject
@@ -70,8 +68,7 @@ module Stribog
70
68
  .inject(v1: first_vector.dup,
71
69
  v2: second_vector.dup) do |vs, const|
72
70
  vs[:v2] = lpsx_func(vs[:v1], vs[:v2])
73
- vs[:v1] = lpsx_func(vs[:v1], BinaryVector.from_byte(const.to_i(16),
74
- size: 512))
71
+ vs[:v1] = lpsx_func(vs[:v1], ByteVector.convert(const))
75
72
  vs
76
73
  end
77
74
  vectors[:v1] ^ vectors[:v2]
@@ -79,8 +76,8 @@ module Stribog
79
76
  # rubocop:enable Style/EachWithObject
80
77
 
81
78
  def not_zeros_indexes(vector)
82
- vector.map.with_index do |bit, index|
83
- next if bit.zero?
79
+ vector.chars.map.with_index do |bit, index|
80
+ next if bit == '0'
84
81
  index
85
82
  end.compact
86
83
  end
@@ -27,11 +27,12 @@ module Stribog
27
27
  # digest.message_vector
28
28
  # @return [BinaryVector] binary representation of message
29
29
  attr_reader :message_vector
30
+ attr_reader :vector
30
31
 
31
- HASH_LENGTH = 512
32
-
33
- def initialize(message)
32
+ def initialize(message, transformation = :from_hex, vector = Stribog.vector)
34
33
  @message = message
34
+ @transformation = transformation
35
+ @vector = vector
35
36
  end
36
37
 
37
38
  # Create digest of {#message}. Default equal to 512.
@@ -41,140 +42,38 @@ module Stribog
41
42
  # Stribog::CreateHash.new('ruby').call(512)
42
43
  # @author WildDima
43
44
  def call(digest_length = HASH_LENGTH)
44
- prepare_hash_params!(digest_length: digest_length)
45
-
45
+ @digest_length = digest_length
46
46
  return_hash(
47
- final_compression(
48
- core_hashing(
49
- compact_message(
50
- sum: @sum,
51
- n: @n,
52
- message_vector: message_vector,
53
- hash_vector: @hash_vector
54
- )
47
+ Stage::Final.new(
48
+ Stage::Compression.new(
49
+ Stage::Initial.new(self)
55
50
  )
56
- )
51
+ ).call
57
52
  )
58
53
  end
59
54
 
60
55
  private
61
56
 
62
- # Create instance vars for hashing
63
- def prepare_hash_params!(digest_length:)
64
- @n = binary_vector_field_by
65
- @sum = binary_vector_field_by
66
- @digest_length = digest_length
67
- @hash_vector = create_hash_vector
68
- @message_vector = binary_vector.from_hex(message)
69
- end
70
-
71
- # Create hash_vector for hashing
72
- def create_hash_vector
73
- case digest_length
74
- when 512
75
- binary_vector_field_by(size: 512)
76
- when 256
77
- binary_vector_from_array(Array.new(64, '00000001').join.chars.map(&:to_i))
78
- else
79
- raise ArgumentError,
80
- "digest length must be equal to 256 or 512, not #{digest_length}"
81
- end
82
- end
83
-
84
- # Method, which slices longer messages, and hashings them by parts.
85
- def compact_message(sum:, n:, message_vector:, hash_vector:, message_head: nil)
86
- current_vector = message_head || message_vector
87
- if current_vector.size < HASH_LENGTH
88
- return { sum: sum, n: n, message_vector: current_vector,
89
- hash_vector: hash_vector }
90
- end
91
-
92
- compact_message(
93
- sum: addition_in_ring_to_binary(sum.to_dec, current_vector.to_dec),
94
- n: addition_in_ring_to_binary(n.to_dec, slice_message_tail(current_vector).size),
95
- message_vector: message_vector,
96
- hash_vector: compress(n: n, message: slice_message_tail(current_vector),
97
- hash_vector: hash_vector),
98
- message_head: slice_message_head(current_vector)
99
- )
100
- end
101
-
102
- # Method, which slices head of message
103
- def slice_message_head(message_vector)
104
- binary_vector_from_array(message_vector.vector[0...-HASH_LENGTH])
105
- end
106
-
107
- # Method, which slices head of tail
108
- def slice_message_tail(message_vector)
109
- binary_vector_from_array(message_vector.vector[-HASH_LENGTH..-1])
110
- end
111
-
112
- # Method, which implements main hashing
113
- def core_hashing(sum:, n:, message_vector:, hash_vector:)
114
- new_sum = addition_in_ring_to_binary(sum.to_dec,
115
- message_vector
116
- .addition_bit_padding(size: HASH_LENGTH)
117
- .to_dec)
118
-
119
- new_n = addition_in_ring_to_binary(n.to_dec, message_vector.size)
120
-
121
- new_hash_vector = compress(n: n.addition_by_zeros(size: HASH_LENGTH),
122
- message: message_vector.addition_bit_padding(size: HASH_LENGTH),
123
- hash_vector: hash_vector)
124
-
125
- { sum: new_sum, n: new_n, hash_vector: new_hash_vector }
126
- end
127
-
128
- # Method, which implements final compression
129
- def final_compression(sum:, n:, hash_vector:)
130
- compress(message: sum, hash_vector: compress(message: n, hash_vector: hash_vector))
131
- end
132
-
133
57
  # Method, which return digest, dependent on them length
134
58
  def return_hash(final_vector)
135
59
  case digest_length
136
60
  when 512
137
61
  create_digest(final_vector)
138
62
  when 256
139
- create_digest(binary_vector_from_array(final_vector[0..255]))
63
+ create_digest(vector_from_array(final_vector[0..31]))
140
64
  else
141
65
  raise ArgumentError,
142
66
  "digest length must be equal to 256 or 512, not #{digest_length}"
143
67
  end
144
68
  end
145
69
 
146
- # Method implements addition in ring
147
- def addition_in_ring(first, second, ring)
148
- (first + second) % ring
149
- end
150
-
151
- # Method implements addition in ring and creates binary vector
152
- def addition_in_ring_to_binary(first, second, ring = 2**HASH_LENGTH, size: HASH_LENGTH)
153
- binary_vector.from_byte(addition_in_ring(first, second, ring), size: size)
154
- end
155
-
156
- # Compression method
157
- def compress(message:, hash_vector:, n: binary_vector_field_by)
158
- Compression.new(n, message, hash_vector).call
159
- end
160
-
161
- # Method creates binary vector from array
162
- def binary_vector_from_array(vector)
163
- binary_vector.new(vector)
164
- end
165
-
166
- # Method creates binary vector and fields it by passed values
167
- def binary_vector_field_by(size: HASH_LENGTH, value: 0)
168
- binary_vector_from_array(Array.new(size, value))
70
+ def vector_from_array(v)
71
+ vector.new(v)
169
72
  end
170
73
 
171
74
  # Create new instance of Digest
172
- def create_digest(binary_vector)
173
- digest.new(binary_vector: binary_vector)
174
- end
175
-
176
- def binary_vector
177
- @binary_vector ||= BinaryVector
75
+ def create_digest(vector)
76
+ digest.new(vector: vector)
178
77
  end
179
78
 
180
79
  def digest
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+
1
3
  module Stribog
2
4
  # Digest
3
5
  #
@@ -12,18 +14,31 @@ module Stribog
12
14
  # @example
13
15
  # digest.binary
14
16
  # @return [Array] binary representation of digest
15
- attr_reader :binary
17
+ attr_reader :vector
18
+ attr_reader :dec
16
19
  # Contains hex value of hash
17
20
  #
18
21
  # @api public
19
22
  # @example
20
23
  # digest.hex
21
24
  # @return [String] hex representation of digest
22
- attr_reader :hex
23
25
 
24
- def initialize(binary_vector:)
25
- @binary = binary_vector.vector
26
- @hex = binary_vector.to_hex
26
+ def initialize(vector:)
27
+ @vector = vector
28
+ @dec = vector.to_dec
29
+ end
30
+
31
+ def hex
32
+ dec.to_s(16)
33
+ end
34
+ alias to_hex hex
35
+
36
+ def base64
37
+ Base64.encode64(dec.to_s)
38
+ end
39
+
40
+ def pack(meaning = 'C*')
41
+ binary.to_byte_array.pack(meaning)
27
42
  end
28
43
  end
29
44
  end
@@ -38,17 +38,17 @@ module Stribog
38
38
  0x70a6a56e2440598e, 0x3853dc371220a247, 0x1ca76e95091051ad, 0x0edd37c48a08a6d8,
39
39
  0x07e095624504536c, 0x8d70c431ac02a736, 0xc83862965601dd1b, 0x641c314b2b8ee083].freeze
40
40
 
41
- CONSTANTS_C = %w(b1085bda1ecadae9ebcb2f81c0657c1f2f6a76432e45d016714eb88d7585c4fc4b7ce09192676901a2422a08a460d31505767436cc744d23dd806559f2a64507
42
- 6fa3b58aa99d2f1a4fe39d460f70b5d7f3feea720a232b9861d55e0f16b501319ab5176b12d699585cb561c2db0aa7ca55dda21bd7cbcd56e679047021b19bb7
43
- f574dcac2bce2fc70a39fc286a3d843506f15e5f529c1f8bf2ea7514b1297b7bd3e20fe490359eb1c1c93a376062db09c2b6f443867adb31991e96f50aba0ab2
44
- ef1fdfb3e81566d2f948e1a05d71e4dd488e857e335c3c7d9d721cad685e353fa9d72c82ed03d675d8b71333935203be3453eaa193e837f1220cbebc84e3d12e
45
- 4bea6bacad4747999a3f410c6ca923637f151c1f1686104a359e35d7800fffbdbfcd1747253af5a3dfff00b723271a167a56a27ea9ea63f5601758fd7c6cfe57
46
- ae4faeae1d3ad3d96fa4c33b7a3039c02d66c4f95142a46c187f9ab49af08ec6cffaa6b71c9ab7b40af21f66c2bec6b6bf71c57236904f35fa68407a46647d6e
47
- f4c70e16eeaac5ec51ac86febf240954399ec6c7e6bf87c9d3473e33197a93c90992abc52d822c3706476983284a05043517454ca23c4af38886564d3a14d493
48
- 9b1f5b424d93c9a703e7aa020c6e41414eb7f8719c36de1e89b4443b4ddbc49af4892bcb929b069069d18d2bd1a5c42f36acc2355951a8d9a47f0dd4bf02e71e
49
- 378f5a541631229b944c9ad8ec165fde3a7d3a1b258942243cd955b7e00d0984800a440bdbb2ceb17b2b8a9aa6079c540e38dc92cb1f2a607261445183235adb
50
- abbedea680056f52382ae548b2e4f3f38941e71cff8a78db1fffe18a1b3361039fe76702af69334b7a1e6c303b7652f43698fad1153bb6c374b4c7fb98459ced
51
- 7bcd9ed0efc889fb3002c6cd635afe94d8fa6bbbebab076120018021148466798a1d71efea48b9caefbacd1d7d476e98dea2594ac06fd85d6bcaa4cd81f32d1b
52
- 378ee767f11631bad21380b00449b17acda43c32bcdf1d77f82012d430219f9b5d80ef9d1891cc86e71da4aa88e12852faf417d5d9b21b9948bc924af11bd720).freeze
41
+ CONSTANTS_C = [0xb1085bda1ecadae9ebcb2f81c0657c1f2f6a76432e45d016714eb88d7585c4fc4b7ce09192676901a2422a08a460d31505767436cc744d23dd806559f2a64507,
42
+ 0x6fa3b58aa99d2f1a4fe39d460f70b5d7f3feea720a232b9861d55e0f16b501319ab5176b12d699585cb561c2db0aa7ca55dda21bd7cbcd56e679047021b19bb7,
43
+ 0xf574dcac2bce2fc70a39fc286a3d843506f15e5f529c1f8bf2ea7514b1297b7bd3e20fe490359eb1c1c93a376062db09c2b6f443867adb31991e96f50aba0ab2,
44
+ 0xef1fdfb3e81566d2f948e1a05d71e4dd488e857e335c3c7d9d721cad685e353fa9d72c82ed03d675d8b71333935203be3453eaa193e837f1220cbebc84e3d12e,
45
+ 0x4bea6bacad4747999a3f410c6ca923637f151c1f1686104a359e35d7800fffbdbfcd1747253af5a3dfff00b723271a167a56a27ea9ea63f5601758fd7c6cfe57,
46
+ 0xae4faeae1d3ad3d96fa4c33b7a3039c02d66c4f95142a46c187f9ab49af08ec6cffaa6b71c9ab7b40af21f66c2bec6b6bf71c57236904f35fa68407a46647d6e,
47
+ 0xf4c70e16eeaac5ec51ac86febf240954399ec6c7e6bf87c9d3473e33197a93c90992abc52d822c3706476983284a05043517454ca23c4af38886564d3a14d493,
48
+ 0x9b1f5b424d93c9a703e7aa020c6e41414eb7f8719c36de1e89b4443b4ddbc49af4892bcb929b069069d18d2bd1a5c42f36acc2355951a8d9a47f0dd4bf02e71e,
49
+ 0x378f5a541631229b944c9ad8ec165fde3a7d3a1b258942243cd955b7e00d0984800a440bdbb2ceb17b2b8a9aa6079c540e38dc92cb1f2a607261445183235adb,
50
+ 0xabbedea680056f52382ae548b2e4f3f38941e71cff8a78db1fffe18a1b3361039fe76702af69334b7a1e6c303b7652f43698fad1153bb6c374b4c7fb98459ced,
51
+ 0x7bcd9ed0efc889fb3002c6cd635afe94d8fa6bbbebab076120018021148466798a1d71efea48b9caefbacd1d7d476e98dea2594ac06fd85d6bcaa4cd81f32d1b,
52
+ 0x378ee767f11631bad21380b00449b17acda43c32bcdf1d77f82012d430219f9b5d80ef9d1891cc86e71da4aa88e12852faf417d5d9b21b9948bc924af11bd720].freeze
53
53
  end
54
54
  end
@@ -0,0 +1,62 @@
1
+ module Stribog
2
+ # Stage
3
+ #
4
+ # @author WildDima
5
+ module Stage
6
+ # Base
7
+ #
8
+ # @author WildDima
9
+ class Base
10
+ attr_reader :prev_stage
11
+ attr_reader :vector
12
+ attr_accessor :n
13
+ attr_accessor :sum
14
+ attr_accessor :digest_length
15
+ attr_accessor :hash_vector
16
+ attr_accessor :message_vector
17
+ attr_accessor :message_head
18
+ attr_accessor :current_vector
19
+
20
+ def initialize(prev_stage, vector = Stribog.vector)
21
+ @prev_stage = prev_stage
22
+ @vector = vector
23
+ end
24
+
25
+ def call
26
+ raise NotImplementedYet
27
+ end
28
+
29
+ protected
30
+
31
+ def prev_stage_call
32
+ @prev_stage_call ||= prev_stage.call
33
+ end
34
+
35
+ def field_vector(value:, size: 64)
36
+ vector.new(Array.new(size, value))
37
+ end
38
+
39
+ def empty_vector(size: 64)
40
+ field_vector(value: 0, size: size)
41
+ end
42
+
43
+ def slice_message_head(message_vector)
44
+ vector.new(message_vector.vector[0...-HASH_LENGTH / 8])
45
+ end
46
+
47
+ # Method, which slices head of tail
48
+ def slice_message_tail(message_vector)
49
+ vector.new(message_vector.vector[-HASH_LENGTH / 8..-1])
50
+ end
51
+
52
+ # Compression method
53
+ def compress(message:, hash_vector:, n: empty_vector)
54
+ CompressionFunc.new(n, message, hash_vector).call
55
+ end
56
+
57
+ def addition_in_ring(first, second, ring = 2**HASH_LENGTH)
58
+ vector.convert((first + second) % ring)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,53 @@
1
+ module Stribog
2
+ # BinaryVector
3
+ #
4
+ # @author WildDima
5
+ module Stage
6
+ # Compression
7
+ #
8
+ # @author WildDima
9
+ class Compression < Base
10
+ def call
11
+ set_params
12
+ compression
13
+ end
14
+
15
+ private
16
+
17
+ def set_params
18
+ @n = prev_stage_call[:n]
19
+ @sum = prev_stage_call[:sum]
20
+ @digest_length = prev_stage_call[:digest_length]
21
+ @hash_vector = prev_stage_call[:hash_vector]
22
+ @message_vector = prev_stage_call[:message_vector]
23
+ @message_head = nil
24
+ end
25
+
26
+ def return_params
27
+ {
28
+ n: n,
29
+ sum: sum,
30
+ digest_length: digest_length,
31
+ hash_vector: hash_vector,
32
+ message_vector: current_vector
33
+ }
34
+ end
35
+
36
+ def compression
37
+ self.current_vector = message_head || message_vector
38
+ return return_params if current_vector.size * 8 < HASH_LENGTH
39
+ transformation
40
+ compression
41
+ end
42
+
43
+ def transformation
44
+ self.hash_vector = compress(n: n,
45
+ message: slice_message_tail(current_vector),
46
+ hash_vector: hash_vector)
47
+ self.sum = addition_in_ring(sum.to_dec, current_vector.to_dec)
48
+ self.n = addition_in_ring(n.to_dec, slice_message_tail(current_vector).size * 8)
49
+ self.message_head = slice_message_head(current_vector)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ module Stribog
2
+ # BinaryVector
3
+ #
4
+ # @author WildDima
5
+ module Stage
6
+ # Final
7
+ #
8
+ # @author WildDima
9
+ class Final < Base
10
+ def call
11
+ set_params
12
+ final
13
+ end
14
+
15
+ private
16
+
17
+ def set_params
18
+ @n = prev_stage_call[:n]
19
+ @sum = prev_stage_call[:sum]
20
+ @digest_length = prev_stage_call[:digest_length]
21
+ @hash_vector = prev_stage_call[:hash_vector]
22
+ @message_vector = prev_stage_call[:message_vector]
23
+ @message_head = nil
24
+ end
25
+
26
+ def final
27
+ self.hash_vector = compress(n: n.addition(size: HASH_LENGTH / 8),
28
+ message: message_vector.padding,
29
+ hash_vector: hash_vector)
30
+ self.sum = addition_in_ring(sum.to_dec, message_vector.padding.to_dec)
31
+ self.n = addition_in_ring(n.to_dec, message_vector.size * 8)
32
+
33
+ compress(message: sum, hash_vector: compress(message: n, hash_vector: hash_vector))
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,47 @@
1
+ module Stribog
2
+ # BinaryVector
3
+ #
4
+ # @author WildDima
5
+ module Stage
6
+ # Initial
7
+ #
8
+ # @author WildDima
9
+ class Initial < Base
10
+ def call
11
+ return_params
12
+ end
13
+
14
+ private
15
+
16
+ def return_params
17
+ {
18
+ n: empty_vector,
19
+ sum: empty_vector,
20
+ digest_length: digest_length,
21
+ hash_vector: hash_vector,
22
+ message_vector: message_vector
23
+ }
24
+ end
25
+
26
+ def hash_vector
27
+ case digest_length
28
+ when 512
29
+ empty_vector
30
+ when 256
31
+ field_vector(value: 1)
32
+ else
33
+ raise ArgumentError,
34
+ "digest length must be equal to 256 or 512, not #{digest_length}"
35
+ end
36
+ end
37
+
38
+ def digest_length
39
+ @digest_length ||= prev_stage.digest_length
40
+ end
41
+
42
+ def message_vector
43
+ @message_vector ||= vector.convert(prev_stage.message)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Stribog
2
- VERSION = '0.1.3'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -34,5 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "rake", "~> 10.0"
35
35
  spec.add_development_dependency "rspec", "~> 3.0"
36
36
  spec.add_development_dependency "rubocop", "~> 0.45.0"
37
- spec.add_development_dependency "byebug", "~> 9.0"
37
+ spec.add_development_dependency "pry", "~> 0.10.4"
38
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stribog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - WildDima
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-04 00:00:00.000000000 Z
11
+ date: 2017-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,19 +67,19 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.45.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: byebug
70
+ name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '9.0'
75
+ version: 0.10.4
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '9.0'
82
+ version: 0.10.4
83
83
  description:
84
84
  email:
85
85
  - dtopornin@gmail.com
@@ -99,11 +99,15 @@ files:
99
99
  - bin/console
100
100
  - bin/setup
101
101
  - lib/stribog.rb
102
- - lib/stribog/binary_vector.rb
103
- - lib/stribog/compression.rb
102
+ - lib/stribog/byte_vector.rb
103
+ - lib/stribog/compression_func.rb
104
104
  - lib/stribog/create_hash.rb
105
105
  - lib/stribog/digest.rb
106
106
  - lib/stribog/hash_params.rb
107
+ - lib/stribog/stage/base.rb
108
+ - lib/stribog/stage/compression.rb
109
+ - lib/stribog/stage/final.rb
110
+ - lib/stribog/stage/initial.rb
107
111
  - lib/stribog/version.rb
108
112
  - stribog.gemspec
109
113
  homepage: https://github.com/WildDima/stribog
@@ -1,105 +0,0 @@
1
- module Stribog
2
- # BinaryVector
3
- #
4
- # @author WildDima
5
- class BinaryVector
6
- include Enumerable
7
-
8
- attr_reader :vector
9
-
10
- class << self
11
- def from_byte(byte, size: 8)
12
- new(byte.to_s(2).chars.map(&:to_i)).addition_by_zeros(size: size)
13
- end
14
-
15
- def from_byte_array(byte_array, size: 8)
16
- new(byte_array.map { |byte| from_byte(byte, size: size).to_a }
17
- .inject([]) { |acc, elem| acc + elem })
18
- end
19
-
20
- def from_hex(hex)
21
- new hex_to_bin(hex)
22
- end
23
-
24
- def hex_to_bin(hex)
25
- hex.chars.map do |x|
26
- bin = x.to_i(16).to_s(2)
27
- '0' * (4 - bin.length) + bin
28
- end.join.chars.map(&:to_i)
29
- end
30
- end
31
-
32
- def initialize(vector)
33
- @vector = vector
34
- raise 'NotBinaryError' unless binary?
35
- end
36
-
37
- def ^(other)
38
- raise 'DimensionError' unless according_dimension?(other)
39
- self.class.new vector.map.with_index { |bit, index| bit ^ other[index] }
40
- end
41
-
42
- def +(other)
43
- self.class.new vector + other.to_a
44
- end
45
-
46
- def addition_by_zeros(size: 512)
47
- return self if vector.size >= size
48
- self.class.new(Array.new(size - vector.size, 0) + @vector)
49
- end
50
-
51
- def addition_bit_padding(size: 512)
52
- return self if vector.size >= size
53
- (self.class.new([1]) + vector).addition_by_zeros(size: 512)
54
- end
55
-
56
- def to_dec
57
- to_s.to_i(2)
58
- end
59
-
60
- def to_hex
61
- to_s.to_i(2).to_s(16)
62
- end
63
-
64
- def to_s
65
- vector.join
66
- end
67
-
68
- def size
69
- vector.size
70
- end
71
-
72
- def [](index)
73
- vector[index]
74
- end
75
-
76
- def each
77
- vector.each do |v|
78
- yield(v)
79
- end
80
- end
81
-
82
- def to_a
83
- vector
84
- end
85
-
86
- def to_byte_array
87
- raise 'DimensionError' unless (vector.size % 8).zero?
88
- vector.each_slice(8).map { |byte| byte.join.to_i(2) }
89
- end
90
-
91
- def zero?
92
- to_dec.zero?
93
- end
94
-
95
- private
96
-
97
- def binary?
98
- vector.all? { |el| [0, 1].include? el }
99
- end
100
-
101
- def according_dimension?(second_vector)
102
- vector.size == second_vector.size
103
- end
104
- end
105
- end