sixword 0.1.0 → 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.
data/bin/sixword ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require_relative '../lib/sixword'
5
+
6
+ BaseName = File.basename($0)
7
+
8
+ def puts_err(message)
9
+ $stderr.puts(BaseName + ': ' + message)
10
+ end
11
+
12
+ def parse_args
13
+ options = {pad: true}
14
+ optparse = OptionParser.new do |opts|
15
+ opts.banner = <<-EOM
16
+ usage: #{BaseName} [OPTION]... [FILE]
17
+
18
+ Six-word encode or decode FILE, or standard input, to standard output.
19
+
20
+ The data are encoded using the 2048 word dictionary created for S/Key (tm) and
21
+ standardized by RFC 2289, RFC 1760, and RFC 1751. It also supports an optional
22
+ custom padding scheme to allow for messages that are not a multiple of 8 bytes.
23
+
24
+ With no FILE, or when FILE is -, read standard input.
25
+
26
+ #{BaseName} understands a few different styles of hexadecimal input and output.
27
+ When encoding, the input will first be decoded to binary data before being
28
+ encoded to words. When decoding, the output will be encoded in hex.
29
+
30
+
31
+ Hex styles:
32
+
33
+ lower/lowercase:
34
+ Accept a variety of inputs, but don't include whitespace in output.
35
+
36
+ Encoding:
37
+ '48:69:20:77:6f:72:6c:64' => 'Hi world' => 'ACRE ADEN INN SLID MAD PAP'
38
+ Decoding:
39
+ 'ACRE ADEN INN SLID MAD PAP' => 'Hi world' => '486920776f726c64'
40
+
41
+ finger/fingerprint:
42
+ Accept a variety of inputs, and include whitespace in output.
43
+ This is intended to look something like GPG fingerprints.
44
+
45
+ Encoding:
46
+ '4869 2077 6F72 6C64' => 'Hi world' => 'ACRE ADEN INN SLID MAP PAP'
47
+ Decoding:
48
+ 'ACRE ADEN INN SLID MAP PAP' => 'Hi world' => '4869 2077 6F72 6C64'
49
+
50
+
51
+ Options:
52
+ EOM
53
+
54
+ opts.on('-h', '--help', 'Display this message', ' ') do
55
+ $stderr.puts opts, ''
56
+ exit 0
57
+ end
58
+
59
+ #
60
+
61
+ opts.on('-d', '--decode', 'Decode data') do
62
+ options[:mode] = :decode
63
+ end
64
+
65
+ opts.on('-p', '--no-pad', "Don't use custom padding scheme", ' ') do
66
+ options[:pad] = false
67
+ end
68
+
69
+ #
70
+
71
+ opts.on('-S', '--hex-style STYLE',
72
+ 'Treat input (when encoding) or print',
73
+ 'output (when decoding) as hex') do |style|
74
+ options[:hex_style] = style
75
+ end
76
+
77
+ opts.on('-H', '--hex', 'Short for --hex-style lowercase') do
78
+ options[:hex_style] = 'lowercase'
79
+ end
80
+
81
+ opts.on('-f', '--fingerprint', 'Short for --hex-style fingerprint') do
82
+ options[:hex_style] = 'fingerprint'
83
+ end
84
+ end
85
+
86
+ optparse.parse!
87
+
88
+ case ARGV.length
89
+ when 0
90
+ filename = '-'
91
+ when 1
92
+ filename = ARGV.fetch(0)
93
+ else
94
+ $stderr.puts optparse, ''
95
+ puts_err "extra operand #{ARGV.fetch(1).inspect}"
96
+ exit 1
97
+ end
98
+
99
+ begin
100
+ runner = Sixword::CLI.new(filename, options)
101
+ runner.run!
102
+ rescue Sixword::CLI::CLIError => err
103
+ puts_err err.message
104
+ exit 2
105
+ rescue Sixword::InvalidParity => err
106
+ puts_err err.message
107
+ exit 3
108
+ rescue Sixword::UnknownWord => err
109
+ puts_err err.message
110
+ exit 4
111
+ rescue Sixword::InvalidWord => err
112
+ puts_err err.message
113
+ exit 5
114
+ rescue Sixword::InputError => err
115
+ puts_err err.message
116
+ exit 10
117
+ rescue Interrupt
118
+ $stderr.puts
119
+ exit 130 # not actually the same as signalled exit, but oh well
120
+ end
121
+ end
122
+
123
+ parse_args
data/lib/sixword.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require_relative 'sixword/cli'
2
+ require_relative 'sixword/hex'
1
3
  require_relative 'sixword/lib'
