crypto_toolchain 0.1.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.
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