bitcoinrb 0.2.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +3 -2
  4. data/README.md +7 -6
  5. data/bitcoinrb.gemspec +4 -4
  6. data/exe/bitcoinrbd +5 -0
  7. data/lib/bitcoin.rb +33 -1
  8. data/lib/bitcoin/bip85_entropy.rb +111 -0
  9. data/lib/bitcoin/block_header.rb +2 -0
  10. data/lib/bitcoin/chain_params.rb +0 -8
  11. data/lib/bitcoin/chainparams/regtest.yml +1 -1
  12. data/lib/bitcoin/chainparams/testnet.yml +1 -1
  13. data/lib/bitcoin/constants.rb +3 -10
  14. data/lib/bitcoin/descriptor.rb +147 -0
  15. data/lib/bitcoin/ext.rb +5 -0
  16. data/lib/bitcoin/ext/json_parser.rb +46 -0
  17. data/lib/bitcoin/ext_key.rb +19 -4
  18. data/lib/bitcoin/key.rb +9 -5
  19. data/lib/bitcoin/key_path.rb +12 -5
  20. data/lib/bitcoin/message.rb +7 -0
  21. data/lib/bitcoin/message/base.rb +1 -0
  22. data/lib/bitcoin/message/cf_parser.rb +16 -0
  23. data/lib/bitcoin/message/cfcheckpt.rb +36 -0
  24. data/lib/bitcoin/message/cfheaders.rb +40 -0
  25. data/lib/bitcoin/message/cfilter.rb +35 -0
  26. data/lib/bitcoin/message/get_cfcheckpt.rb +29 -0
  27. data/lib/bitcoin/message/get_cfheaders.rb +24 -0
  28. data/lib/bitcoin/message/get_cfilters.rb +25 -0
  29. data/lib/bitcoin/message/network_addr.rb +31 -12
  30. data/lib/bitcoin/message/version.rb +14 -22
  31. data/lib/bitcoin/mnemonic.rb +5 -5
  32. data/lib/bitcoin/network/peer.rb +12 -11
  33. data/lib/bitcoin/network/peer_discovery.rb +3 -1
  34. data/lib/bitcoin/node/cli.rb +14 -10
  35. data/lib/bitcoin/node/spv.rb +1 -1
  36. data/lib/bitcoin/out_point.rb +14 -7
  37. data/lib/bitcoin/payment_code.rb +92 -0
  38. data/lib/bitcoin/psbt.rb +3 -1
  39. data/lib/bitcoin/psbt/input.rb +7 -16
  40. data/lib/bitcoin/psbt/tx.rb +18 -12
  41. data/lib/bitcoin/rpc/bitcoin_core_client.rb +22 -12
  42. data/lib/bitcoin/rpc/request_handler.rb +3 -3
  43. data/lib/bitcoin/script/script.rb +18 -10
  44. data/lib/bitcoin/script/script_interpreter.rb +3 -5
  45. data/lib/bitcoin/secp256k1.rb +1 -0
  46. data/lib/bitcoin/secp256k1/rfc6979.rb +43 -0
  47. data/lib/bitcoin/secp256k1/ruby.rb +4 -35
  48. data/lib/bitcoin/slip39.rb +93 -0
  49. data/lib/bitcoin/slip39/share.rb +122 -0
  50. data/lib/bitcoin/slip39/sss.rb +245 -0
  51. data/lib/bitcoin/slip39/wordlist/english.txt +1024 -0
  52. data/lib/bitcoin/store.rb +2 -1
  53. data/lib/bitcoin/store/chain_entry.rb +1 -0
  54. data/lib/bitcoin/store/db/level_db.rb +2 -2
  55. data/lib/bitcoin/store/utxo_db.rb +226 -0
  56. data/lib/bitcoin/tx.rb +6 -10
  57. data/lib/bitcoin/tx_in.rb +4 -5
  58. data/lib/bitcoin/util.rb +29 -1
  59. data/lib/bitcoin/version.rb +1 -1
  60. data/lib/bitcoin/wallet.rb +1 -0
  61. data/lib/bitcoin/wallet/account.rb +1 -0
  62. data/lib/bitcoin/wallet/base.rb +3 -3
  63. data/lib/bitcoin/wallet/db.rb +1 -1
  64. data/lib/bitcoin/wallet/master_key.rb +1 -0
  65. data/lib/bitcoin/wallet/utxo.rb +37 -0
  66. metadata +45 -26