2
4
  require_relative 'sixword/version'
3
5
  require_relative 'sixword/words'
@@ -44,6 +46,10 @@ module Sixword
44
46
  words_per_slice = options.fetch(:words_per_slice)
45
47
  pad = options.fetch(:pad)
46
48
 
49
+ unless byte_string
50
+ raise ArgumentError.new("byte_string is falsy")
51
+ end
52
+
47
53
  unless block_given?
48
54
  return Enumerator.new(self, :encode_iter, byte_string, options)
49
55
  end
@@ -107,14 +113,4 @@ module Sixword
107
113
  def self.pad_decode(string_or_words)
108
114
  decode(string_or_words, padding_ok: true)
109
115
  end
110
-
111
- def self.hex_string_to_byte_string(hex_string)
112
- # strip whitespace, make sure it's valid hex
113
- hex_string = hex_string.gsub(/\s+/, '')
114
- if hex_string =~ /[^a-fA-F0-9]/
115
- raise ArgumentError.new("Invalid value for hex: #{hex_string.inspect}")
116
- end
117
-
118
- [hex_string].pack('H*')
119
- end
120
116
  end
@@ -0,0 +1,202 @@
1
+ module Sixword
2
+ class CLI
3
+ class CLIError < StandardError; end
4
+
5
+ attr_reader :filename, :options, :stream, :mode
6
+
7
+ def initialize(filename, options)
8
+ @filename = filename
9
+ @options = {mode: :encode, pad: false}.merge(options)
10
+
11
+ if filename == '-'
12
+ # dup stdin and put it into binary mode
13
+ @stream = $stdin.dup
14
+ @stream.binmode
15
+ else
16
+ # read in binary mode even on unix so ruby yields binary encoding
17
+ @stream = File.open(filename, 'rb')
18
+ end
19
+
20
+
21
+ @mode = @options.fetch(:mode)
22
+ unless [:encode, :decode].include?(mode)
23
+ raise ArgumentError.new("Invalid mode: #{mode.inspect}")
24
+ end
25
+ end
26
+
27
+ def pad?
28
+ options.fetch(:pad)
29
+ end
30
+
31
+ def encoding?
32
+ mode == :encode
33
+ end
34
+
35
+ def hex_style
36
+ options[:hex_style]
37
+ end
38
+
39
+ def print_hex(data, chunk_index, cols=80)
40
+ case hex_style
41
+ when 'lower', 'lowercase'
42
+ # encode to lowercase hex with no newlines
43
+ print Sixword::Hex.encode(data)
44
+ when 'finger', 'fingerprint'
45
+ # encode to GPG fingerprint like hex with newlines
46
+ newlines_every = cols / 5
47
+ if chunk_index != 0
48
+ if chunk_index % newlines_every == 0
49
+ print "\n"
50
+ else
51
+ print ' '
52
+ end
53
+ end
54
+ print Sixword::Hex.encode_fingerprint(data)
55
+ when 'colon', 'colons'
56
+ # encode to SSL/SSH fingerprint like hex with colons
57
+ print ':' unless chunk_index == 0
58
+ print Sixword::Hex.encode_colons(data)
59
+ end
60
+ end
61
+
62
+ def run!
63
+ if encoding?
64
+ do_encode! do |encoded|
65
+ puts encoded
66
+ end
67
+ else
68
+ chunk_index = 0
69
+ do_decode! do |decoded|
70
+ if hex_style
71
+ print_hex(decoded, chunk_index)
72
+ chunk_index += 1
73
+ else
74
+ print decoded
75
+ end
76
+ end
77
+
78
+ # add trailing newline for hex output
79
+ puts if hex_style
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def do_decode!
86
+ unless block_given?
87
+ raise ArgumentError.new("block is required")
88
+ end
89
+
90
+ arr = []
91
+ read_input_by_6_words do |arr|
92
+ yield Sixword.decode(arr, padding_ok: pad?)
93
+ end
94
+ end
95
+
96
+ def do_encode!
97
+ process_encode_input do |chunk|
98
+ Sixword.encode_iter(chunk, words_per_slice:6, pad:pad?) do |encoded|
99
+ yield encoded
100
+ end
101
+ end
102
+ end
103
+
104
+ def process_encode_input
105
+ unless block_given?
106
+ raise ArgumentError.new("block is required")
107
+ end
108
+
109
+ if hex_style
110
+ # yield data in chunks from accumulate_hex_input until EOF
111
+ accumulate_hex_input do |hex|
112
+ begin
113
+ data = Sixword::Hex.decode(hex)
114
+ rescue ArgumentError => err
115
+ # expose hex decoding failures to user
116
+ raise CLIError.new(err.message)
117
+ else
118
+ yield data
119
+ end
120
+ end
121
+ else
122
+ # yield data 8 bytes at a time until EOF
123
+ while true
124
+ buf = stream.read(8)
125
+ if buf
126
+ yield buf
127
+ else
128
+ # EOF
129
+ break
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ # Yield data 6 words at a time until EOF
136
+ def read_input_by_6_words
137
+ block_size = 2048
138
+ word_arr = []
139
+
140
+ while true
141
+ buf = stream.read(block_size)
142
+ if buf.nil?
143
+ break #EOF
144
+ end
145
+
146
+ buf.scan(/\S+/) do |word|
147
+ word_arr << word
148
+
149
+ # return the array if we have accumulated 6 words
150
+ if word_arr.length == 6
151
+ yield word_arr
152
+ word_arr.clear
153
+ end
154
+ end
155
+ end
156
+
157
+ # yield whatever we have left, if anything
158
+ if !word_arr.empty?
159
+ yield word_arr
160
+ end
161
+ end
162
+
163
+ def accumulate_hex_input
164
+ unless block_given?
165
+ raise ArgumentError.new("must pass block")
166
+ end
167
+
168
+ # these are actually treated the same at the moment
169
+ case hex_style
170
+ when 'lower', 'lowercase'
171
+ when 'finger', 'fingerprint'
172
+ else
173
+ raise CLIError.new("unknown hex style: #{hex_style.inspect}")
174
+ end
175
+
176
+ while true
177
+ buf = ''
178
+
179
+ # try to accumulate 8 bytes (16 chars) before yielding the hex
180
+ while buf.length < 16
181
+ char = stream.getc
182
+ if char.nil?
183
+ # EOF, so yield whatever we have if it's non-empty
184
+ yield buf unless buf.empty?
185
+ return
186
+ end
187
+
188
+ if Sixword::Hex.valid_hex?(char)
189
+ buf << char
190
+ next
191
+ elsif Sixword::Hex.strip_char?(char)
192
+ next
193
+ end
194
+
195
+ raise CLIError.new("invalid hex character: #{char.inspect}")
196
+ end
197
+
198
+ yield buf
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,49 @@
1
+ module Sixword
2
+ module Hex
3
+ HexValid = /\A[a-fA-F0-9]+\z/
4
+ HexStrip = /[\s:.-]+/
5
+
6
+ def self.valid_hex?(string)
7
+ !!(string =~ HexValid)
8
+ end
9
+
10
+ def self.strip_char?(char)
11
+ unless char.length == 1
12
+ raise ArgumentError.new("Must pass single character string")
13
+ end
14
+ !!(char =~ HexStrip)
15
+ end
16
+
17
+ def self.encode(bytes)
18
+ bytes.unpack('H*').fetch(0)
19
+ end
20
+
21
+ def self.encode_slice(bytes, slice, delimiter)
22
+ encode(bytes).each_char.each_slice(slice).map(&:join).join(delimiter)
23
+ end
24
+
25
+ def self.encode_fingerprint(bytes)
26
+ encode_slice(bytes, 4, ' ').upcase
27
+ end
28
+
29
+ def self.encode_colons(bytes)
30
+ encode_slice(bytes, 2, ':')
31
+ end
32
+
33
+ def self.decode(hex_string, strip_chars=true)
34
+ if strip_chars
35
+ hex_string = hex_string.gsub(HexStrip, '')
36
+ end
37
+
38
+ unless valid_hex?(hex_string)
39
+ raise ArgumentError.new("Invalid value for hex: #{hex_string.inspect}")
40
+ end
41
+
42
+ unless hex_string.length % 2 == 0
43
+ raise ArgumentError.new("Odd length hex: #{hex_string.inspect}")
44
+ end
45
+
46
+ [hex_string].pack('H*')
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module Sixword
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,124 @@
1
+ require_relative '../rspec_helper'
2
+
3
+ describe Sixword::Hex do
4
+ TestCases = {
5
+ "\x73\xe2\x16\xb5\x36\x3f\x23\x77" => [
6
+ "73e216b5363f2377",
7
+ "73E2 16B5 363F 2377",
8
+ "73:e2:16:b5:36:3f:23:77",
9
+ ],
10
+ "\xfe\xfb\x90\x3d\x12\x59\x36\xee" => [
11
+ "fefb903d125936ee",
12
+ "FEFB 903D 1259 36EE",
13
+ "fe:fb:90:3d:12:59:36:ee",
14
+ ],
15
+ "\x41\x2e\xb9\x92\xe8\x34\xe9\x90" => [
16
+ "412eb992e834e990",
17
+ "412E B992 E834 E990",
18
+ "41:2e:b9:92:e8:34:e9:90",
19
+ ],
20
+ "\x76\x55\x69\x21\x5c\x74\x1b\xda" => [
21
+ "765569215c741bda",
22
+ "7655 6921 5C74 1BDA",
23
+ "76:55:69:21:5c:74:1b:da",
24
+ ],
25
+ "\x62\xec\x83\xdf\x92\x2f\x8a\x7d" => [
26
+ "62ec83df922f8a7d",
27
+ "62EC 83DF 922F 8A7D",
28
+ "62:ec:83:df:92:2f:8a:7d",
29
+ ],
30
+ "\xe2\x65\x2a\x67\xe8\x32\x41\x19" => [
31
+ "e2652a67e8324119",
32
+ "E265 2A67 E832 4119",
33
+ "e2:65:2a:67:e8:32:41:19",
34
+ ],
35
+ "\xd2\x6b\x73\x44\x17\xad\x7f\x93" => [
36
+ "d26b734417ad7f93",
37
+ "D26B 7344 17AD 7F93",
38
+ "d2:6b:73:44:17:ad:7f:93",
39
+ ],
40
+ "\xc5\x3c\xab\x0e\x0c\xf5\x2a\xe8" => [
41
+ "c53cab0e0cf52ae8",
42
+ "C53C AB0E 0CF5 2AE8",
43
+ "c5:3c:ab:0e:0c:f5:2a:e8",
44
+ ],
45
+
46
+ "\x34\x59\xa1\x13\x01\x94\xc3\xf6\xe8\xa9\xec\xf6\x44\xb5\xba\x41" => [
47
+ "3459a1130194c3f6e8a9ecf644b5ba41",
48
+ "3459 A113 0194 C3F6 E8A9 ECF6 44B5 BA41",
49
+ "34:59:a1:13:01:94:c3:f6:e8:a9:ec:f6:44:b5:ba:41",
50
+ ],
51
+ "\x8e\x93\x05\x97\xec\x03\x41\x9d\x13\x1c\x05\x7a\x6a\xa9\xc5\x73" => [
52
+ "8e930597ec03419d131c057a6aa9c573",
53
+ "8E93 0597 EC03 419D 131C 057A 6AA9 C573",
54
+ "8e:93:05:97:ec:03:41:9d:13:1c:05:7a:6a:a9:c5:73",
55
+ ],
56
+ "\xc6\xb4\x10\xe9\x26\x71\x1a\x7c\x4f\x67\x98\xf9\x92\x0e\xdf\x4c" => [
57
+ "c6b410e926711a7c4f6798f9920edf4c",
58
+ "C6B4 10E9 2671 1A7C 4F67 98F9 920E DF4C",
59
+ "c6:b4:10:e9:26:71:1a:7c:4f:67:98:f9:92:0e:df:4c",
60
+ ],
61
+ "\x83\x6a\x14\xd4\x0b\xf0\xc6\xed\xb5\xa8\x1f\xb7\xc0\xcc\xc5\x22" => [
62
+ "836a14d40bf0c6edb5a81fb7c0ccc522",
63
+ "836A 14D4 0BF0 C6ED B5A8 1FB7 C0CC C522",
64
+ "83:6a:14:d4:0b:f0:c6:ed:b5:a8:1f:b7:c0:cc:c5:22",
65
+ ],
66
+ "\x26\xb8\xdf\xd0\x00\x35\x98\xff\xec\x95\xc3\xa1\x1e\x64\x97\x08" => [
67
+ "26b8dfd0003598ffec95c3a11e649708",
68
+ "26B8 DFD0 0035 98FF EC95 C3A1 1E64 9708",
69
+ "26:b8:df:d0:00:35:98:ff:ec:95:c3:a1:1e:64:97:08",
70
+ ],
71
+ "\xd9\xff\xcb\x22\xe5\x2e\x92\x0c\xfd\x45\xcb\x0c\x18\x18\x08\x10" => [
72
+ "d9ffcb22e52e920cfd45cb0c18180810",
73
+ "D9FF CB22 E52E 920C FD45 CB0C 1818 0810",
74
+ "d9:ff:cb:22:e5:2e:92:0c:fd:45:cb:0c:18:18:08:10",
75
+ ],
76
+ "\x73\x13\xc0\x90\x96\xd1\x5b\xbd\x10\x04\x69\x34\xf0\xbe\xf9\x60" => [
77
+ "7313c09096d15bbd10046934f0bef960",
78
+ "7313 C090 96D1 5BBD 1004 6934 F0BE F960",
79
+ "73:13:c0:90:96:d1:5b:bd:10:04:69:34:f0:be:f9:60",
80
+ ],
81
+ "\x18\x3b\xa9\x75\x54\x57\xf9\x5d\x00\x13\x5e\x3c\x87\x9f\x1c\x17" => [
82
+ "183ba9755457f95d00135e3c879f1c17",
83
+ "183B A975 5457 F95D 0013 5E3C 879F 1C17",
84
+ "18:3b:a9:75:54:57:f9:5d:00:13:5e:3c:87:9f:1c:17",
85
+ ],
86
+ }
87
+
88
+ it 'should decode and encode random hex strings correctly' do
89
+ TestCases.each do |binary, hexes|
90
+ lower, finger, colons = hexes
91
+ Sixword::Hex.encode(binary).should == lower
92
+ Sixword::Hex.decode(lower).should == binary
93
+ end
94
+ end
95
+
96
+ it 'should decode and encode random hex fingerprints correctly' do
97
+ TestCases.each do |binary, hexes|
98
+ lower, finger, colons = hexes
99
+ Sixword::Hex.encode_fingerprint(binary).should == finger
100
+ Sixword::Hex.decode(finger).should == binary
101
+ end
102
+ end
103
+
104
+ it 'should decode and encode random colon hexes correctly' do
105
+ TestCases.each do |binary, hexes|
106
+ lower, finger, colons = hexes
107
+ Sixword::Hex.encode_colons(binary).should == colons
108
+ Sixword::Hex.decode(colons).should == binary
109
+ end
110
+ end
111
+
112
+ it 'should accept all valid hex characters' do
113
+ Sixword::Hex.valid_hex?('abcdefABCDEF0123456789').should == true
114
+ end
115
+
116
+ it 'should reject invalid hex characters' do
117
+ ('g'..'z').each do |c|
118
+ Sixword::Hex.valid_hex?(c).should == false
119
+ end
120
+ ('G'..'Z').each do |c|
121
+ Sixword::Hex.valid_hex?(c).should == false
122
+ end
123
+ end
124
+ end
data/spec/sixword_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe Sixword do
5
5
  Sixword::TestVectors::HexTests.each do |section, tests|
