crypto_toolchain 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +51 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +3 -0
  6. data/Guardfile +15 -0
  7. data/LICENSE +21 -0
  8. data/README.md +95 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/crypto_toolchain.gemspec +33 -0
  13. data/exe/crypto +7 -0
  14. data/lib/crypto_toolchain/black_boxes/aes_ctr_editor.rb +25 -0
  15. data/lib/crypto_toolchain/black_boxes/cbc_bitflip_target.rb +33 -0
  16. data/lib/crypto_toolchain/black_boxes/cbc_iv_equals_key_target.rb +35 -0
  17. data/lib/crypto_toolchain/black_boxes/cbc_padding_oracle.rb +44 -0
  18. data/lib/crypto_toolchain/black_boxes/ctr_bitflip_target.rb +32 -0
  19. data/lib/crypto_toolchain/black_boxes/dsa_keypair.rb +50 -0
  20. data/lib/crypto_toolchain/black_boxes/ecb_cut_and_paste_target.rb +50 -0
  21. data/lib/crypto_toolchain/black_boxes/ecb_interpolate_chosen_plaintext_oracle.rb +28 -0
  22. data/lib/crypto_toolchain/black_boxes/ecb_or_cbc_encryptor.rb +47 -0
  23. data/lib/crypto_toolchain/black_boxes/ecb_prepend_chosen_plaintext_oracle.rb +23 -0
  24. data/lib/crypto_toolchain/black_boxes/md4_mac.rb +20 -0
  25. data/lib/crypto_toolchain/black_boxes/mt_19937_stream_cipher.rb +47 -0
  26. data/lib/crypto_toolchain/black_boxes/netcat_cbc_padding_oracle.rb +33 -0
  27. data/lib/crypto_toolchain/black_boxes/rsa_keypair.rb +83 -0
  28. data/lib/crypto_toolchain/black_boxes/rsa_parity_oracle.rb +14 -0
  29. data/lib/crypto_toolchain/black_boxes/rsa_unpadded_message_recovery_oracle.rb +24 -0
  30. data/lib/crypto_toolchain/black_boxes/sha1_mac.rb +20 -0
  31. data/lib/crypto_toolchain/black_boxes.rb +22 -0
  32. data/lib/crypto_toolchain/diffie_hellman/messages.rb +53 -0
  33. data/lib/crypto_toolchain/diffie_hellman/mitm.rb +52 -0
  34. data/lib/crypto_toolchain/diffie_hellman/peer.rb +130 -0
  35. data/lib/crypto_toolchain/diffie_hellman/peer_info.rb +43 -0
  36. data/lib/crypto_toolchain/diffie_hellman/received_message.rb +17 -0
  37. data/lib/crypto_toolchain/diffie_hellman.rb +10 -0
  38. data/lib/crypto_toolchain/extensions/integer_extensions.rb +90 -0
  39. data/lib/crypto_toolchain/extensions/object_extensions.rb +24 -0
  40. data/lib/crypto_toolchain/extensions/string_extensions.rb +263 -0
  41. data/lib/crypto_toolchain/extensions.rb +8 -0
  42. data/lib/crypto_toolchain/srp/client.rb +51 -0
  43. data/lib/crypto_toolchain/srp/framework.rb +55 -0
  44. data/lib/crypto_toolchain/srp/server.rb +38 -0
  45. data/lib/crypto_toolchain/srp/simple_client.rb +32 -0
  46. data/lib/crypto_toolchain/srp/simple_server.rb +68 -0
  47. data/lib/crypto_toolchain/srp.rb +14 -0
  48. data/lib/crypto_toolchain/tools/aes_ctr_recoverer.rb +30 -0
  49. data/lib/crypto_toolchain/tools/cbc_bitflip_attack.rb +30 -0
  50. data/lib/crypto_toolchain/tools/cbc_iv_equals_key_attack.rb +30 -0
  51. data/lib/crypto_toolchain/tools/cbc_padding_oracle_attack.rb +51 -0
  52. data/lib/crypto_toolchain/tools/ctr_bitflip_attack.rb +24 -0
  53. data/lib/crypto_toolchain/tools/determine_blocksize.rb +20 -0
  54. data/lib/crypto_toolchain/tools/dsa_recover_nonce_from_signatures.rb +53 -0
  55. data/lib/crypto_toolchain/tools/dsa_recover_private_key_from_nonce.rb +39 -0
  56. data/lib/crypto_toolchain/tools/ecb_cut_and_paste_attack.rb +47 -0
  57. data/lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb +72 -0
  58. data/lib/crypto_toolchain/tools/ecb_prepend_chosen_plaintext_attack.rb +42 -0
  59. data/lib/crypto_toolchain/tools/interactive_xor.rb +51 -0
  60. data/lib/crypto_toolchain/tools/low_exponent_rsa_signature_forgery.rb +27 -0
  61. data/lib/crypto_toolchain/tools/md4_length_extension_attack.rb +30 -0
  62. data/lib/crypto_toolchain/tools/mt_19937_seed_recoverer.rb +27 -0
  63. data/lib/crypto_toolchain/tools/mt_19937_stream_cipher_seed_recoverer.rb +40 -0
  64. data/lib/crypto_toolchain/tools/rsa_broadcast_attack.rb +21 -0
  65. data/lib/crypto_toolchain/tools/rsa_parity_oracle_attack.rb +33 -0
  66. data/lib/crypto_toolchain/tools/rsa_unpadded_message_recovery_attack.rb +49 -0
  67. data/lib/crypto_toolchain/tools/sha1_length_extension_attack.rb +30 -0
  68. data/lib/crypto_toolchain/tools.rb +31 -0
  69. data/lib/crypto_toolchain/utilities/hmac.rb +73 -0
  70. data/lib/crypto_toolchain/utilities/md4.rb +106 -0
  71. data/lib/crypto_toolchain/utilities/mt_19937.rb +218 -0
  72. data/lib/crypto_toolchain/utilities/sha1.rb +95 -0
  73. data/lib/crypto_toolchain/utilities.rb +9 -0
  74. data/lib/crypto_toolchain/version.rb +3 -0
  75. data/lib/crypto_toolchain.rb +34 -0
  76. metadata +232 -0