@@ -0,0 +1,122 @@
1
+ module Bitcoin
2
+ module SLIP39
3
+
4
+ # Share of Shamir's Secret Sharing Scheme
5
+ class Share
6
+
7
+ attr_accessor :id # 15 bits, Integer
8
+ attr_accessor :iteration_exp # 5 bits, Integer
9
+ attr_accessor :group_index # 4 bits, Integer
10
+ attr_accessor :group_threshold # 4 bits, Integer
11
+ attr_accessor :group_count # 4 bits, Integer
12
+ attr_accessor :member_index # 4 bits, Integer
13
+ attr_accessor :member_threshold # 4 bits, Integer
14
+ attr_accessor :value # 8n bits, hex string.
15
+ attr_accessor :checksum # 30 bits, Integer
16
+
17
+ # Recover Share from the mnemonic words
18
+ # @param [Array{String}] words the mnemonic words
19
+ # @return [Bitcoin::SLIP39::Share] a share
20
+ def self.from_words(words)
21
+ raise ArgumentError, 'Mnemonics should be an array of strings' unless words.is_a?(Array)
22
+ indices = words.map do |word|
23
+ index = Bitcoin::SLIP39::WORDS.index(word.downcase)
24
+ raise IndexError, 'word not found in words list.' unless index
25
+ index
26
+ end
27
+
28
+ raise ArgumentError, 'Invalid mnemonic length.' if indices.size < MIN_MNEMONIC_LENGTH_WORDS
29
+ raise ArgumentError, 'Invalid mnemonic checksum.' unless verify_rs1024_checksum(indices)
30
+
31
+ padding_length = (RADIX_BITS * (indices.size - METADATA_LENGTH_WORDS)) % 16
32
+ raise ArgumentError, 'Invalid mnemonic length.' if padding_length > 8
33
+ data = indices.map{|i|i.to_s(2).rjust(10, '0')}.join
34
+
35
+ s = self.new
36
+ s.id = data[0...ID_LENGTH_BITS].to_i(2)
37
+ s.iteration_exp = data[ID_LENGTH_BITS...(ID_LENGTH_BITS + ITERATION_EXP_LENGTH_BITS)].to_i(2)
38
+ s.group_index = data[20...24].to_i(2)
39
+ s.group_threshold = data[24...28].to_i(2) + 1
40
+ s.group_count = data[28...32].to_i(2) + 1
41
+ raise ArgumentError, "Invalid mnemonic. Group threshold(#{s.group_threshold}) cannot be greater than group count(#{s.group_count})." if s.group_threshold > s.group_count
42
+ s.member_index = data[32...36].to_i(2)
43
+ s.member_threshold = data[36...40].to_i(2) + 1
44
+ value_length = data.length - 70
45
+ start_index = 40 + padding_length
46
+ end_index = start_index + value_length - padding_length
47
+ padding_value = data[40...(40 + padding_length)]
48
+ raise ArgumentError, "Invalid mnemonic. padding must only zero." unless padding_value.to_i(2) == 0
49
+ s.value = data[start_index...end_index].to_i(2).to_even_length_hex
50
+ s.checksum = data[(40 + value_length)..-1].to_i(2)
51
+ s
52
+ end
53
+
54
+ # Generate mnemonic words
55
+ # @return [Array[String]] array of mnemonic word.
56
+ def to_words
57
+ indices = build_word_indices
58
+ indices.map{|index| Bitcoin::SLIP39::WORDS[index]}
59
+ end
60
+
61
+ # Calculate checksum using current fields
62
+ # @return [Integer] checksum
63
+ def calculate_checksum
64
+ indices = build_word_indices(false)
65
+ create_rs1024_checksum(indices).map{|i|i.to_bits(10)}.join.to_i(2)
66
+ end
67
+
68
+ def self.rs1024_polymod(values)
69
+ gen = [0xe0e040, 0x1c1c080, 0x3838100, 0x7070200, 0xe0e0009, 0x1c0c2412, 0x38086c24, 0x3090fc48, 0x21b1f890, 0x3f3f120]
70
+ chk = 1
71
+ values.each do |v|
72
+ b = (chk >> 20)
73
+ chk = (chk & 0xfffff) << 10 ^ v
74
+ 10.times do |i|
75
+ chk ^= (((b >> i) & 1 == 1) ? gen[i] : 0)
76
+ end
77
+ end
78
+ chk
79
+ end
80
+
81
+ private
82
+
83
+ # Create word indices from this share.
84
+ # @param [Boolean] include_checksum whether include checksum when creating indices.
85
+ # @param [Array[Integer]] the array of index
86
+ def build_word_indices(include_checksum = true)
87
+ s = id.to_bits(ID_LENGTH_BITS)
88
+ s << iteration_exp.to_bits(ITERATION_EXP_LENGTH_BITS)
89
+ s << group_index.to_bits(4)
90
+ s << (group_threshold - 1).to_bits(4)
91
+ s << (group_count - 1).to_bits(4)
92
+ raise StandardError, "Group threshold(#{group_threshold}) cannot be greater than group count(#{group_count})." if group_threshold > group_count
93
+ s << member_index.to_bits(4)
94
+ s << (member_threshold - 1).to_bits(4)
95
+ value_length = value.to_i(16).bit_length
96
+ padding_length = RADIX_BITS - (value_length % RADIX_BITS)
97
+ s << value.to_i(16).to_bits(value_length + padding_length)
98
+ s << checksum.to_bits(30) if include_checksum
99
+ s.chars.each_slice(10).map{|index| index.join.to_i(2)}
100
+ end
101
+
102
+ # Verify RS1024 checksum
103
+ # @param [Array[Integer] data the array of mnemonic word index
104
+ # @return [Boolean] verify result
105
+ def self.verify_rs1024_checksum(data)
106
+ rs1024_polymod(CUSTOMIZATION_STRING + data) == 1
107
+ end
108
+
109
+ # Create RS1024 checksum
110
+ # @param [Array[Integer] data the array of mnemonic word index without checksum
111
+ # @return [Array[Integer]] the array of checksum integer
112
+ def create_rs1024_checksum(data)
113
+ values = CUSTOMIZATION_STRING + data + Array.new(CHECKSUM_LENGTH_WORDS, 0)
114
+ polymod = Bitcoin::SLIP39::Share.rs1024_polymod(values) ^ 1
115
+ CHECKSUM_LENGTH_WORDS.times.to_a.reverse.map {|i|(polymod >> (10 * i)) & 1023 }
116
+ end
117
+
118
+ private_class_method :verify_rs1024_checksum
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,245 @@
1
+ require 'securerandom'
2
+
3
+ module Bitcoin
4
+ module SLIP39
5
+
6
+ # Shamir's Secret Sharing
7
+ class SSS
8
+
9
+ include Bitcoin::Util
10
+ extend Bitcoin::Util
11
+
12
+ # Create SSS shares.
13
+ #
14
+ # [Usage]
15
+ # 4 groups shares.
16
+ # = two for Alice
17
+ # = one for friends(required 3 of her 5 friends) and
18
+ # = one for family members(required 2 of her 6 family)
19
+ #
20
+ # Two of these group shares are required to reconstruct the master secret.
21
+ # groups = [1, 1], [1, 1], [3, 5], [2, 6]
22
+ #
23
+ # group_shares = Bitcoin::SLIP39::SSS.setup_shares(group_threshold: 2, groups: groups, secret: 'secret with hex format', passphrase: 'xxx')
24
+ # return 4 group array of Bitcoin::SLIP39::Share
25
+ #
26
+ # Get each share word
27
+ # groups[0][1].to_words
28
+ # => ["shadow", "pistol", "academic", "always", "adequate", "wildlife", "fancy", "gross", "oasis", "cylinder", "mustang", "wrist", "rescue", "view", "short", "owner", "flip", "making", "coding", "armed"]
29
+ #
30
+ # @param [Array[Array[Integer, Integer]]] groups
31
+ # @param [Integer] group_threshold threshold number of group shares required to reconstruct the master secret.
32
+ # @param [Integer] exp Iteration exponent. default is 0.
33
+ # @param [String] secret master secret with hex format.
34
+ # @param [String] passphrase the passphrase used for encryption/decryption.
35
+ # @return [Array[Array[Bitcoin::SLIP39::Share]]] array of group shares.
36
+ def self.setup_shares(groups: [], group_threshold: nil, exp: 0, secret: nil, passphrase: '')
37
+ raise ArgumentError, 'Groups is empty.' if groups.empty?
38
+ raise ArgumentError, 'Group threshold must be greater than 0.' if group_threshold.nil? || group_threshold < 1
39
+ raise ArgumentError, 'Master secret does not specified.' unless secret
40
+ raise ArgumentError, "The length of the master secret (#{secret.htb.bytesize} bytes) must be at least #{MIN_STRENGTH_BITS / 8} bytes." if (secret.htb.bytesize * 8) < MIN_STRENGTH_BITS
41
+ raise ArgumentError, 'The length of the master secret in bytes must be an even number.' unless secret.bytesize.even?
42
+ raise ArgumentError, 'The passphrase must contain only printable ASCII characters (code points 32-126).' unless passphrase.ascii_only?
43
+ raise ArgumentError, "The requested group threshold (#{group_threshold}) must not exceed the number of groups (#{groups.length})." if group_threshold > groups.length
44
+ groups.each do |threshold, count|
45
+ raise ArgumentError, 'Group threshold must be greater than 0.' if threshold.nil? || threshold < 1
46
+ raise ArgumentError, "The requested member threshold (#{threshold}) must not exceed the number of share (#{count})." if threshold > count
47
+ raise ArgumentError, "Creating multiple member shares with member threshold 1 is not allowed. Use 1-of-1 member sharing instead." if threshold == 1 && count > 1
48
+ end
49
+
50
+ id = SecureRandom.random_number(32767) # 32767 is max number for 15 bits.
51
+ ems = encrypt(secret, passphrase, exp, id)
52
+
53
+ group_shares = split_secret(group_threshold, groups.length, ems)
54
+
55
+ shares = group_shares.map.with_index do |s, i|
56
+ group_index, group_share = s[0], s[1]
57
+ member_threshold, member_count = groups[i][0], groups[i][1]
58
+ shares = split_secret(member_threshold, member_count, group_share)
59
+ shares.map do |member_index, member_share|
60
+ share = Bitcoin::SLIP39::Share.new
61
+ share.id = id
62
+ share.iteration_exp = exp
63
+ share.group_index = group_index
64
+ share.group_threshold = group_threshold
65
+ share.group_count = groups.length
66
+ share.member_index = member_index
67
+ share.member_threshold = member_threshold
68
+ share.value = member_share
69
+ share.checksum = share.calculate_checksum
70
+ share
71
+ end
72
+ end
73
+ shares
74
+ end
75
+
76
+ # recovery master secret form shares.
77
+ #
78
+ # [Usage]
79
+ # shares: An array of shares required for recovery.
80
+ # master_secret = Bitcoin::SLIP39::SSS.recover_secret(shares, passphrase: 'xxx')
81
+ #
82
+ # @param [Array[Bitcoin::SLIP30::Share]] shares an array of shares.
83
+ # @param [String] passphrase the passphrase using decrypt master secret.
84
+ # @return [String] a master secret.
85
+ def self.recover_secret(shares, passphrase: '')
86
+ raise ArgumentError, 'share is empty.' if shares.nil? || shares.empty?
87
+ groups = {}
88
+ id = shares[0].id
89
+ exp = shares[0].iteration_exp
90
+ group_threshold = shares.first.group_threshold
91
+ group_count = shares.first.group_count
92
+
93
+ shares.each do |share|
94
+ raise ArgumentError, 'Invalid set of shares. All shares must have the same id.' unless id == share.id
95
+ raise ArgumentError, 'Invalid set of shares. All shares must have the same group threshold.' unless group_threshold == share.group_threshold
96
+ raise ArgumentError, 'Invalid set of shares. All shares must have the same group count.' unless group_count == share.group_count
97
+ raise ArgumentError, 'Invalid set of shares. All Shares must have the same iteration exponent.' unless exp == share.iteration_exp
98
+ groups[share.group_index] ||= []
99
+ groups[share.group_index] << share
100
+ end
101
+
102
+ group_shares = {}
103
+ groups.each do |group_index, shares|
104
+ member_threshold = shares.first.member_threshold
105
+ raise ArgumentError, "Wrong number of mnemonics. Threshold is #{member_threshold}, but share count is #{shares.length}" if shares.length < member_threshold
106
+ if shares.length == 1 && member_threshold == 1
107
+ group_shares[group_index] = shares.first.value
108
+ else
109
+ value_length = shares.first.value.length
110
+ x_coordinates = []
111
+ shares.each do |share|
112
+ raise ArgumentError, 'Invalid set of shares. All shares in a group must have the same member threshold.' unless member_threshold == share.member_threshold
113
+ raise ArgumentError, 'Invalid set of shares. All share values must have the same length.' unless value_length == share.value.length
114
+ x_coordinates << share.member_index
115
+ end
116
+ x_coordinates.uniq!
117
+ raise ArgumentError, 'Invalid set of shares. Share indices must be unique.' unless x_coordinates.size == shares.size
118
+ interpolate_shares = shares.map{|s|[s.member_index, s.value]}
119
+
120
+ secret = interpolate(interpolate_shares, SECRET_INDEX)
121
+ digest_value = interpolate(interpolate_shares, DIGEST_INDEX).htb
122
+ digest, random_value = digest_value[0...DIGEST_LENGTH_BYTES].bth, digest_value[DIGEST_LENGTH_BYTES..-1].bth
123
+ recover_digest = create_digest(secret, random_value)
124
+ raise ArgumentError, 'Invalid digest of the shared secret.' unless digest == recover_digest
125
+
126
+ group_shares[group_index] = secret
127
+ end
128
+ end
129
+
130
+ return decrypt(group_shares.values.first, passphrase, exp, id) if group_threshold == 1
131
+
132
+ raise ArgumentError, "Wrong number of mnemonics. Group threshold is #{group_threshold}, but share count is #{group_shares.length}" if group_shares.length < group_threshold
133
+
134
+ interpolate_shares = group_shares.map{|k, v|[k, v]}
135
+ secret = interpolate(interpolate_shares, SECRET_INDEX)
136
+ digest_value = interpolate(interpolate_shares, DIGEST_INDEX).htb
137
+ digest, random_value = digest_value[0...DIGEST_LENGTH_BYTES].bth, digest_value[DIGEST_LENGTH_BYTES..-1].bth
138
+ recover_digest = create_digest(secret, random_value)
139
+ raise ArgumentError, 'Invalid digest of the shared secret.' unless digest == recover_digest
140
+
141
+ decrypt(secret, passphrase, exp, id)
142
+ end
143
+
144
+ private
145
+
146
+ # Calculate f(x) from given shamir shares.
147
+ # @param [Array[index, value]] shares the array of shamir shares.
148
+ # @param [Integer] x the x coordinate of the result.
149
+ # @return [String] f(x) value with hex format.
150
+ def self.interpolate(shares, x)
151
+ s = shares.find{|s|s[0] == x}
152
+ return s[1] if s
153
+
154
+ log_prod = shares.sum{|s|LOG_TABLE[s[0] ^ x]}
155
+
156
+ result = ('00' * shares.first[1].length).htb
157
+ shares.each do |share|
158
+ log_basis_eval = (log_prod - LOG_TABLE[share[0] ^ x] - shares.sum{|s|LOG_TABLE[share[0] ^ s[0]]}) % 255
159
+ result = share[1].htb.bytes.each.map.with_index do |v, i|
160
+ (result[i].bti ^ (v == 0 ? 0 : (EXP_TABLE[(LOG_TABLE[v] + log_basis_eval) % 255]))).itb
161
+ end.join
162
+ end
163
+ result.bth
164
+ end
165
+
166
+ # Decrypt encrypted master secret using passphrase.
167
+ # @param [String] ems an encrypted master secret with hex format.
168
+ # @param [String] passphrase the passphrase when using encrypt master secret with binary format.
169
+ # @param [Integer] exp iteration exponent
170
+ # @param [Integer] id identifier
171
+ def self.decrypt(ems, passphrase, exp, id)
172
+ l, r = ems[0...(ems.length / 2)].htb, ems[(ems.length / 2)..-1].htb
173
+ salt = get_salt(id)
174
+ e = (Bitcoin::SLIP39::BASE_ITERATION_COUNT << exp) / Bitcoin::SLIP39::ROUND_COUNT
175
+ Bitcoin::SLIP39::ROUND_COUNT.times.to_a.reverse.each do |i|
176
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
177
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
178
+ end
179
+ (r + l).bth
180
+ end
181
+
182
+ # Encrypt master secret using passphrase
183
+ # @param [String] secret master secret with hex format.
184
+ # @param [String] passphrase the passphrase when using encrypt master secret with binary format.
185
+ # @param [Integer] exp iteration exponent
186
+ # @param [Integer] id identifier
187
+ # @return [String] encrypted master secret with hex format.
188
+ def self.encrypt(secret, passphrase, exp, id)
189
+ s = secret.htb
190
+ l, r = s[0...(s.bytesize / 2)], s[(s.bytesize / 2)..-1]
191
+ salt = get_salt(id)
192
+ e = (Bitcoin::SLIP39::BASE_ITERATION_COUNT << exp) / Bitcoin::SLIP39::ROUND_COUNT
193
+ Bitcoin::SLIP39::ROUND_COUNT.times.to_a.each do |i|
194
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
195
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
196
+ end
197
+ (r + l).bth
198
+ end
199
+
200
+ # Create digest of the shared secret.
201
+ # @param [String] secret the shared secret with hex format.
202
+ # @param [String] random value (n-4 bytes) with hex format.
203
+ # @return [String] digest value(4 bytes) with hex format.
204
+ def self.create_digest(secret, random)
205
+ h = Bitcoin.hmac_sha256(random.htb, secret.htb)
206
+ h[0...4].bth
207
+ end
208
+
209
+ # get salt using encryption/decryption form id.
210
+ # @param [Integer] id id
211
+ # @return [String] salt with binary format.
212
+ def self.get_salt(id)
213
+ (Bitcoin::SLIP39::CUSTOMIZATION_STRING.pack('c*') + id.itb)
214
+ end
215
+
216
+ # Split the share into +count+ with threshold +threshold+.
217
+ # @param [Integer] threshold the threshold.
218
+ # @param [Integer] count split count.
219
+ # @param [Integer] secret the secret to be split.
220
+ # @return [Array[Integer, String]] the array of split secret.
221
+ def self.split_secret(threshold, count, secret)
222
+ raise ArgumentError, "The requested threshold (#{threshold}) must be a positive integer." if threshold < 1
223
+ raise ArgumentError, "The requested threshold (#{threshold}) must not exceed the number of shares (#{count})." if threshold > count
224
+ raise ArgumentError, "The requested number of shares (#{count}) must not exceed #{MAX_SHARE_COUNT}." if count > MAX_SHARE_COUNT
225
+
226
+ return count.times.map{|i|[i, secret]} if threshold == 1 # if the threshold is 1, digest of the share is not used.
227
+
228
+ random_share_count = threshold - 2
229
+
230
+ shares = random_share_count.times.map{|i|[i, SecureRandom.hex(secret.htb.bytesize)]}
231
+ random_part = SecureRandom.hex(secret.htb.bytesize - DIGEST_LENGTH_BYTES)
232
+ digest = create_digest(secret, random_part)
233
+
234
+ base_shares = shares + [[DIGEST_INDEX, digest + random_part], [SECRET_INDEX, secret]]
235
+
236
+ (random_share_count...count).each { |i| shares << [i, interpolate(base_shares, i)]}
237
+
238
+ shares
239
+ end
240
+
241
+ private_class_method :split_secret, :get_salt, :interpolate, :encrypt, :decrypt, :create_digest
242
+
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,1024 @@
1
+ academic
2
+ acid
3
+ acne
4
+ acquire
5
+ acrobat
6
+ activity
7
+ actress
8
+ adapt
9
+ adequate
10
+ adjust
11
+ admit
12
+ adorn
13
+ adult
14
+ advance
15
+ advocate
16
+ afraid
17
+ again
18
+ agency
19
+ agree
20
+ aide
21
+ aircraft
22
+ airline
23
+ airport
24
+ ajar
25
+ alarm
26
+ album
27
+ alcohol
28
+ alien
29
+ alive
30
+ alpha
31
+ already
32
+ alto
33
+ aluminum
34
+ always
35
+ amazing
36
+ ambition
37
+ amount
38
+ amuse
39
+ analysis
40
+ anatomy
41
+ ancestor
42
+ ancient
43
+ angel
44
+ angry
45
+ animal
46
+ answer
47
+ antenna
48
+ anxiety
49
+ apart
50
+ aquatic
51
+ arcade
52
+ arena
53
+ argue
54
+ armed
55
+ artist
56
+ artwork
57
+ aspect
58
+ auction
59
+ august
60
+ aunt
61
+ average
62
+ aviation
63
+ avoid
64
+ award
65
+ away
66
+ axis
67
+ axle
68
+ beam
69
+ beard
70
+ beaver
71
+ become
72
+ bedroom
73
+ behavior
74
+ being
75
+ believe
76
+ belong
77
+ benefit
78
+ best
79
+ beyond
80
+ bike
81
+ biology
82
+ birthday
83
+ bishop
84
+ black
85
+ blanket
86
+ blessing
87
+ blimp
88
+ blind
89
+ blue
90
+ body
91
+ bolt
92
+ boring
93
+ born
94
+ both
95
+ boundary
96
+ bracelet
97
+ branch
98
+ brave
99
+ breathe
100
+ briefing
101
+ broken
102
+ brother
103
+ browser
104
+ bucket
105
+ budget
106
+ building
107
+ bulb
108
+ bulge
109
+ bumpy
110
+ bundle
111
+ burden
112
+ burning
113
+ busy
114
+ buyer
115
+ cage
116
+ calcium
117
+ camera
118
+ campus
119
+ canyon
120
+ capacity
121
+ capital
122
+ capture
123
+ carbon
124
+ cards
125
+ careful
126
+ cargo
127
+ carpet
128
+ carve
129
+ category
130
+ cause
131
+ ceiling
132
+ center
133
+ ceramic
134
+ champion
135
+ change
136
+ charity
137
+ check
138
+ chemical
139
+ chest
140
+ chew
141
+ chubby
142
+ cinema
143
+ civil
144
+ class
145
+ clay
146
+ cleanup
147
+ client
148
+ climate
149
+ clinic
150
+ clock
151
+ clogs
152
+ closet
153
+ clothes
154
+ club
155
+ cluster
156
+ coal
157
+ coastal
158
+ coding
159
+ column
160
+ company
161
+ corner
162
+ costume
163
+ counter
164
+ course
165
+ cover
166
+ cowboy
167
+ cradle
168
+ craft
169
+ crazy
170
+ credit
171
+ cricket
172
+ criminal
173
+ crisis
174
+ critical
175
+ crowd
176
+ crucial
177
+ crunch
178
+ crush
179
+ crystal
180
+ cubic
181
+ cultural
182
+ curious
183
+ curly
184
+ custody
185
+ cylinder
186
+ daisy
187
+ damage
188
+ dance
189
+ darkness
190
+ database
191
+ daughter
192
+ deadline
193
+ deal
194
+ debris
195
+ debut
196
+ decent
197
+ decision
198
+ declare
199
+ decorate
200
+ decrease
201
+ deliver
202
+ demand
203
+ density
204
+ deny
205
+ depart
206
+ depend
207
+ depict
208
+ deploy
209
+ describe
210
+ desert
211
+ desire
212
+ desktop
213
+ destroy
214
+ detailed
215
+ detect
216
+ device
217
+ devote
218
+ diagnose
219
+ dictate
220
+ diet
221
+ dilemma
222
+ diminish
223
+ dining
224
+ diploma
225
+ disaster
226
+ discuss
227
+ disease
228
+ dish
229
+ dismiss
230
+ display
231
+ distance
232
+ dive
233
+ divorce
234
+ document
235
+ domain
236
+ domestic
237
+ dominant
238
+ dough
239
+ downtown
240
+ dragon
241
+ dramatic
242
+ dream
243
+ dress
244
+ drift
245
+ drink
246
+ drove
247
+ drug
248
+ dryer
249
+ duckling
250
+ duke
251
+ duration
252
+ dwarf
253
+ dynamic
254
+ early
255
+ earth
256
+ easel
257
+ easy
258
+ echo
259
+ eclipse
260
+ ecology
261
+ edge
262
+ editor
263
+ educate
264
+ either
265
+ elbow
266
+ elder
267
+ election
268
+ elegant
269
+ element
270
+ elephant
271
+ elevator
272
+ elite
273
+ else
274
+ email
275
+ emerald
276
+ emission
277
+ emperor
278
+ emphasis
279
+ employer
280
+ empty
281
+ ending
282
+ endless
283
+ endorse
284
+ enemy
285
+ energy
286
+ enforce
287
+ engage
288
+ enjoy
289
+ enlarge
290
+ entrance
291
+ envelope
292
+ envy
293
+ epidemic
294
+ episode
295
+ equation
296
+ equip
297
+ eraser
298
+ erode
299
+ escape
300
+ estate
301
+ estimate
302
+ evaluate
303
+ evening
304
+ evidence
305
+ evil
306
+ evoke
307
+ exact
308
+ example
309
+ exceed
310
+ exchange
311
+ exclude
312
+ excuse
313
+ execute
314
+ exercise
315
+ exhaust
316
+ exotic
317
+ expand
318
+ expect
319
+ explain
320
+ express
321
+ extend
322
+ extra
323
+ eyebrow
324
+ facility
325
+ fact
326
+ failure
327
+ faint
328
+ fake
329
+ false
330
+ family
331
+ famous
332
+ fancy
333
+ fangs
334
+ fantasy
335
+ fatal
336
+ fatigue
337
+ favorite
338
+ fawn
339
+ fiber
340
+ fiction
341
+ filter
342
+ finance
343
+ findings
344
+ finger
345
+ firefly
346
+ firm
347
+ fiscal
348
+ fishing
349
+ fitness
350
+ flame
351
+ flash
352
+ flavor
353
+ flea
354
+ flexible
355
+ flip
356
+ float
357
+ floral
358
+ fluff
359
+ focus
360
+ forbid
361
+ force
362
+ forecast
363
+ forget
364
+ formal
365
+ fortune
366
+ forward
367
+ founder
368
+ fraction
369
+ fragment
370
+ frequent
371
+ freshman
372
+ friar
373
+ fridge
374
+ friendly
375
+ frost
376
+ froth
377
+ frozen
378
+ fumes
379
+ funding
380
+ furl
381
+ fused
382
+ galaxy
383
+ game
384
+ garbage
385
+ garden
386
+ garlic
387
+ gasoline
388
+ gather
389
+ general
390
+ genius
391
+ genre
392
+ genuine
393
+ geology
394
+ gesture
395
+ glad
396
+ glance
397
+ glasses
398
+ glen
399
+ glimpse
400
+ goat
401
+ golden
402
+ graduate
403
+ grant
404
+ grasp
405
+ gravity
406
+ gray
407
+ greatest
408
+ grief
409
+ grill
410
+ grin
411
+ grocery
412
+ gross
413
+ group
414
+ grownup
415
+ grumpy
416
+ guard
417
+ guest
418
+ guilt
419
+ guitar
420
+ gums
421
+ hairy
422
+ hamster
423
+ hand
424
+ hanger
425
+ harvest
426
+ have
427
+ havoc
428
+ hawk
429
+ hazard
430
+ headset
431
+ health
432
+ hearing
433
+ heat
434
+ helpful
435
+ herald
436
+ herd
437
+ hesitate
438
+ hobo
439
+ holiday
440
+ holy
441
+ home
442
+ hormone
443
+ hospital
444
+ hour
445
+ huge
446
+ human
447
+ humidity
448
+ hunting
449
+ husband
450
+ hush
451
+ husky
452
+ hybrid
453
+ idea
454
+ identify
455
+ idle
456
+ image
457
+ impact
458
+ imply
459
+ improve
460
+ impulse
461
+ include
462
+ income
463
+ increase
464
+ index
465
+ indicate
466
+ industry
467
+ infant
468
+ inform
469
+ inherit
470
+ injury
471
+ inmate
472
+ insect
473
+ inside
474
+ install
475
+ intend
476
+ intimate
477
+ invasion
478
+ involve
479
+ iris
480
+ island
481
+ isolate
482
+ item
483
+ ivory
484
+ jacket
485
+ jerky
486
+ jewelry
487
+ join
488
+ judicial
489
+ juice
490
+ jump
491
+ junction
492
+ junior
493
+ junk
494
+ jury
495
+ justice
496
+ kernel
497
+ keyboard
498
+ kidney
499
+ kind
500
+ kitchen
501
+ knife
502
+ knit
503
+ laden
504
+ ladle
505
+ ladybug
506
+ lair
507
+ lamp
508
+ language
509
+ large
510
+ laser
511
+ laundry
512
+ lawsuit
513
+ leader
514
+ leaf
515
+ learn
516
+ leaves
517
+ lecture
518
+ legal
519
+ legend
520
+ legs
521
+ lend
522
+ length
523
+ level
524
+ liberty
525
+ library
526
+ license
527
+ lift
528
+ likely
529
+ lilac
530
+ lily
531
+ lips
532
+ liquid
533
+ listen
534
+ literary
535
+ living
536
+ lizard
537
+ loan
538
+ lobe
539
+ location
540
+ losing
541
+ loud
542
+ loyalty
543
+ luck
544
+ lunar
545
+ lunch
546
+ lungs
547
+ luxury
548
+ lying
549
+ lyrics
550
+ machine
551
+ magazine
552
+ maiden
553
+ mailman
554
+ main
555
+ makeup
556
+ making
557
+ mama
558
+ manager
559
+ mandate
560
+ mansion
561
+ manual
562
+ marathon
563
+ march
564
+ market
565
+ marvel
566
+ mason
567
+ material
568
+ math
569
+ maximum
570
+ mayor
571
+ meaning
572
+ medal
573
+ medical
574
+ member
575
+ memory
576
+ mental
577
+ merchant
578
+ merit
579
+ method
580
+ metric
581
+ midst
582
+ mild
583
+ military
584
+ mineral
585
+ minister
586
+ miracle
587
+ mixed
588
+ mixture
589
+ mobile
590
+ modern
591
+ modify
592
+ moisture
593
+ moment
594
+ morning
595
+ mortgage
596
+ mother
597
+ mountain
598
+ mouse
599
+ move
600
+ much
601
+ mule
602
+ multiple
603
+ muscle
604
+ museum
605
+ music
606
+ mustang
607
+ nail
608
+ national
609
+ necklace
610
+ negative
611
+ nervous
612
+ network
613
+ news
614
+ nuclear
615
+ numb
616
+ numerous
617
+ nylon
618
+ oasis
619
+ obesity
620
+ object
621
+ observe
622
+ obtain
623
+ ocean
624
+ often
625
+ olympic
626
+ omit
627
+ oral
628
+ orange
629
+ orbit
630
+ order
631
+ ordinary
632
+ organize
633
+ ounce
634
+ oven
635
+ overall
636
+ owner
637
+ paces
638
+ pacific
639
+ package
640
+ paid
641
+ painting
642
+ pajamas
643
+ pancake
644
+ pants
645
+ papa
646
+ paper
647
+ parcel
648
+ parking
649
+ party
650
+ patent
651
+ patrol
652
+ payment
653
+ payroll
654
+ peaceful
655
+ peanut
656
+ peasant
657
+ pecan
658
+ penalty
659
+ pencil
660
+ percent
661
+ perfect
662
+ permit
663
+ petition
664
+ phantom
665
+ pharmacy
666
+ photo
667
+ phrase
668
+ physics
669
+ pickup
670
+ picture
671
+ piece
672
+ pile
673
+ pink
674
+ pipeline
675
+ pistol
676
+ pitch
677
+ plains
678
+ plan
679
+ plastic
680
+ platform
681
+ playoff
682
+ pleasure
683
+ plot
684
+ plunge
685
+ practice
686
+ prayer
687
+ preach
688
+ predator
689
+ pregnant
690
+ premium
691
+ prepare
692
+ presence
693
+ prevent
694
+ priest
695
+ primary
696
+ priority
697
+ prisoner
698
+ privacy
699
+ prize
700
+ problem
701
+ process
702
+ profile
703
+ program
704
+ promise
705
+ prospect
706
+ provide
707
+ prune
708
+ public
709
+ pulse
710
+ pumps
711
+ punish
712
+ puny
713
+ pupal
714
+ purchase
715
+ purple
716
+ python
717
+ quantity
718
+ quarter
719
+ quick
720
+ quiet
721
+ race
722
+ racism
723
+ radar
724
+ railroad
725
+ rainbow
726
+ raisin
727
+ random
728
+ ranked
729
+ rapids
730
+ raspy
731
+ reaction
732
+ realize
733
+ rebound
734
+ rebuild
735
+ recall
736
+ receiver
737
+ recover
738
+ regret
739
+ regular
740
+ reject
741
+ relate
742
+ remember
743
+ remind
744
+ remove
745
+ render
746
+ repair
747
+ repeat
748
+ replace
749
+ require
750
+ rescue
751
+ research
752
+ resident
753
+ response
754
+ result
755
+ retailer
756
+ retreat
757
+ reunion
758
+ revenue
759
+ review
760
+ reward
761
+ rhyme
762
+ rhythm
763
+ rich
764
+ rival
765
+ river
766
+ robin
767
+ rocky
768
+ romantic
769
+ romp
770
+ roster
771
+ round
772
+ royal
773
+ ruin
774
+ ruler
775
+ rumor
776
+ sack
777
+ safari
778
+ salary
779
+ salon
780
+ salt
781
+ satisfy
782
+ satoshi
783
+ saver
784
+ says
785
+ scandal
786
+ scared
787
+ scatter
788
+ scene
789
+ scholar
790
+ science
791
+ scout
792
+ scramble
793
+ screw
794
+ script
795
+ scroll
796
+ seafood
797
+ season
798
+ secret
799
+ security
800
+ segment
801
+ senior
802
+ shadow
803
+ shaft
804
+ shame
805
+ shaped
806
+ sharp
807
+ shelter
808
+ sheriff
809
+ short
810
+ should
811
+ shrimp
812
+ sidewalk
813
+ silent
814
+ silver
815
+ similar
816
+ simple
817
+ single
818
+ sister
819
+ skin
820
+ skunk
821
+ slap
822
+ slavery
823
+ sled
824
+ slice
825
+ slim
826
+ slow
827
+ slush
828
+ smart
829
+ smear
830
+ smell
831
+ smirk
832
+ smith
833
+ smoking
834
+ smug
835
+ snake
836
+ snapshot
837
+ sniff
838
+ society
839
+ software
840
+ soldier
841
+ solution
842
+ soul
843
+ source
844
+ space
845
+ spark
846
+ speak
847
+ species
848
+ spelling
849
+ spend
850
+ spew
851
+ spider
852
+ spill
853
+ spine
854
+ spirit
855
+ spit
856
+ spray
857
+ sprinkle
858
+ square
859
+ squeeze
860
+ stadium
861
+ staff
862
+ standard
863
+ starting
864
+ station
865
+ stay
866
+ steady
867
+ step
868
+ stick
869
+ stilt
870
+ story
871
+ strategy
872
+ strike
873
+ style
874
+ subject
875
+ submit
876
+ sugar
877
+ suitable
878
+ sunlight
879
+ superior
880
+ surface
881
+ surprise
882
+ survive
883
+ sweater
884
+ swimming
885
+ swing
886
+ switch
887
+ symbolic
888
+ sympathy
889
+ syndrome
890
+ system
891
+ tackle
892
+ tactics
893
+ tadpole
894
+ talent
895
+ task
896
+ taste
897
+ taught
898
+ taxi
899
+ teacher
900
+ teammate
901
+ teaspoon
902
+ temple
903
+ tenant
904
+ tendency
905
+ tension
906
+ terminal
907
+ testify
908
+ texture
909
+ thank
910
+ that
911
+ theater
912
+ theory
913
+ therapy
914
+ thorn
915
+ threaten
916
+ thumb
917
+ thunder
918
+ ticket
919
+ tidy
920
+ timber
921
+ timely
922
+ ting
923
+ tofu
924
+ together
925
+ tolerate
926
+ total
927
+ toxic
928
+ tracks
929
+ traffic
930
+ training
931
+ transfer
932
+ trash
933
+ traveler
934
+ treat
935
+ trend
936
+ trial
937
+ tricycle
938
+ trip
939
+ triumph
940
+ trouble
941
+ true
942
+ trust
943
+ twice
944
+ twin
945
+ type
946
+ typical
947
+ ugly
948
+ ultimate
949
+ umbrella
950
+ uncover
951
+ undergo
952
+ unfair
953
+ unfold
954
+ unhappy
955
+ union
956
+ universe
957
+ unkind
958
+ unknown
959
+ unusual
960
+ unwrap
961
+ upgrade
962
+ upstairs
963
+ username
964
+ usher
965
+ usual
966
+ valid
967
+ valuable
968
+ vampire
969
+ vanish
970
+ various
971
+ vegan
972
+ velvet
973
+ venture
974
+ verdict
975
+ verify
976
+ very
977
+ veteran
978
+ vexed
979
+ victim
980
+ video
981
+ view
982
+ vintage
983
+ violence
984
+ viral
985
+ visitor
986
+ visual
987
+ vitamins
988
+ vocal
989
+ voice
990
+ volume
991
+ voter
992
+ voting
993
+ walnut
994
+ warmth
995
+ warn
996
+ watch
997
+ wavy
998
+ wealthy
999
+ weapon
1000
+ webcam
1001
+ welcome
1002
+ welfare
1003
+ western
1004
+ width
1005
+ wildlife
1006
+ window
1007
+ wine
1008
+ wireless
1009
+ wisdom
1010
+ withdraw
1011
+ wits
1012
+ wolf
1013
+ woman
1014
+ work
1015
+ worthy
1016
+ wrap
1017
+ wrist
1018
+ writing
1019
+ wrote
1020
+ year
1021
+ yelp
1022
+ yield
1023
+ yoga
1024
+ zero