6
6
  tests.each do |hex, sentence|
7
7
  words = sentence.split
8
- byte_string = Sixword.hex_string_to_byte_string(hex)
8
+ byte_string = Sixword::Hex.decode(hex)
9
9
  debug_puts "Encode 0x#{hex} => #{words.inspect}"
10
10
  Sixword.encode(byte_string).should == words
11
11
  end
@@ -16,7 +16,7 @@ describe Sixword do
16
16
  Sixword::TestVectors::HexTests.each do |section, tests|
17
17
  tests.each do |hex, sentence|
18
18
  words = sentence.split
19
- byte_string = Sixword.hex_string_to_byte_string(hex)
19
+ byte_string = Sixword::Hex.decode(hex)
20
20
  debug_puts "Decode #{words.inspect} => 0x#{hex}"
21
21
  Sixword.decode(words).should == byte_string
22
22
  end
@@ -49,7 +49,7 @@ describe Sixword do
49
49
  Sixword::TestVectors::HexTests.fetch('rfc 1751').each do |hex, sentence|
50
50
  # group into 6-word sentences
51
51
  sentences = sentence.split.each_slice(6).map {|s| s.join(' ')}
52
- byte_string = Sixword.hex_string_to_byte_string(hex)
52
+ byte_string = Sixword::Hex.decode(hex)
53
53
  debug_puts "Encoding #{hex.inspect} to sentences"