@@ -0,0 +1,73 @@
1
+ module CryptoToolchain
2
+ module Utilities
3
+ class HMAC
4
+ class << self
5
+ def digest(message, key: , hash: CryptoToolchain::Utilities::SHA1)
6
+ new(key: key, hash: hash).digest(message)
7
+ end
8
+
9
+ def hexdigest(message, key: , hash: CryptoToolchain::Utilities::SHA1)
10
+ new(key: key, hash: hash).hexdigest(message)
11
+ end
12
+
13
+ end
14
+
15
+ def initialize(key: , hash: , blocksize: nil)
16
+ @key = key
17
+ @hash = hash
18
+ @blocksize = blocksize || determine_blocksize
19
+ end
20
+
21
+ def digest(message)
22
+ hash.digest(outer_pad + hash.digest(inner_pad + message))
23
+ end
24
+
25
+ def hexdigest(message)
26
+ digest(message).to_hex
27
+ end
28
+
29
+ def determine_blocksize
30
+ case hash.to_s.split(':').last.downcase.gsub(/[^a-z0-9]/i, '')
31
+ when /md(4|5)/
32
+ 64
33
+ when /sha(1|224|256)/
34
+ 64
35
+ else
36
+ raise ArgumentError.new("Unsupported hash #{hash}")
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def outer_pad
43
+ @outer_pad ||= (0x5c.chr * blocksize) ^ blocksize_key
44
+ end
45
+
46
+ def inner_pad
47
+ @inner_pad ||= (0x36.chr * blocksize) ^ blocksize_key
48
+ end
49
+
50
+ def blocksize_key
51
+ @blocksize_key ||= padded(shortened(key))
52
+ end
53
+
54
+ def padded(input)
55
+ if input.bytesize < blocksize
56
+ input.ljust(blocksize, 0.chr)
57
+ else
58
+ input
59
+ end
60
+ end
61
+
62
+ def shortened(input)
63
+ if input.bytesize > blocksize
64
+ hash.digest(input)
65
+ else
66
+ input
67
+ end
68
+ end
69
+
70
+ attr_reader :blocksize, :key, :hash
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,106 @@
1
+ #encoding: ASCII-8BIT
2
+ module CryptoToolchain
3
+ module Utilities
4
+ class MD4
5
+ class << self
6
+ def hexdigest(str, state: INITIAL_STATE, append_length: 0 )
7
+ CryptoToolchain::Utilities::MD4.new(str).hexdigest(state: state, append_length: append_length)
8
+ end
9
+
10
+ def bindigest(str, state: INITIAL_STATE, append_length: 0)
11
+ CryptoToolchain::Utilities::MD4.new(str).bindigest(state: state, append_length: append_length)
12
+ end
13
+ alias_method :digest, :bindigest
14
+
15
+ def padding(str)
16
+ num_null_pad = (56 - (str.bytesize + 1) ) % 64
17
+ 0x80.chr + (0.chr * num_null_pad) + [(str.bytesize * 8)].pack("Q<")
18
+ end
19
+ end
20
+
21
+ def initialize(message)
22
+ @original = message
23
+ end
24
+
25
+ def hexdigest(state: INITIAL_STATE, append_length: 0)
26
+ bindigest(state: state, append_length: append_length).unpack("H*").join
27
+ end
28
+
29
+ def bindigest(state: INITIAL_STATE, append_length: 0)
30
+ running_state = registers_from(state)
31
+
32
+ length = original.bytesize + append_length
33
+
34
+ padding_len = (56 - (length + 1) ) % 64
35
+ str_length = [(length * 8)].pack("Q<")
36
+ padding = (0x80.chr + (0.chr * padding_len) + str_length)
37
+
38
+ (original + padding).in_blocks(64).each do |block|
39
+ w = block.unpack("L<16")
40
+
41
+ a, b, c, d = running_state
42
+ # Extraction of each 16-operation round into a loop over four elements originally
43
+ # found at https://rosettacode.org/wiki/MD4#Ruby
44
+ [0, 4, 8, 12].each do |i|
45
+ a = f(a, b, c, d, w[i]).lrot(3)
46
+ d = f(d, a, b, c, w[i+1]).lrot(7)
47
+ c = f(c, d, a, b, w[i+2]).lrot(11)
48
+ b = f(b, c, d, a, w[i+3]).lrot(19)
49
+ end
50
+ [0, 1, 2, 3].each do |i|
51
+ a = g(a, b, c, d, w[i]).lrot(3)
52
+ d = g(d, a, b, c, w[i+4]).lrot(5)
53
+ c = g(c, d, a, b, w[i+8]).lrot(9)
54
+ b = g(b, c, d, a, w[i+12]).lrot(13)
55
+ end
56
+ [0, 2, 1, 3].each do |i|
57
+ a = h(a, b, c, d, w[i]).lrot(3)
58
+ d = h(d, a, b, c, w[i+8]).lrot(9)
59
+ c = h(c, d, a, b, w[i+4]).lrot(11)
60
+ b = h(b, c, d, a, w[i+12]).lrot(15)
61
+ end
62
+
63
+ [a, b, c, d].each_with_index do |val, i|
64
+ running_state[i] = (running_state[i] + val) & 0xffffffff
65
+ end
66
+ end
67
+
68
+ running_state.pack("L<4")
69
+ end
70
+ alias_method :digest, :bindigest
71
+
72
+ private
73
+
74
+ attr_reader :original
75
+
76
+ def f(arg, x, y, z, block)
77
+ arg +
78
+ ((x & y) | (~x & z)) +
79
+ block
80
+ end
81
+
82
+ def g(arg, x, y, z, block)
83
+ arg +
84
+ ((x & y) | (x & z) | (y & z)) +
85
+ block +
86
+ 0x5a827999
87
+ end
88
+
89
+ def h(arg, x, y, z, block)
90
+ arg +
91
+ (x ^ y ^ z) +
92
+ block +
93
+ 0x6ed9eba1
94
+ end
95
+
96
+ # Equivalent to [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 ]
97
+ INITIAL_STATE = "0123456789abcdeffedcba9876543210"
98
+
99
+ def registers_from(hex_str)
100
+ raise ArgumentError.new("Argument must be a hex string") unless hex_str.hex?
101
+ raise ArgumentError.new("Argument must be 32 characters long") unless hex_str.length == 32
102
+ hex_str.from_hex.unpack("L<4")
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,218 @@
1
+ #encoding: ASCII-8BIT
2
+
3
+ # Note: 64 bit is untested
4
+ module CryptoToolchain
5
+ module Utilities
6
+ class MT19937
7
+ PARAMETERS_32 = {
8
+ w: 32, n: 624, m: 397, r: 31,
9
+ a: 0x9908b0df,
10
+ u: 11, d: 0xFFFFFFFF,
11
+ s: 7, b: 0x9d2c5680,
12
+ t: 15, c: 0xefc60000,
13
+ l: 18,
14
+ f: 1812433253
15
+ }.freeze
16
+ PARAMETERS_64 = {
17
+ w: 64, n: 312, m: 156, r: 31,
18
+ a: 0xB5026F5AA96619E9,
19
+ u: 29, d: 0x5555555555555555,
20
+ s: 17, b: 0x71D67FFFEDA60000,
21
+ t: 37, c: 0xFFF7EEE000000000,
22
+ l: 43,
23
+ f: 6364136223846793005
24
+ }.freeze
25
+
26
+ def self.from_array(arr, bits: 32, index: parameters_for(bits).fetch(:n))
27
+ mt = new(0, bits: bits)
28
+ mt.send(:state=, arr)
29
+ mt.send(:index=, index)
30
+ mt
31
+ end
32
+
33
+ def self.parameters_for(bits)
34
+ case bits
35
+ when 32
36
+ PARAMETERS_32
37
+ when 64
38
+ PARAMETERS_64
39
+ else
40
+ raise ArgumentError.new("Bits must be 32 or 64")
41
+ end
42
+ end
43
+
44
+ def initialize(seed, bits: 32)
45
+ @seed = seed
46
+ set_vars!(self.class.parameters_for(bits))
47
+ @index = n
48
+ @state = build_state!
49
+ end
50
+
51
+ def ==(other)
52
+ return false unless other.is_a?(self.class)
53
+ other.send(:state) == state && other.send(:index) == index
54
+ end
55
+
56
+ def extract
57
+ twist! if index >= n
58
+ temper(state[index])
59
+ ensure
60
+ @index += 1
61
+ end
62
+
63
+ def temper(y)
64
+ y ^= (y >> u) & d
65
+ y ^= (y << s) & b
66
+ y ^= (y << t) & c
67
+ y ^= (y >> l)
68
+ lowest_bits(y)
69
+ end
70
+
71
+ def untemper(y)
72
+ y = untemper_rshift(y, shift: l)
73
+ y = untemper_lshift(y, shift: t, mask: c)
74
+ y = untemper_lshift(y, shift: s, mask: b)
75
+ untemper_rshift(y, shift: u, mask: d)
76
+ end
77
+
78
+ private
79
+
80
+ attr_reader(*(PARAMETERS_32.keys))
81
+ attr_accessor :seed, :state, :index
82
+
83
+ # General principle:
84
+ # x ^= (x << y) is periodic.
85
+ #
86
+ # What we want to do, then, is exploit this periodicity:
87
+ # a -> b -> c -> d
88
+ # ^ v
89
+ # |------<-------|
90
+ # Where the temper function went from c -> d, we want to go d->a->b->c to untemper
91
+ # So we do the most naive thing possible, rather than the performant method below which never quite
92
+ # clicked in the ol' brain
93
+ def untemper_lshift(val, shift: , mask: 0xffffffff)
94
+ original = val
95
+ loop do
96
+ prev = val
97
+ val ^= ((val << shift) & mask)
98
+ return prev if val == original
99
+ end
100
+ end
101
+
102
+ def untemper_rshift(val, shift: , mask: 0xffffffff)
103
+ original = val
104
+ loop do
105
+ prev = val
106
+ val ^= ((val >> shift) & mask)
107
+ return prev if val == original
108
+ end
109
+ end
110
+
111
+ def defunct_untemper_step_for_posterity(y, debug: false)
112
+ # We're reversing
113
+ # y ^= (y << 7) & 0x9d2cf80
114
+ # so, take the bottom 25 bits of y, shift them over, and & that with the constant 0x9d2c5680,
115
+ # and xor the result with the top 25 bits of y. Notably, this leaves the bottom 7 bits of y
116
+ # untouched. The general idea is that we iteratively recover bits. The input shares the bottom 7
117
+ # bits with the proper output. We work in 7-bit chunks (the last chunk is only 4 bits of course),
118
+ # shifting and xor-ing (and &ing with the appropriate chunk of the mask) as we go.
119
+ #
120
+ # This algorithm never has varying periodicity, unlike the brute force method above. My current
121
+ # thought is that this is because I'm not appropriately breaking the mask up into chunks like I do
122
+ # here, but I'm not quite sure. For now, I'll stick with the naive algorithm until I have a complete
123
+ # understanding of this one.
124
+ if debug
125
+ puts " y #{y.to_bits} #{y}"
126
+ puts
127
+ puts "y<<7 #{((y<<7) & 0xffffffff).to_bits}"
128
+ puts "&with #{(0x00003f80 & b).to_bits}"
129
+ puts " = #{((y << 7) & (0x00003f80 & b)).to_bits}"
130
+ puts "xor y #{y.to_bits}"
131
+ end
132
+
133
+ y ^= (y << 7) & (0x00003f80 & b)
134
+
135
+ if debug
136
+ puts " = #{y.to_bits}"
137
+ puts
138
+ puts "y<<7 #{((y<<7) & 0xffffffff).to_bits}"
139
+ puts "&with #{(0x001fc000 & b).to_bits}"
140
+ puts " = #{((y << 7) & (0x001fc000 & b)).to_bits}"
141
+ puts "xor y #{y.to_bits}"
142
+ end
143
+
144
+ y ^= (y << 7) & (0x001fc000 & b)
145
+
146
+ if debug
147
+ puts " = #{y.to_bits}"
148
+ puts
149
+ puts "y<<7 #{((y<<7) & 0xffffffff).to_bits}"
150
+ puts "&with #{(0x0fe00000 & b).to_bits}"
151
+ puts " = #{((y << 7) & (0x0fe00000 & b)).to_bits}"
152
+ puts "xor y #{y.to_bits}"
153
+ end
154
+
155
+ y ^= (y << 7) & (0x0fe00000 & b)
156
+
157
+ if debug
158
+ puts " = #{y.to_bits}"
159
+ puts
160
+ puts "y<<7 #{((y<<7) & 0xffffffff).to_bits}"
161
+ puts "&with #{(0xf0000000 & b).to_bits}"
162
+ puts " = #{((y << 7) & (0xf0000000 & b)).to_bits}"
163
+ puts "xor y #{y.to_bits}"
164
+ end
165
+
166
+ y ^= (y << 7) & (0xf0000000 & b)
167
+
168
+ if debug
169
+ puts " = #{y.to_bits}"
170
+ puts y
171
+ end
172
+ y
173
+ end
174
+
175
+ def build_state!
176
+ _state = [seed]
177
+ for i in (1...n)
178
+ prev = _state[i - 1]
179
+ val = lowest_bits((f * (prev ^ (prev >> (w-2)) ) + i))
180
+ _state << val
181
+ end
182
+ _state
183
+ end
184
+
185
+ def twist!
186
+ for i in (0...n)
187
+ cur = state[i]
188
+ x = (cur & upper_mask) + (state[(i+1) % n] & lower_mask)
189
+ xA = x >> 1
190
+ if (x % 2) != 0
191
+ xA = xA ^ a
192
+ end
193
+ state[i] = state[(i + m) % n] ^ xA
194
+ end
195
+ @index = 0
196
+ nil
197
+ end
198
+
199
+ def lower_mask
200
+ @lower_mask ||= (1 << r) - 1
201
+ end
202
+
203
+ def upper_mask
204
+ @upper_mask ||= lowest_bits(~lower_mask)
205
+ end
206
+
207
+ def set_vars!(parameters)
208
+ parameters.each do |k, v|
209
+ instance_variable_set("@#{k}", v)
210
+ end
211
+ end
212
+
213
+ def lowest_bits(num)
214
+ num & 0xffffffff
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,95 @@
1
+ #encoding: ASCII-8BIT
2
+ module CryptoToolchain
3
+ module Utilities
4
+ class SHA1
5
+ class << self
6
+ def hexdigest(str, state: INITIAL_STATE, append_length: 0 )
7
+ CryptoToolchain::Utilities::SHA1.new(str).hexdigest(state: state, append_length: append_length)
8
+ end
9
+
10
+ def bindigest(str, state: INITIAL_STATE, append_length: 0)
11
+ CryptoToolchain::Utilities::SHA1.new(str).bindigest(state: state, append_length: append_length)
12
+ end
13
+ alias_method :digest, :bindigest
14
+
15
+ def padding(str)
16
+ num_null_pad = (56 - (str.bytesize + 1) ) % 64
17
+ 0x80.chr + (0.chr * num_null_pad) + [str.bytesize * 8].pack("Q>")
18
+ end
19
+ end
20
+
21
+ def initialize(message)
22
+ @original = message
23
+ end
24
+
25
+ def hexdigest(state: INITIAL_STATE, append_length: 0)
26
+ bindigest(state: state, append_length: append_length).unpack("H*").join
27
+ end
28
+
29
+ def bindigest(state: INITIAL_STATE, append_length: 0)
30
+ h = registers_from(state).dup
31
+
32
+ length = original.bytesize + append_length
33
+
34
+ # while (string.size % 64) != 56
35
+ num_null_pad = (56 - (length + 1) ) % 64
36
+ padding = 0x80.chr + (0.chr * num_null_pad) + [length * 8].pack("Q>")
37
+
38
+ (original + padding).in_blocks(64).each do |_block|
39
+ w = _block.unpack("L>16")
40
+ (16..79).each do |i|
41
+ w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]).lrot(1)
42
+ end
43
+
44
+ a, b, c, d, e = h
45
+
46
+ (0..79).each do |i|
47
+ func, k = f_and_k_for(i)
48
+ f = func.call(b, c, d)
49
+ temp = (a.lrot(5) + f + e + k + w[i]) & 0xffffffff
50
+ e = d
51
+ d = c
52
+ c = b.lrot(30)
53
+ b = a
54
+ a = temp
55
+ end
56
+
57
+ [a, b, c, d, e].each_with_index do |val, i|
58
+ h[i] = (h[i] + val) & 0xffffffff
59
+ end
60
+ end
61
+ h.pack("L>5")
62
+ end
63
+ alias_method :digest, :bindigest
64
+
65
+ private
66
+
67
+ attr_reader :original
68
+
69
+ F_FUNCTIONS = [
70
+ ->(b,c,d) { (b & c) | ((~b) & d) },
71
+ ->(b,c,d) { b ^ c ^ d },
72
+ ->(b,c,d) { (b & c) | (b & d) | (c & d) },
73
+ ->(b,c,d) { b ^ c ^ d },
74
+ ].freeze
75
+
76
+ K_CONSTANTS = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 ].freeze
77
+
78
+ CONSTANTS = F_FUNCTIONS.zip(K_CONSTANTS).freeze
79
+
80
+ # Equivalent to [ 0x67452301, 0xefcdaB89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ] when using registers
81
+ INITIAL_STATE = "67452301efcdab8998badcfe10325476c3d2e1f0".freeze
82
+
83
+ def registers_from(hex_str)
84
+ raise ArgumentError.new("Argument must be a hex string") unless hex_str.hex?
85
+ raise ArgumentError.new("Argument must be 40 characters long") unless hex_str.length == 40
86
+ hex_str.from_hex.unpack("L>*")
87
+ end
88
+
89
+ def f_and_k_for(i)
90
+ raise ArgumentError.new("i must be in 0..79") unless i >=0 && i <= 79
91
+ CONSTANTS[i/20]
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,9 @@
1
+ require "crypto_toolchain/utilities/mt_19937"
2
+ require "crypto_toolchain/utilities/sha1"
3
+ require "crypto_toolchain/utilities/hmac"
4
+ require "crypto_toolchain/utilities/md4"
5
+
6
+ module CryptoToolchain
7
+ module Utilities
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module CryptoToolchain
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: ASCII-8BIT
2
+
3
+ require "base64"
4
+ require "pry-byebug"
5
+ require "pp"
6
+ require "uri"
7
+ require 'json'
8
+ require 'securerandom'
9
+ require "bigdecimal"
10
+ require "crypto_toolchain/version"
11
+ require "crypto_toolchain/extensions"
12
+ require "crypto_toolchain/utilities"
13
+ require "crypto_toolchain/tools"
14
+ require "crypto_toolchain/black_boxes"
15
+ require "crypto_toolchain/diffie_hellman"
16
+ require "crypto_toolchain/srp"
17
+
18
+ module CryptoToolchain
19
+ AES_BLOCK_SIZE = 16
20
+ PRINTABLE_CHARACTERS = ((0x20..0x7e).to_a + [0x0a, 0x0d]).map(&:chr).freeze
21
+ NIST_P = 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff
22
+ NIST_G = 2
23
+ ASN1 = {
24
+ md5: "0 0\f\x06\b*\x86H\x86\xF7\r\x02\x05\x05\x00\x04\x10",
25
+ sha1: "0!0\t\x06\x05+\x0E\x03\x02\x1A\x05\x00\x04\x14",
26
+ sha256: "010\r\x06\t`\x86H\x01e\x03\x04\x02\x01\x05\x00\x04 ",
27
+ sha384: "0A0\r\x06\t`\x86H\x01e\x03\x04\x02\x02\x05\x00\x040",
28
+ sha512: "0Q0\r\x06\t`\x86H\x01e\x03\x04\x02\x03\x05\x00\x04@"
29
+ }.freeze
30
+
31
+ DSA_P = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
32
+ DSA_Q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
33
+ DSA_G = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291
34
+ end