stribog 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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