54
54
  debug_puts " => #{sentences.inspect}"
55
55
  Sixword.encode_to_sentences(byte_string).should == sentences
@@ -71,7 +71,7 @@ describe Sixword do
71
71
  "6C617A7920646F672E" =>
72
72
  "The quick brown fox jumps over the lazy dog.",
73
73
  }.each do |hex_string, byte_string|
74
- Sixword.hex_string_to_byte_string(hex_string).should == byte_string
74
+ Sixword::Hex.decode(hex_string).should == byte_string
75
75
  end
76
76
  end
77
77
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sixword
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-26 00:00:00.000000000 Z
12
+ date: 2013-09-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -68,7 +68,8 @@ description: ! " Sixword implements the 6-word binary encoding created for S/
68
68
  Word List, Diceware, Base64, Base32\n"
69
69
  email:
70
70
  - abrody@abrody.com
71
- executables: []
71
+ executables:
72
+ - sixword
72
73
  extensions: []
73
74
  extra_rdoc_files: []
74
75
  files:
@@ -77,12 +78,16 @@ files:
77
78
  - LICENSE.txt
78
79
  - README.md
79
80
  - Rakefile
81
+ - bin/sixword
80
82
  - lib/sixword.rb
83
+ - lib/sixword/cli.rb
84
+ - lib/sixword/hex.rb
81
85
  - lib/sixword/lib.rb
82
86
  - lib/sixword/version.rb
83
87
  - lib/sixword/words.rb
84
88
  - sixword.gemspec
85
89
  - spec/rspec_helper.rb
90
+ - spec/sixword/hex_spec.rb
86
91
  - spec/sixword/lib_spec.rb
87
92
  - spec/sixword_spec.rb
88
93
  - spec/test_vectors.rb
@@ -101,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
106
  version: '0'
102
107
  segments:
103
108
  - 0
104
- hash: 2348163145907655780
109
+ hash: -1062992431278592122
105
110
  required_rubygems_version: !ruby/object:Gem::Requirement
106
111
  none: false
107
112
  requirements:
@@ -110,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
115
  version: '0'
111
116
  segments:
112
117
  - 0
113
- hash: 2348163145907655780
118
+ hash: -1062992431278592122
114
119
  requirements: []
115
120
  rubyforge_project:
116
121
  rubygems_version: 1.8.23
@@ -119,6 +124,7 @@ specification_version: 3
119
124
  summary: Implementation of RFC 2289 compatible 6-word encoding
120
125
  test_files:
121
126
  - spec/rspec_helper.rb
127
+ - spec/sixword/hex_spec.rb
122
128
  - spec/sixword/lib_spec.rb
123
129
  - spec/sixword_spec.rb
124
130
  - spec/test_vectors.rb