├── .github
└── workflows
│ ├── ci-linux.yml
│ └── ci-windows.yml
├── .gitignore
├── .gitmodules
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── LICENSE.txt
├── README.md
├── source
├── addresses.adb
├── addresses.ads
├── base64.adb
├── base64.ads
├── benchmark.adb
├── cells.adb
├── cells.ads
├── cryptography.adb
├── cryptography.ads
├── mnemonic2address.adb
├── mnemonics.adb
├── mnemonics.ads
├── types.adb
├── types.ads
├── vaniton.adb
├── wallets.adb
├── wallets.ads
├── words.ads
├── workers.adb
└── workers.ads
└── vaniton.gpr
/.github/workflows/ci-linux.yml:
--------------------------------------------------------------------------------
1 | name: CI linux
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | release:
7 | types: [created]
8 |
9 | jobs:
10 |
11 | build:
12 | name: CI on Linux
13 |
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Check out repository
18 | uses: actions/checkout@v2
19 | with:
20 | submodules: true
21 |
22 | - name: Install toolchain
23 | uses: ada-actions/toolchain@ce2021
24 | with:
25 | distrib: community
26 |
27 | - name: Build release
28 | run: >
29 | gprbuild -P vaniton.gpr -XBUILD=RELEASE -j0
30 |
31 | - name: Upload binaries
32 | uses: actions/upload-artifact@v2
33 | with:
34 | name: vaniton-bin-linux.zip
35 | path: |
36 | bin/vaniton
37 | bin/mnemonic2address
38 | bin/benchmark
39 | README.md
40 | LICENSE.txt
41 |
42 | # Release steps
43 | - name: Package binaries
44 | if: (github.event_name == 'release')
45 | run: zip vaniton-bin-linux.zip bin/vaniton bin/mnemonic2address bin/benchmark README.md LICENSE.txt
46 |
47 | - name: Retrieve upload URL for the release
48 | if: (github.event_name == 'release')
49 | id: get_release
50 | uses: bruceadams/get-release@v1.2.1
51 | env:
52 | GITHUB_TOKEN: ${{ github.token }}
53 |
54 | - name: Get release version
55 | if: (github.event_name == 'release')
56 | id: get_version
57 | uses: battila7/get-version-action@v2
58 |
59 | - name: Upload binary assets
60 | if: (github.event_name == 'release')
61 | uses: actions/upload-release-asset@v1
62 | env:
63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64 | with:
65 | upload_url: ${{ steps.get_release.outputs.upload_url }}
66 | asset_path: vaniton-bin-linux.zip
67 | asset_name: vaniton-${{ steps.get_version.outputs.version-without-v }}-bin-x86_64-linux.zip
68 | asset_content_type: application/zip
69 |
--------------------------------------------------------------------------------
/.github/workflows/ci-windows.yml:
--------------------------------------------------------------------------------
1 | name: CI windows
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | release:
7 | types: [created]
8 |
9 | jobs:
10 |
11 | build:
12 | name: CI on Windows
13 |
14 | runs-on: windows-2022
15 |
16 | steps:
17 | - name: Check out repository
18 | uses: actions/checkout@v2
19 | with:
20 | submodules: true
21 |
22 | - name: Install toolchain
23 | uses: ada-actions/toolchain@ce2021
24 | with:
25 | distrib: community
26 |
27 | - name: Install OpenSSL on MSYS2
28 | run: |
29 | C:\msys64\usr\bin\pacman --noconfirm -S mingw-w64-x86_64-openssl zip
30 | Copy-Item -Path "C:\msys64\mingw64\include\openssl" -Destination "D:\a\_temp\gnat-2021-20210519-x86_64-windows64-bin\x86_64-w64-mingw32\include" -Recurse
31 | Copy-Item "C:\msys64\mingw64\lib\libssl.*" -Destination "D:\a\_temp\gnat-2021-20210519-x86_64-windows64-bin\lib"
32 | Copy-Item "C:\msys64\mingw64\lib\libcrypto.*" -Destination "D:\a\_temp\gnat-2021-20210519-x86_64-windows64-bin\lib"
33 | mkdir bin
34 | Copy-Item "C:\msys64\mingw64\bin\libcrypto-*-x64.dll" -Destination "bin"
35 | Copy-Item "C:\msys64\mingw64\share\licenses\openssl\LICENSE" -Destination ".\LICENSE.OpenSSL"
36 |
37 | - name: Build release
38 | run: >
39 | gprbuild -P vaniton.gpr -XBUILD=RELEASE -j0
40 |
41 | - name: Upload binaries
42 | uses: actions/upload-artifact@v2
43 | with:
44 | name: vaniton-bin-windows.zip
45 | path: |
46 | bin/vaniton.exe
47 | bin/mnemonic2address.exe
48 | bin/benchmark.exe
49 | bin/libcrypto-1_1-x64.dll
50 | README.md
51 | LICENSE.txt
52 | LICENSE.OpenSSL
53 |
54 | # Release steps
55 | - name: Package binaries
56 | if: (github.event_name == 'release')
57 | run: C:\msys64\usr\bin\zip vaniton-bin-windows.zip bin/vaniton.exe bin/mnemonic2address.exe bin/benchmark.exe bin/libcrypto-*-x64.dll README.md LICENSE.txt LICENSE.OpenSSL
58 |
59 | - name: Retrieve upload URL for the release
60 | if: (github.event_name == 'release')
61 | id: get_release
62 | uses: bruceadams/get-release@v1.2.1
63 | env:
64 | GITHUB_TOKEN: ${{ github.token }}
65 |
66 | - name: Get release version
67 | if: (github.event_name == 'release')
68 | id: get_version
69 | uses: battila7/get-version-action@v2
70 |
71 | - name: Upload binary assets
72 | if: (github.event_name == 'release')
73 | uses: actions/upload-release-asset@v1
74 | env:
75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76 | with:
77 | upload_url: ${{ steps.get_release.outputs.upload_url }}
78 | asset_path: vaniton-bin-windows.zip
79 | asset_name: vaniton-${{ steps.get_version.outputs.version-without-v }}-bin-x86_64-windows.zip
80 | asset_content_type: application/zip
81 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | build/
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "third-party/sparknacl"]
2 | path = third-party/sparknacl
3 | url = https://github.com/rod-chapman/SPARKNaCl.git
4 | [submodule "third-party/fastpbkdf2"]
5 | path = third-party/fastpbkdf2
6 | url = https://github.com/ctz/fastpbkdf2.git
7 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "(gdb) Launch vaniton.exe",
6 | "type": "cppdbg",
7 | "request": "launch",
8 | "program": "${workspaceFolder}/bin/vaniton.exe",
9 | "args": [],
10 | "stopAtEntry": false,
11 | "cwd": "${workspaceFolder}",
12 | "environment": [],
13 | "MIMode": "gdb",
14 | "setupCommands": [
15 | {
16 | "description": "Enable pretty-printing for gdb",
17 | "text": "-enable-pretty-printing",
18 | "ignoreFailures": true
19 | }
20 | ]
21 | },
22 | {
23 | "name": "(gdb) Launch benchmark.exe",
24 | "type": "cppdbg",
25 | "request": "launch",
26 | "program": "${workspaceFolder}/bin/benchmark.exe",
27 | "args": [],
28 | "stopAtEntry": false,
29 | "cwd": "${workspaceFolder}",
30 | "environment": [],
31 | "MIMode": "gdb",
32 | "setupCommands": [
33 | {
34 | "description": "Enable pretty-printing for gdb",
35 | "text": "-enable-pretty-printing",
36 | "ignoreFailures": true
37 | }
38 | ]
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ada.defaultCharset": "utf-8",
3 | "ada.projectFile": "vaniton.gpr",
4 | "files.eol": "\n"
5 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "problemMatcher": [
6 | "$ada"
7 | ],
8 | "type": "process",
9 | "command": "gprbuild.exe",
10 | "group": {
11 | "kind": "build",
12 | "isDefault": true
13 | },
14 | "presentation": {
15 | "reveal": "always"
16 | },
17 | "args": [
18 | "-P${config:ada.projectFile}",
19 | "-XBUILD=DEBUG",
20 | "-j0"
21 | ],
22 | "label": "Build vaniton",
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | vaniton   
3 | =======
4 |
5 | **vaniton** is a vanity wallet address generator for [The Open Network's](https://ton.org/) blockchain. Currently it supports all major versions of wallet smart contracts you could encounter (from SimpleR1 to V4R2).
6 |
7 | > **Disclaimer**:
8 | Always verify that mnemonic generated by this program corresponds to address by importing it into a wallet of your choice. As any other software this program may contain bugs.
9 |
10 | # Help
11 | ```
12 | Vanity address generator for The Open Network blockchain wallets.
13 | Generates 24-word secret phrases and computes wallet address for the selected wallet
14 | contract version (default: V3_R2).
15 | Optionally, addresses are filtered out by matching against [pattern].
16 | Project page:
17 |
18 | Usage: vaniton.exe [switches] [pattern]
19 |
20 | -j, --threads=ARG Number of working threads running in parallel
21 | -w, --wallet=ARG Wallet version to use (default: V3_R2)
22 | -c, --case-sensitive Match case-sensitive (default: FALSE)
23 | -l, --log=ARG Log program output to file (default: '')
24 | -t, --test-only Generate mainnet/test-only addresses (default: FALSE)
25 | -b, --bounceable Generate bounceable/non-bounceable addresses (default: TRUE)
26 | -wsimpler1 Equivalent to --wallet=Simple_R1
27 | -wsimpler2 Equivalent to --wallet=Simple_R2
28 | -wsimpler3 Equivalent to --wallet=Simple_R3
29 | -wsimple Equivalent to --wallet=Simple_R3
30 | -wv2r1 Equivalent to --wallet=V2_R1
31 | -wv2r2 Equivalent to --wallet=V2_R2
32 | -wv2 Equivalent to --wallet=V2_R2
33 | -wv3r1 Equivalent to --wallet=V3_R1
34 | -wv3r2 Equivalent to --wallet=V3_R2
35 | -wv3 Equivalent to --wallet=V3_R2
36 | -wv4r1 Equivalent to --wallet=V4_R1
37 | -wv4r2 Equivalent to --wallet=V4_R2
38 | -wv4 Equivalent to --wallet=V4_R2
39 | ```
40 |
41 | # Pattern format
42 | Currently, program implements only a simple subset of regular expression patterns, here's a quick summary:
43 |
44 | | Expression | Description |
45 | |------------|-------------|
46 | | a|b | Matches 'a' or 'b' |
47 | | ab | Matches 'ab' |
48 | | a* | Matches zero or more 'a's |
49 | | a+ | Matches one or more 'a's |
50 | | a? | Matches one 'a' or nothing |
51 | | [ab] | Matches 'a' or 'b' |
52 | | [^ab] | Matches anything but 'a' or 'b' |
53 | | [a-c] | Matches 'a' or 'b' or 'c' |
54 | | . | Matches anything |
55 | | (abc) | Grouping |
56 |
57 | Note, that patterns in **vaniton** match entire address string, and by default are case-insensitive (can be changed with `-c` switch). If you get stuck, it might be worth it to redirect output into *grep*, *awk*, or some other program of your liking to filter out unwanted addresses.
58 |
59 | Here are some of the examples to get you started:
60 | ```
61 | $ vaniton .*abc.* # Match any address that has "abc" anywhere in it
62 | $ vaniton .*t[o0]n.* # Match any address that has "ton" or "t0n" anywhere in it
63 | $ vaniton ..al[i1]z[e3]r.* # Since first two characters are always "EQ" and third character is [ABCD], this would match addresses that start with "EQalizer", "EQal1z3r", "EQaliz3r", or "EQal1z3r"
64 | ```
65 |
66 | # Safety
67 | This program utilizes same algorithms used by all TON wallets and relies on well-tested cryptography libraries such as OpenSSL and SPARKNaCl. While corners were certainly cut to improve overall performance, safety was not compromised.
68 |
69 | Furthermore, **vaniton** does not have any online capabilities, dynamically loaded code (apart from abovementioned OpenSSL on certain systems), nor a large number of obscure dependencies.
70 |
71 | # Are you cracking passwords? Can I accidentally get access to someone else's funds?
72 | Impossible, this will never happen. Although mathematics forces me to say that this is *possible*, it is so unimaginably improbable that calling it impossible is a pretty good approximation.
73 |
74 | See, secret phrase consists of a 24-word mnemonic phrase where each word can be one of 2048 words of a special wordlist. This gives us 2048^24 or about 2.9\*10^79 possible combinations. It is rather difficult to wrap one's head around a number this big, but just for the sake of comparison, Solar System, the entirety of it, consists of about 1.2\*10^56 atoms. Yep, it just ain't gonna happen
75 |
76 | # Speed
77 | **vaniton** is extremely slow compared to similar vanity address generators made for different blockchains. This all comes down to key derivation functions used by TON wallets, which increases time required to calculate a private key from supplied mnemonic phrase.
78 | This is done to greatly decrease efficiency of brute-force attacks where an attacker would try to blindly go over a large number of private keys. Unfortunately, this is pretty much what searching for a vanity address is like.
79 |
80 | Tips on improving performance:
81 | - Use as many worker threads as possible
82 | - Limit number of characters you're searching for
83 | - Search for characters of both upper and lower case
84 | - 1337. Try t0 s34rch f0r numb3rs t00
85 |
86 | Here's an example table that shows you how much time it takes to match N characters. Albeit time to match a certain set of characters is largely dependent on your luck, and these measures were made on a fairly slow virtual machine, this can give you a good idea on what to expect.
87 | You can used supplied `benchmark` tool to measure address generation speed of your machine.
88 |
89 | | N | Time (s) | How much longer? |
90 | |---|----------|------------------|
91 | | 1 | 0.1 | - |
92 | | 2 | 3.9 | 39x |
93 | | 3 | 595.6 | 153x |
94 | | 4 | 17441.6 | 29x |
95 |
96 |
97 | # Wallet contract versions
98 | Due to the nature of TON blockchain, users' wallets *are* smart contracts. Over time, different versions of wallet smart contracts were used in TON. It is important to specify which version of a wallet you want to be generating addresses for. Here's a quick overview of different versions:
99 | - Do not use Simple or V2 wallet versions, these are largely obsolete
100 | - V3R2 is the default version of wallets created by all major wallet software. This is also the default for vaniton and a good place to start
101 | - V4R2 is, at the time of writing, the latest and greatest version that introduces plug-in functionality. Choose this if you want to have a future-proof wallet
102 |
103 | >It is important to note that basic functionality of all wallet versions is the same - you don't have to update whenever a new version comes out
104 |
105 | # Importing the mnemonic phrase
106 | After **vaniton** created a nice address for you, you can import the mnemonic phrase it generated into a wallet software of your liking. If version of the wallet contract is different than the software's default (i.e. not V3R2), then your wallet software will show you a completely different address. Fear not, once you deposit some funds to the address generated by **vaniton**, your wallet software should recognize that and switch to use it (re-importing your mnemonic phrase might be necessary).
107 |
108 | Be aware, that some wallet software may implement automatic wallet smart contract upgrades by sending funds from an older version to a newer version, which can completely ruin the purpose of using **vaniton** to generate the address.
109 |
110 | # Donations
111 | Donations will help me to work on improvement of this project!
112 | Feel free to drop a few TON cents to the following address:
113 | > EQAnTon5VVNKup8v0EUT0SvCKsRmEpotr_3eSpqYJTneIVht
114 |
115 | Yes, this address was in fact generated by **vaniton** over a course of a few days :)
116 |
--------------------------------------------------------------------------------
/source/addresses.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Ada.Unchecked_Conversion;
4 |
5 | with Base64; use Base64;
6 |
7 | package body Addresses is
8 | function Convert is new Ada.Unchecked_Conversion (Integer_8, Unsigned_8);
9 | function Get_Tag
10 | (Test_Only : Boolean; Bounceable : Boolean) return Unsigned_8;
11 | function CRC16 (Data : Address) return Byte_Array;
12 |
13 | function Get_Tag
14 | (Test_Only : Boolean; Bounceable : Boolean) return Unsigned_8
15 | is
16 | Tag : Unsigned_8 := 0;
17 | begin
18 | if Test_Only then
19 | Tag := Unsigned_8 (16#80#);
20 | end if;
21 |
22 | if Bounceable then
23 | Tag := Tag or Unsigned_8 (16#11#);
24 | else
25 | Tag := Tag or Unsigned_8 (16#51#);
26 | end if;
27 | return Tag;
28 | end Get_Tag;
29 |
30 | function CRC16 (Data : Address) return Byte_Array is
31 | Binary_Data : Byte_Array (1 .. 34);
32 | begin
33 |
34 | Binary_Data (1) := Get_Tag (Data.Test_Only, Data.Bounceable);
35 | Binary_Data (2) := Convert (Data.Workchain);
36 | Binary_Data (3 .. 34) := Data.Hash_Part;
37 | return CRC16 (Binary_Data);
38 | end CRC16;
39 |
40 | function Create (Addr : String) return Address is
41 | Result : Address;
42 | begin
43 | Create (Result, Addr);
44 | return Result;
45 | end Create;
46 |
47 | procedure Create (This : in out Address; Addr : String) is
48 | Data : constant Byte_Array := From_Base64 (Addr);
49 |
50 | function Convert is new Ada.Unchecked_Conversion (Unsigned_8, Integer_8);
51 | begin
52 | if Data'Length /= 36 then
53 | raise Address_Error
54 | with "Unknown address type: byte length is not equal to 36";
55 | end if;
56 |
57 | declare
58 | Address_Part : constant Byte_Array := Data (1 .. 34);
59 | CRC : constant Byte_Array := Data (35 .. 36);
60 | Calculated_CRC : constant Byte_Array := CRC16 (Address_Part);
61 | Tag : Unsigned_8 := Address_Part (1);
62 | Workchain : constant Integer_8 := Convert (Address_Part (2));
63 |
64 | Test_Only : Boolean := False;
65 | Bounceable : Boolean := False;
66 | begin
67 | if CRC /= Calculated_CRC then
68 | raise Address_Error with "Wrong CRC16 checksum";
69 | end if;
70 |
71 | if (Tag and Unsigned_8 (16#80#)) = 1 then
72 | Test_Only := True;
73 | Tag := Tag and not Unsigned_8 (16#80#);
74 | end if;
75 |
76 | if Tag /= Unsigned_8 (16#11#) and then Tag /= Unsigned_8 (16#51#) then
77 | raise Address_Error with "Unknown address tag";
78 | end if;
79 |
80 | Bounceable := Tag = Unsigned_8 (16#11#);
81 |
82 | if Workchain /= 0 and then Workchain /= -1 then
83 | raise Address_Error with "Invalid address workchain";
84 | end if;
85 |
86 | This.Test_Only := Test_Only;
87 | This.Bounceable := Bounceable;
88 | This.Workchain := Workchain;
89 | This.Hash_Part := Address_Part (3 .. 34);
90 | This.CRC := CRC;
91 | end;
92 | end Create;
93 |
94 | function Create
95 | (Test_Only : Boolean; Bounceable : Boolean; Workchain : Integer_8;
96 | Hash_Part : Byte_Array) return Address
97 | is
98 | Result : Address;
99 | begin
100 | Create (Result, Test_Only, Bounceable, Workchain, Hash_Part);
101 | return Result;
102 | end Create;
103 |
104 | procedure Create
105 | (This : in out Address; Test_Only : Boolean; Bounceable : Boolean;
106 | Workchain : Integer_8; Hash_Part : Byte_Array)
107 | is
108 | begin
109 | This.Test_Only := Test_Only;
110 | This.Bounceable := Bounceable;
111 | This.Workchain := Workchain;
112 | This.Hash_Part := Hash_Part;
113 | This.CRC := CRC16 (This);
114 | end Create;
115 |
116 | function Is_Valid (Addr : String) return Boolean is
117 | Temporary : Address;
118 | begin
119 | Create (Temporary, Addr);
120 | return True;
121 | exception
122 | when others =>
123 | return False;
124 | end Is_Valid;
125 |
126 | function Is_Bounceable (This : in Address) return Boolean is
127 | (This.Bounceable);
128 | function Is_Test_Only (This : in Address) return Boolean is
129 | (This.Test_Only);
130 |
131 | function To_String
132 | (This : Address; User_Friendly : Boolean := True;
133 | Url_Safe : Boolean := True; Bounceable : Triboolean := Indeterminate;
134 | Test_Only : Triboolean := Indeterminate) return String
135 | is
136 | Data : Byte_Array (1 .. 36);
137 | begin
138 | if User_Friendly then
139 | Data (1) :=
140 | Get_Tag
141 | ((if Test_Only = Indeterminate then This.Test_Only
142 | else To_Boolean (Test_Only)),
143 | (if Bounceable = Indeterminate then This.Bounceable
144 | else To_Boolean (Bounceable)));
145 | Data (2) := Convert (This.Workchain);
146 | Data (3 .. 34) := This.Hash_Part;
147 | Data (35 .. 36) := This.CRC;
148 |
149 | if Url_Safe then
150 | return To_Base64Url (Data);
151 | else
152 | return To_Base64 (Data);
153 | end if;
154 | else
155 | return This.Workchain'Image & ":" & To_Hex_String (This.Hash_Part);
156 | end if;
157 |
158 | end To_String;
159 | end Addresses;
160 |
--------------------------------------------------------------------------------
/source/addresses.ads:
--------------------------------------------------------------------------------
1 | with Types; use Types;
2 | with Interfaces; use Interfaces;
3 |
4 | package Addresses is
5 | type Address is private;
6 | Address_Error : exception;
7 |
8 | function Create (Addr : String) return Address;
9 | procedure Create (This : in out Address; Addr : String);
10 | function Create
11 | (Test_Only : Boolean; Bounceable : Boolean; Workchain : Integer_8;
12 | Hash_Part : Byte_Array) return Address;
13 | procedure Create
14 | (This : in out Address; Test_Only : Boolean; Bounceable : Boolean;
15 | Workchain : Integer_8; Hash_Part : Byte_Array);
16 |
17 | function Is_Valid (Addr : String) return Boolean;
18 | function Is_Bounceable (This : in Address) return Boolean;
19 | function Is_Test_Only (This : in Address) return Boolean;
20 |
21 | function To_String
22 | (This : Address; User_Friendly : Boolean := True;
23 | Url_Safe : Boolean := True; Bounceable : Triboolean := Indeterminate;
24 | Test_Only : Triboolean := Indeterminate) return String;
25 | private
26 | type Address is record
27 | Test_Only : Boolean := False;
28 | Bounceable : Boolean := False;
29 | Workchain : Integer_8;
30 | Hash_Part : Byte_Array (1 .. 32);
31 | CRC : Byte_Array (1 .. 2);
32 | end record;
33 | end Addresses;
34 |
--------------------------------------------------------------------------------
/source/base64.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Ada.Strings.Fixed;
4 |
5 | with Interfaces; use Interfaces;
6 |
7 | package body Base64 is
8 | PAD_CHAR : constant Character := '=';
9 | DE_FIRST : constant Character := '+';
10 | DE_LAST : constant Character := 'z';
11 |
12 | type Character_Array is array (Natural range <>) of Character;
13 | type Unsigned_8_Array is array (Natural range <>) of Unsigned_8;
14 |
15 | Encoding_Table : constant Character_Array (0 .. 63) :=
16 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
17 |
18 | pragma Style_Checks (Off);
19 | --!pp off
20 | Decoding_Table : constant Unsigned_8_Array (0 .. 127) :=
21 | (
22 | -- nul, soh, stx, etx, eot, enq, ack, bel,
23 | 255, 255, 255, 255, 255, 255, 255, 255,
24 | -- bs, ht, nl, vt, np, cr, so, si,
25 | 255, 255, 255, 255, 255, 255, 255, 255,
26 | -- dle, dc1, dc2, dc3, dc4, nak, syn, etb,
27 | 255, 255, 255, 255, 255, 255, 255, 255,
28 | -- can, em, sub, esc, fs, gs, rs, us,
29 | 255, 255, 255, 255, 255, 255, 255, 255,
30 | -- sp, '!', '"', '#', '$', '%', '&', ''',
31 | 255, 255, 255, 255, 255, 255, 255, 255,
32 | -- '(', ')', '*', '+', ',', '-', '.', '/',
33 | 255, 255, 255, 62, 255, 255, 255, 63,
34 | -- '0', '1', '2', '3', '4', '5', '6', '7',
35 | 52, 53, 54, 55, 56, 57, 58, 59,
36 | -- '8', '9', ':', ';', '<', '=', '>', '?',
37 | 60, 61, 255, 255, 255, 255, 255, 255,
38 | -- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
39 | 255, 0, 1, 2, 3, 4, 5, 6,
40 | -- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
41 | 7, 8, 9, 10, 11, 12, 13, 14,
42 | -- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
43 | 15, 16, 17, 18, 19, 20, 21, 22,
44 | -- 'X', 'Y', 'Z', '[', '\', ']', '^', '_',
45 | 23, 24, 25, 255, 255, 255, 255, 255,
46 | -- '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
47 | 255, 26, 27, 28, 29, 30, 31, 32,
48 | -- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
49 | 33, 34, 35, 36, 37, 38, 39, 40,
50 | -- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
51 | 41, 42, 43, 44, 45, 46, 47, 48,
52 | -- 'x', 'y', 'z', '{', '|', '}', '~', del,
53 | 49, 50, 51, 255, 255, 255, 255, 255
54 | );
55 | --!pp on
56 | pragma Style_Checks (On);
57 |
58 | function From_Base64 (Input : String) return Byte_Array is
59 | Result : Byte_Array
60 | (1 .. Input'Length * 2); -- TODO: optimize stack usage here
61 | Index : Natural := Input'First;
62 | Current : Unsigned_8;
63 | begin
64 | if (Unsigned_32 (Input'Length) and Unsigned_32 (16#3#)) /= 0 then
65 | raise Base64_Error with "Invalid base64 string length";
66 | end if;
67 |
68 | for I in Input'Range loop
69 | exit when Input (I) = PAD_CHAR;
70 |
71 | if Input (I) < DE_FIRST or else Input (I) > DE_LAST then
72 | raise Base64_Error with "Invalid base64 character";
73 | end if;
74 |
75 | Current := Decoding_Table (Character'Pos (Input (I)));
76 | if Current = 255 then
77 | raise Base64_Error with "Invalid base64 character";
78 | end if;
79 |
80 | case Unsigned_32 (I - Input'First) and Unsigned_32 (16#3#) is
81 | when 0 =>
82 | Result (Index) :=
83 | Shift_Left (Current, 2) and Unsigned_8 (16#FF#);
84 | when 1 =>
85 | Result (Index) :=
86 | Result (Index) or
87 | (Shift_Right (Current, 4) and Unsigned_8 (16#3#));
88 | Index := Index + 1;
89 | Result (Index) :=
90 | Shift_Left (Current and Unsigned_8 (16#F#), 4);
91 | when 2 =>
92 | Result (Index) :=
93 | Result (Index) or
94 | (Shift_Right (Current, 2) and Unsigned_8 (16#F#));
95 | Index := Index + 1;
96 | Result (Index) :=
97 | Shift_Left (Current and Unsigned_8 (16#3#), 6);
98 | when 3 =>
99 | Result (Index) := Result (Index) or Current;
100 | Index := Index + 1;
101 | when others =>
102 | raise Program_Error;
103 | end case;
104 | end loop;
105 |
106 | return Result (1 .. Index);
107 | end From_Base64;
108 |
109 | function To_Base64 (Input : Byte_Array) return String is
110 | Result : String
111 | (1 .. Input'Length * 2); -- TODO: optimize stack usage here
112 | Index : Natural := 0;
113 | Step : Natural := 0;
114 | Last : Unsigned_8 := 0;
115 | begin
116 | for Current of Input loop
117 | case Step is
118 | when 0 =>
119 | Step := 1;
120 | Index := Index + 1;
121 | Result (Index) :=
122 | Encoding_Table
123 | (Integer
124 | (Shift_Right (Current, 2) and Unsigned_8 (16#3F#)));
125 | when 1 =>
126 | Step := 2;
127 | Index := Index + 1;
128 | Result (Index) :=
129 | Encoding_Table
130 | (Integer
131 | (Shift_Left (Last and Unsigned_8 (16#3#), 4) or
132 | (Shift_Right (Current, 4) and Unsigned_8 (16#F#))));
133 | when 2 =>
134 | Step := 0;
135 | Result (Index + 1) :=
136 | Encoding_Table
137 | (Integer
138 | (Shift_Left (Last and Unsigned_8 (16#F#), 2) or
139 | (Shift_Right (Current, 6) and Unsigned_8 (16#3#))));
140 | Result (Index + 2) :=
141 | Encoding_Table (Integer (Current and Unsigned_8 (16#3F#)));
142 | Index := Index + 2;
143 | when others =>
144 | raise Program_Error;
145 | end case;
146 | Last := Current;
147 | end loop;
148 |
149 | case Step is
150 | when 1 =>
151 | Result (Index + 1) :=
152 | Encoding_Table
153 | (Integer (Shift_Left (Last and Unsigned_8 (16#3#), 4)));
154 | Result (Index + 2) := PAD_CHAR;
155 | Result (Index + 3) := PAD_CHAR;
156 | Index := Index + 3;
157 | when 2 =>
158 | Result (Index + 1) :=
159 | Encoding_Table
160 | (Integer (Shift_Left (Last and Unsigned_8 (16#F#), 2)));
161 | Result (Index + 2) := PAD_CHAR;
162 | Index := Index + 2;
163 | when others =>
164 | null;
165 | end case;
166 |
167 | return Result (1 .. Index);
168 | end To_Base64;
169 |
170 | function Mapping (From : in Character) return Character;
171 |
172 | function To_Base64Url (Input : Byte_Array) return String is
173 | (Ada.Strings.Fixed.Translate (To_Base64 (Input), Mapping'Access));
174 |
175 | function Mapping (From : in Character) return Character is
176 | begin
177 | case From is
178 | when '+' =>
179 | return '-';
180 | when '/' =>
181 | return '_';
182 | when others =>
183 | return From;
184 | end case;
185 | end Mapping;
186 | end Base64;
187 |
--------------------------------------------------------------------------------
/source/base64.ads:
--------------------------------------------------------------------------------
1 | with Types; use Types;
2 |
3 | package Base64 is
4 | Base64_Error : exception;
5 |
6 | function From_Base64 (Input : String) return Byte_Array;
7 | function To_Base64 (Input : Byte_Array) return String;
8 | function To_Base64Url (Input : Byte_Array) return String;
9 | end Base64;
10 |
--------------------------------------------------------------------------------
/source/benchmark.adb:
--------------------------------------------------------------------------------
1 | with Ada.Calendar; use Ada.Calendar;
2 | with Ada.Exceptions; use Ada.Exceptions;
3 | with Ada.Text_IO; use Ada.Text_IO;
4 |
5 | with GNAT.Command_Line; use GNAT.Command_Line;
6 | with GNAT.Formatted_String; use GNAT.Formatted_String;
7 | with GNAT.OS_Lib;
8 | with GNAT.Regexp; use GNAT.Regexp;
9 |
10 | with Wallets;
11 | with Workers; use Workers;
12 |
13 | procedure Benchmark is
14 | Config : Command_Line_Configuration;
15 | Number_Of_Workers : aliased Integer;
16 | Iterations : aliased Integer;
17 |
18 | type Worker_Array_Type is array (Natural range <>) of Worker;
19 | type Worker_Array_Access is access all Worker_Array_Type;
20 | Worker_Array : Worker_Array_Access := null;
21 | begin
22 | Set_Usage
23 | (Config, Usage => "[switches]",
24 | Help =>
25 | "Benchmark for vaniton, the vanity generator for TON" & ASCII.LF &
26 | "Part of project vaniton: " &
27 | ASCII.LF);
28 |
29 | Define_Switch
30 | (Config, Number_Of_Workers'Access, "-j:", "--threads=",
31 | "Number of working threads running in parallel", Initial => 1);
32 | Define_Switch
33 | (Config, Iterations'Access, "-n:", "--iterations=",
34 | "Number of iterations", Initial => 100);
35 |
36 | Getopt (Config);
37 |
38 | Worker_Array :=
39 | new Worker_Array_Type (0 .. Natural (Number_Of_Workers) - 1);
40 | for I in Worker_Array.all'Range loop
41 | Worker_Array.all (I).Start (Wallets.V3_R2, False, True, "", False);
42 | end loop;
43 |
44 | declare
45 | Start_Time : constant Time := Clock;
46 | Index : Natural := 0;
47 | Temporary : Work_Unit;
48 | Taken : Duration;
49 | begin
50 | Put_Line
51 | (-
52 | (+"[benchmark] Measuring address generation speed (%d iterations)..." &
53 | Iterations));
54 | loop
55 | exit when Index = Iterations;
56 | Work_Queue.Dequeue (Temporary);
57 | Index := Index + 1;
58 | end loop;
59 |
60 | Taken := Clock - Start_Time;
61 | Put_Line
62 | (-
63 | (+"[benchmark] It took %fs; %f addresses/sec; %f addressses/(sec*thread)" &
64 | Taken & ((Iterations * 1.0) / Taken) &
65 | ((Iterations * 1.0) / Taken / Number_Of_Workers)));
66 | end;
67 |
68 | declare
69 | type Regexp_Array is array (Positive range <>) of Regexp;
70 |
71 | Expressions : constant Regexp_Array (1 .. 5) :=
72 | (Compile (".*a.*"), Compile (".*ab.*"), Compile (".*abc.*"),
73 | Compile (".*abcd.*"), Compile (".*abcde.*"));
74 |
75 | Start_Time : Time := Clock;
76 | Current : Work_Unit;
77 | Currently_Matching : Positive := 1;
78 | Index : Integer := 1;
79 | begin
80 | Put_Line ("[benchmark] Measuring time it takes to match N characters");
81 |
82 | loop
83 | Work_Queue.Dequeue (Current);
84 |
85 | if Match (Current.Address, Expressions (Currently_Matching)) then
86 | declare
87 | Taken : constant Duration := Clock - Start_Time;
88 | begin
89 | Put_Line
90 | (-
91 | (+("[benchmark] Matched %d character(s) in %fs after %d " &
92 | "attempts; %f addresses/sec; %f addresses/(sec*thread).") &
93 | Currently_Matching & Taken & Index &
94 | ((Index * 1.0) / Taken) &
95 | ((Index * 1.0) / Taken / Number_Of_Workers)));
96 |
97 | Start_Time := Clock;
98 | Currently_Matching := Currently_Matching + 1;
99 | end;
100 | end if;
101 |
102 | Index := Index + 1;
103 | exit when Currently_Matching > 5;
104 | end loop;
105 | end;
106 |
107 | Control.Signal_Stop;
108 | exception
109 | when Exit_From_Command_Line =>
110 | GNAT.OS_Lib.OS_Exit (0); -- All chill
111 | when Error : others =>
112 | Put (Exception_Information (Error));
113 | GNAT.OS_Lib.OS_Exit (-1);
114 | end Benchmark;
115 |
--------------------------------------------------------------------------------
/source/cells.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Ada.Unchecked_Conversion;
4 | with Ada.Unchecked_Deallocation;
5 |
6 | with Cryptography;
7 |
8 | package body Cells is
9 | function Empty_Cell return Cell is
10 | Result : Cell;
11 | begin
12 | return Result;
13 | end Empty_Cell;
14 |
15 | function From_BoC (Data : String) return Cell is
16 | (From_BoC (From_Hex_String (Data)));
17 |
18 | function From_BoC (Data : Byte_Array) return Cell is
19 | Magic : constant Byte_Array (1 .. 4) := From_Hex_String ("b5ee9c72");
20 |
21 | Index : Positive := 1;
22 |
23 | has_idx, hash_crc32, has_cache_bits : Boolean := False;
24 | flags, size_bytes, offset_bytes : Unsigned_8 := 0;
25 |
26 | cells_num, roots_num, absent_num, tot_cells_size : Unsigned_32;
27 |
28 | function Read_NBytes
29 | (A : Byte_Array; I : Positive; N : Unsigned_8) return Unsigned_32
30 | is
31 | R : Unsigned_32 := 0;
32 | begin
33 | for B of A (I .. I + Positive (N) - 1) loop
34 | R := R * 256;
35 | R := R + Unsigned_32 (B);
36 | end loop;
37 | return R;
38 | end Read_NBytes;
39 | begin
40 | if Data (1 .. 4) /= Magic then
41 | raise Cell_Error with "Invalid magic number";
42 | end if;
43 | Index := Index + 4;
44 |
45 | has_idx := (Data (Index) and 128) /= 0;
46 | hash_crc32 := (Data (Index) and 64) /= 0;
47 | has_cache_bits := (Data (Index) and 32) /= 0;
48 | flags := (Data (Index) and 16) * 2 + (Data (Index) and 8);
49 | size_bytes := Data (Index) rem 8;
50 | Index := Index + 1;
51 |
52 | offset_bytes := Data (Index);
53 | Index := Index + 1;
54 | cells_num := Read_NBytes (Data, Index, size_bytes);
55 | Index := Index + Positive (size_bytes);
56 | roots_num := Read_NBytes (Data, Index, size_bytes);
57 | Index := Index + Positive (size_bytes);
58 | absent_num := Read_NBytes (Data, Index, size_bytes);
59 | Index := Index + Positive (size_bytes);
60 | tot_cells_size := Read_NBytes (Data, Index, offset_bytes);
61 | Index := Index + Positive (offset_bytes);
62 |
63 | declare
64 | type Root_List_Type is array (Positive range <>) of Unsigned_32;
65 | root_list : Root_List_Type (1 .. Positive (roots_num));
66 |
67 | type Index_List_Type is array (Positive range <>) of Unsigned_32;
68 | index_list : Index_List_Type (1 .. Positive (cells_num));
69 |
70 | cells_data : Byte_Array (1 .. Positive (tot_cells_size));
71 |
72 | type Cell_Array_Type is array (Positive range <>) of Cell;
73 | cells_array : Cell_Array_Type (1 .. Positive (cells_num));
74 |
75 | type Cell_Reference_Array is array (Positive range <>) of Unsigned_32;
76 | type Cell_Reference_Map is
77 | array (Positive range <>) of Cell_Reference_Array (1 .. 4);
78 | cells_reference : Cell_Reference_Map (1 .. Positive (cells_num)) :=
79 | (others => (others => Unsigned_32'Last));
80 |
81 | Cells_Data_Index : Positive := 1;
82 | begin
83 | for I in 1 .. Positive (roots_num) loop
84 | root_list (I) := Read_NBytes (Data, Index, size_bytes);
85 | Index := Index + Positive (size_bytes);
86 | end loop;
87 |
88 | if has_idx then
89 | for I in 1 .. Positive (cells_num) loop
90 | index_list (I) := Read_NBytes (Data, Index, offset_bytes);
91 | Index := Index + Positive (offset_bytes);
92 | end loop;
93 | end if;
94 |
95 | cells_data := Data (Index .. Index + Positive (tot_cells_size) - 1);
96 | Index := Index + Positive (tot_cells_size);
97 |
98 | for I in 1 .. Positive (cells_num) loop
99 | declare
100 | D1 : Unsigned_8 := cells_data (Cells_Data_Index);
101 | D2 : Unsigned_8 := cells_data (Cells_Data_Index + 1);
102 |
103 | Reference_Number : Unsigned_8 := D1 rem 8;
104 | Data_Bytes_Size : Unsigned_8 :=
105 | Unsigned_8 (Float'Ceiling (Float (D2) / Float (2)));
106 | Fullfilled_Bytes : Boolean := (D2 rem 2) = 0;
107 | begin
108 | Cells_Data_Index := Cells_Data_Index + 2;
109 |
110 | cells_array (I).Data.all.Bits
111 | (1 .. Positive (Data_Bytes_Size) * 8) :=
112 | To_Bit_Array
113 | (cells_data
114 | (Cells_Data_Index ..
115 | Cells_Data_Index + Positive (Data_Bytes_Size) - 1));
116 | if Fullfilled_Bytes then
117 | cells_array (I).Data.all.Length :=
118 | Natural (Data_Bytes_Size) * 8;
119 | else
120 | for L in reverse 1 .. Positive (Data_Bytes_Size) * 8 loop
121 | if cells_array (I).Data.all.Bits (L) then
122 | cells_array (I).Data.all.Bits (L) := False;
123 | cells_array (I).Data.all.Length := L - 1;
124 | exit;
125 | end if;
126 | end loop;
127 | end if;
128 | Cells_Data_Index :=
129 | Cells_Data_Index + Positive (Data_Bytes_Size);
130 |
131 | for L in 1 .. Reference_Number loop
132 | cells_reference (I) (Integer (L)) :=
133 | (Read_NBytes (cells_data, Cells_Data_Index, size_bytes));
134 | Cells_Data_Index := Cells_Data_Index + Positive (size_bytes);
135 | end loop;
136 | end;
137 | end loop;
138 |
139 | for I in reverse 1 .. Positive (cells_num) loop
140 | for R of cells_reference (I) loop
141 | exit when R = Unsigned_32'Last;
142 | Append_Reference
143 | (cells_array (I), cells_array (Integer (R) + 1));
144 | end loop;
145 | end loop;
146 |
147 | if hash_crc32 then
148 | -- todo we actually don't check shit here
149 | Index := Index + 4;
150 | end if;
151 |
152 | if Index /= Data'Length + 1 then
153 | raise Cell_Error with "Too much data for BoC deserialization";
154 | end if;
155 |
156 | return cells_array (1);
157 | end;
158 | end From_BoC;
159 |
160 | function Get_Max_Level (This : in out Cell_Data) return Unsigned_8 is
161 | -- Idk why this exists, it always just returns zero duh
162 | Max_Level : Unsigned_8 := 0;
163 | begin
164 | for I in This.Cell_References'Range loop
165 | exit when This.Cell_References (I) = null;
166 | declare
167 | Inner_Level : Unsigned_8 :=
168 | Get_Max_Level (This.Cell_References (I).all);
169 | begin
170 | if Inner_Level > Max_Level then
171 | Max_Level := Inner_Level;
172 | end if;
173 | end;
174 | end loop;
175 | return Max_Level;
176 | end Get_Max_Level;
177 |
178 | function Get_Max_Depth (This : in out Cell_Data) return Unsigned_16 is
179 | Max_Depth : Unsigned_16 := 0;
180 | begin
181 | for I in This.Cell_References'Range loop
182 | exit when This.Cell_References (I) = null;
183 | declare
184 | Inner_Depth : Unsigned_16 :=
185 | Get_Max_Depth (This.Cell_References (I).all);
186 | begin
187 | if Inner_Depth > Max_Depth then
188 | Max_Depth := Inner_Depth;
189 | end if;
190 | end;
191 | end loop;
192 |
193 | if This.Cell_References (1) /= null then
194 | Max_Depth := Max_Depth + 1;
195 | end if;
196 |
197 | return Max_Depth;
198 | end Get_Max_Depth;
199 |
200 | function Hash (This : in out Cell_Data) return Byte_Array;
201 |
202 | function Representation (This : in out Cell_Data) return Byte_Array is
203 | Number_Of_References : Natural := 0;
204 | Index : Natural := 1;
205 |
206 | Data_Length : constant Natural := Padded_Length (This.Length) / 8;
207 | begin
208 | for I in This.Cell_References'Range loop
209 | exit when This.Cell_References (I) = null;
210 | Number_Of_References := Number_Of_References + 1;
211 | end loop;
212 |
213 | declare
214 | Result : Byte_Array
215 | (1 ..
216 | 2 + Data_Length + 2 * Number_Of_References +
217 | 32 * Number_Of_References) :=
218 | (others => 0);
219 |
220 | Padded : Bit_Array (1 .. Padded_Length (This.Length)) :=
221 | Pad (This.Bits (1 .. This.Length));
222 | begin
223 | -- First byte - reference descriptor
224 | Result (Index) :=
225 | Unsigned_8 (Number_Of_References) +
226 | -- This.Is_Exotic * 8 + -- Completely useless for our purposes
227 | Get_Max_Level (This) * 32; -- Also does nothing, always 0
228 | Index := Index + 1;
229 | -- Second byte - bits descriptor
230 | Result (Index) :=
231 | Unsigned_8 (Float'Ceiling (Float (This.Length) / Float (8))) +
232 | Unsigned_8 (Float'Floor (Float (This.Length) / Float (8)));
233 | Index := Index + 1;
234 |
235 | -- Padded data
236 | if Padded'Length /= This.Length then
237 | Padded (This.Length + 1) := True;
238 | end if;
239 | Result (Index .. Index + Data_Length - 1) := To_Byte_Array (Padded);
240 | Index := Index + Data_Length;
241 |
242 | for I in 1 .. Number_Of_References loop
243 | declare
244 | Max_Depth : Unsigned_16 :=
245 | Get_Max_Depth (This.Cell_References (I).all);
246 | begin
247 | Result (Index) :=
248 | Unsigned_8 (Float'Floor (Float (Max_Depth) / Float (256)));
249 | Result (Index + 1) := Unsigned_8 (Max_Depth rem 256);
250 | Index := Index + 2;
251 | end;
252 | end loop;
253 |
254 | for I in 1 .. Number_Of_References loop
255 | Result (Index .. Index + 31) :=
256 | Hash (This.Cell_References (I).all);
257 | Index := Index + 32;
258 | end loop;
259 | return Result;
260 | end;
261 | end Representation;
262 |
263 | function Representation (This : in out Cell) return Byte_Array is
264 | (Representation (This.Data.all));
265 |
266 | function Hash (This : in out Cell_Data) return Byte_Array is
267 | (Cryptography.SHA256 (Representation (This)));
268 |
269 | function Hash (This : in out Cell) return Byte_Array is
270 | (Hash (This.Data.all));
271 |
272 | procedure Append_Reference (This : in out Cell; Other : in Cell) is
273 | begin
274 | for I in This.Data.all.Cell_References'Range loop
275 | if This.Data.all.Cell_References (I) = null then
276 | This.Data.all.Cell_References (I) := Other.Data;
277 | Increment (Other.Data.all.Reference_Count);
278 | return;
279 | end if;
280 | end loop;
281 | raise Cell_Error with "Cannot append any more elements to the cell";
282 | end Append_Reference;
283 |
284 | procedure Write (This : in out Cell; Data : Cell) is
285 | begin
286 | Write (This, Data.Data.all.Bits (1 .. Data.Data.all.Length));
287 | end Write;
288 |
289 | procedure Write (This : in out Cell; Data : Bit_Array) is
290 | begin
291 | This.Data.all.Bits
292 | (This.Data.all.Length + 1 .. This.Data.all.Length + Data'Length) :=
293 | Data;
294 | This.Data.all.Length := This.Data.all.Length + Data'Length;
295 | end Write;
296 |
297 | procedure Write (This : in out Cell; Data : Byte_Array) is
298 | begin
299 | Write (This, To_Bit_Array (Data));
300 | end Write;
301 |
302 | procedure Write (This : in out Cell; Data : Unsigned_32) is
303 | subtype Output_Type is Byte_Array (1 .. 4);
304 | function Convert is new Ada.Unchecked_Conversion
305 | (Unsigned_32, Output_Type);
306 | begin
307 | Write (This, Reverse_Bytes (Convert (Data)));
308 | end Write;
309 |
310 | procedure Write (This : in out Cell; Data : Boolean) is
311 | begin
312 | This.Data.all.Bits (This.Data.all.Length + 1) := Data;
313 | This.Data.all.Length := This.Data.all.Length + 1;
314 | end Write;
315 |
316 | procedure Initialize (This : in out Cell) is
317 | begin
318 | This.Data := new Cell_Data;
319 | end Initialize;
320 |
321 | procedure Adjust (This : in out Cell) is
322 | begin
323 | Increment (This.Data.all.Reference_Count);
324 | end Adjust;
325 |
326 | procedure Decrement (This : in out Cell_Data_Access) is
327 | procedure Deallocate is new Ada.Unchecked_Deallocation
328 | (Cell_Data, Cell_Data_Access);
329 | begin
330 | if Decrement (This.all.Reference_Count) then
331 | for I in This.all.Cell_References'Range loop
332 | if This.all.Cell_References (I) /= null then
333 | Decrement (This.all.Cell_References (I));
334 | This.all.Cell_References (I) := null;
335 | end if;
336 | end loop;
337 |
338 | Deallocate (This);
339 | This := null;
340 | end if;
341 | end Decrement;
342 |
343 | procedure Finalize (This : in out Cell) is
344 | begin
345 | Decrement (This.Data);
346 | end Finalize;
347 | end Cells;
348 |
--------------------------------------------------------------------------------
/source/cells.ads:
--------------------------------------------------------------------------------
1 | with Ada.Finalization;
2 |
3 | with System.Atomic_Counters; use System.Atomic_Counters;
4 |
5 | with Interfaces; use Interfaces;
6 |
7 | with Types; use Types;
8 |
9 | package Cells is
10 | type Cell is new Ada.Finalization.Controlled with private;
11 |
12 | function Empty_Cell return Cell;
13 |
14 | Cell_Error : exception;
15 |
16 | function From_BoC (Data : String) return Cell;
17 | function From_BoC (Data : Byte_Array) return Cell;
18 |
19 | function Representation (This : in out Cell) return Byte_Array;
20 | function Hash (This : in out Cell) return Byte_Array;
21 |
22 | procedure Append_Reference (This : in out Cell; Other : in Cell);
23 |
24 | procedure Write (This : in out Cell; Data : Cell);
25 | procedure Write (This : in out Cell; Data : Bit_Array);
26 | procedure Write (This : in out Cell; Data : Byte_Array);
27 | procedure Write (This : in out Cell; Data : Unsigned_32);
28 | procedure Write (This : in out Cell; Data : Boolean);
29 | private
30 | type Cell_Data;
31 | type Cell_Data_Access is access all Cell_Data;
32 | type Cell_Data_Array is array (Positive range <>) of Cell_Data_Access;
33 |
34 | type Cell_Data is record
35 | Reference_Count : aliased Atomic_Unsigned := 1;
36 | Bits : Bit_Array (1 .. 1_023) := (others => False);
37 | Length : Natural := 0;
38 | Cell_References : Cell_Data_Array (1 .. 4) := (others => null);
39 | end record;
40 |
41 | type Cell is new Ada.Finalization.Controlled with record
42 | Data : Cell_Data_Access;
43 | end record;
44 |
45 | procedure Initialize (This : in out Cell);
46 | procedure Adjust (This : in out Cell);
47 | procedure Finalize (This : in out Cell);
48 | end Cells;
49 |
--------------------------------------------------------------------------------
/source/cryptography.adb:
--------------------------------------------------------------------------------
1 | with Ada.Unchecked_Conversion;
2 | with Ada.Streams;
3 | with Interfaces.C;
4 | with Interfaces.C.Extensions;
5 |
6 | with System;
7 |
8 | with GNAT.SHA256; use GNAT.SHA256;
9 |
10 | with SPARKNaCl.Sign;
11 | with SPARKNaCl;
12 |
13 | package body Cryptography is
14 |
15 | function HMAC_SHA512 (Phrase : String; Password : String) return Byte_Array
16 | is
17 | use System;
18 | use Interfaces.C;
19 | use Interfaces.C.Extensions;
20 |
21 | Phrase_Bytes : aliased Byte_Array := To_Byte_Array (Phrase);
22 | Password_Bytes : aliased Byte_Array := To_Byte_Array (Password);
23 |
24 | Result : aliased Byte_Array (1 .. 64);
25 | Written : aliased size_t := 0;
26 |
27 | function EVP_sha512 return void_ptr with
28 | Import => True,
29 | Convention => C,
30 | External_Name => "EVP_sha512";
31 |
32 | function HMAC
33 | (evp_md : void_ptr; key : access Interfaces.Unsigned_8;
34 | key_len : size_t; d : access Interfaces.Unsigned_8; n : size_t;
35 | md : access Interfaces.Unsigned_8; md_len : access size_t)
36 | return void_ptr with
37 | Import => True,
38 | Convention => C,
39 | External_Name => "HMAC";
40 | begin
41 | if Password'Length /= 0 then
42 | Password_Bytes := To_Byte_Array (Password);
43 | end if;
44 |
45 | if HMAC
46 | (EVP_sha512, Phrase_Bytes (Phrase_Bytes'First)'Access,
47 | Phrase_Bytes'Length,
48 | (if Password'Length /= 0 then
49 | Password_Bytes (Password_Bytes'First)'Access
50 | else null),
51 | Password'Length, Result (1)'Access, Written'Access) =
52 | Null_Address
53 | then
54 | raise Program_Error;
55 | end if;
56 |
57 | if Written /= Result'Length then
58 | raise Program_Error;
59 | end if;
60 |
61 | return Result;
62 | end HMAC_SHA512;
63 |
64 | function PBKDF2_SHA512
65 | (Key : Byte_Array; Salt : String; Iterations : Positive) return Byte_Array
66 | is
67 | use Interfaces.C;
68 |
69 | Salt_Bytes : aliased Byte_Array := To_Byte_Array (Salt);
70 | Key_Copy : aliased Byte_Array := Key;
71 |
72 | Result : aliased Byte_Array (1 .. 64);
73 |
74 | procedure fastpbkdf2_hmac_sha512
75 | (pw : access Unsigned_8; npw : size_t; salt_1 : access Unsigned_8;
76 | nsalt : size_t; iterations_1 : Unsigned_32; c_out : access Unsigned_8;
77 | nout : size_t) with
78 | Import => True,
79 | Convention => C,
80 | External_Name => "fastpbkdf2_hmac_sha512";
81 | begin
82 | fastpbkdf2_hmac_sha512
83 | (Key_Copy (Key_Copy'First)'Access, Key_Copy'Length,
84 | Salt_Bytes (Salt_Bytes'First)'Access, Salt_Bytes'Length,
85 | Unsigned_32 (Iterations), Result (1)'Access, Result'Length);
86 | return Result;
87 | end PBKDF2_SHA512;
88 |
89 | function SHA256 (Data : Byte_Array) return Byte_Array is
90 | use Ada.Streams;
91 |
92 | subtype Buffer_Type is Stream_Element_Array (1 .. Data'Length);
93 | function To_Stream_Element_Array is new Ada.Unchecked_Conversion
94 | (Byte_Array, Buffer_Type);
95 |
96 | subtype Output_Type is Byte_Array (1 .. 32);
97 | function To_Output is new Ada.Unchecked_Conversion
98 | (Stream_Element_Array, Output_Type);
99 | begin
100 | return To_Output (Digest (To_Stream_Element_Array (Data)));
101 | end SHA256;
102 |
103 | function From_Seed (Seed : Byte_Array) return Key_Pair is
104 | use SPARKNaCl.Sign;
105 | use SPARKNaCl;
106 |
107 | subtype PK_Type is Byte_Array (1 .. 32);
108 | subtype SK_Type is Byte_Array (1 .. 64);
109 |
110 | Result : Key_Pair;
111 |
112 | PK : Signing_PK;
113 | SK : Signing_SK;
114 |
115 | function To_Bytes_32 is new Ada.Unchecked_Conversion
116 | (Byte_Array, Bytes_32);
117 | function Convert is new Ada.Unchecked_Conversion (Signing_PK, PK_Type);
118 | function Convert is new Ada.Unchecked_Conversion (Signing_SK, SK_Type);
119 | begin
120 | Keypair (To_Bytes_32 (Seed), PK, SK);
121 |
122 | Result.Public_Key := Convert (PK);
123 | Result.Secret_Key := Convert (SK);
124 |
125 | return Result;
126 | end From_Seed;
127 |
128 | use Interfaces.C;
129 | type uchar_array is array (Natural range <>) of aliased unsigned_char;
130 |
131 | function RAND_bytes (buf : access unsigned_char; num : int) return int with
132 | Import => True,
133 | Convention => C,
134 | External_Name => "RAND_bytes";
135 |
136 | function Get_Random return Unsigned_32 is
137 | Buffer : uchar_array (0 .. 3);
138 |
139 | function To_Unsigned_32 is new Ada.Unchecked_Conversion
140 | (uchar_array, Unsigned_32);
141 | begin
142 | if RAND_bytes (Buffer (0)'Access, Buffer'Length) /= 1 then
143 | raise Program_Error;
144 | end if;
145 | return To_Unsigned_32 (Buffer);
146 | end Get_Random;
147 |
148 | function Get_Random (Length : Positive) return Unsigned_16_Array is
149 | subtype Result_Type is Unsigned_16_Array (1 .. Length);
150 |
151 | Buffer : uchar_array (0 .. Length * 2 - 1);
152 |
153 | function To_Unsigned_16_Array is new Ada.Unchecked_Conversion
154 | (uchar_array, Result_Type);
155 | begin
156 | if RAND_bytes (Buffer (0)'Access, Buffer'Length) /= 1 then
157 | raise Program_Error;
158 | end if;
159 | return To_Unsigned_16_Array (Buffer);
160 | end Get_Random;
161 | end Cryptography;
162 |
--------------------------------------------------------------------------------
/source/cryptography.ads:
--------------------------------------------------------------------------------
1 | with Interfaces; use Interfaces;
2 |
3 | with Types; use Types;
4 |
5 | package Cryptography is
6 | PBKDF_ITERATIONS : constant Natural := 100_000;
7 | type Key_Pair is record
8 | Public_Key : Byte_Array (1 .. 32);
9 | Secret_Key : Byte_Array (1 .. 64);
10 | end record;
11 |
12 | function HMAC_SHA512 (Phrase : String; Password : String) return Byte_Array;
13 | function PBKDF2_SHA512
14 | (Key : Byte_Array; Salt : String; Iterations : Positive)
15 | return Byte_Array;
16 |
17 | function SHA256 (Data : Byte_Array) return Byte_Array;
18 |
19 | function From_Seed (Seed : Byte_Array) return Key_Pair;
20 |
21 | function Get_Random return Unsigned_32;
22 | function Get_Random (Length : Positive) return Unsigned_16_Array;
23 | end Cryptography;
24 |
--------------------------------------------------------------------------------
/source/mnemonic2address.adb:
--------------------------------------------------------------------------------
1 | with Ada.Exceptions; use Ada.Exceptions;
2 | with Ada.Text_IO; use Ada.Text_IO;
3 |
4 | with GNAT.Command_Line; use GNAT.Command_Line;
5 | with GNAT.OS_Lib;
6 |
7 | with Addresses; use Addresses;
8 | with Cryptography; use Cryptography;
9 | with Wallets; use Wallets;
10 | with Mnemonics; use Mnemonics;
11 | with Words; use Words.Bounded_Words;
12 |
13 | procedure Mnemonic2Address is
14 | Config : Command_Line_Configuration;
15 | begin
16 | Set_Usage
17 | (Config, Usage => "[switches] [mnemonic phrase]",
18 | Help =>
19 | "Tool to compute wallet address for the supplied mnemonic phrase." &
20 | ASCII.LF &
21 | "Part of vaniton project: " &
22 | ASCII.LF);
23 |
24 | Getopt (Config);
25 |
26 | declare
27 | Phrase : Mnemonic (1 .. 24);
28 | Keys : Key_Pair;
29 | begin
30 | for I in Phrase'Range loop
31 | Phrase (I) := To_Bounded_String (Get_Argument);
32 | end loop;
33 |
34 | if not Is_Valid (Phrase) then
35 | raise Program_Error with "Supplied mnemonic phrase is not valid";
36 | end if;
37 |
38 | Keys := To_Key_Pair (Phrase);
39 |
40 | for Kind in Wallet_Kind'Range loop
41 | for Test_Only in Boolean'Range loop
42 | for Bounceable in Boolean'Range loop
43 | Put (Kind'Image & " | ");
44 | if Test_Only then
45 | Put ("T | ");
46 | else
47 | Put ("M | ");
48 | end if;
49 |
50 | if Bounceable then
51 | Put ("B | ");
52 | else
53 | Put ("N | ");
54 | end if;
55 |
56 | Put_Line
57 | (To_String
58 | (Get_Wallet_Address
59 | (Public_Key => Keys.Public_Key, Kind => Kind,
60 | Test_Only => Test_Only, Bounceable => Bounceable)));
61 | end loop;
62 | end loop;
63 | end loop;
64 | end;
65 | exception
66 | when Exit_From_Command_Line =>
67 | GNAT.OS_Lib.OS_Exit (0); -- All chill
68 | when Error : others =>
69 | Put (Exception_Information (Error));
70 | GNAT.OS_Lib.OS_Exit (-1);
71 | end Mnemonic2Address;
72 |
--------------------------------------------------------------------------------
/source/mnemonics.adb:
--------------------------------------------------------------------------------
1 | with Ada.Strings.Fixed;
2 |
3 | with Interfaces; use Interfaces;
4 |
5 | package body Mnemonics is
6 | function Generate
7 | (Words_Count : Positive := 24; Password : String := "";
8 | List : Wordlist := English_Words) return Mnemonic
9 | is
10 | Result : Mnemonic (1 .. Words_Count);
11 |
12 | function Check_Validity return Boolean;
13 |
14 | function Check_Validity return Boolean is
15 | Entropy : constant Byte_Array := To_Entropy (Result);
16 | begin
17 | if Password'Length > 0 and then not Is_Password_Needed (Entropy) then
18 | return False;
19 | end if;
20 |
21 | return Is_Basic_Seed (Entropy);
22 | end Check_Validity;
23 | begin
24 | loop
25 | declare
26 | Random : constant Unsigned_16_Array := Get_Random (Words_Count);
27 | begin
28 | for I in Result'Range loop
29 | Result (I) :=
30 | List (Natural (Random (I) and Unsigned_16 (List'Last)));
31 | end loop;
32 | end;
33 |
34 | exit when Check_Validity;
35 | end loop;
36 |
37 | if not Is_Valid (Result, Password, List) then
38 | raise Program_Error; -- Debugging only
39 | end if;
40 |
41 | return Result;
42 | end Generate;
43 |
44 | function From_String (Input : String) return Mnemonic is
45 | use Ada.Strings.Fixed;
46 | use Words.Bounded_Words;
47 |
48 | Result : Mnemonic (1 .. Count (Input, " ") + 1);
49 | Current : Positive := 1;
50 | begin
51 | for I in Input'Range loop
52 | if Input (I) = ' ' then
53 | Current := Current + 1;
54 | else
55 | Append (Result (Current), Input (I));
56 | end if;
57 | end loop;
58 |
59 | return Result;
60 | end From_String;
61 |
62 | function To_String (This : Mnemonic) return String is
63 | use Words.Bounded_Words;
64 | Phrase_Length : Positive := This'Length - 1;
65 | begin
66 | for Word of This loop
67 | Phrase_Length := Phrase_Length + Length (Word);
68 | end loop;
69 |
70 | declare
71 | Result : String (1 .. Phrase_Length);
72 | I : Positive := 1;
73 | begin
74 | for Word of This loop
75 | for C in 1 .. Length (Word) loop
76 | Result (I) := Element (Word, C);
77 | I := I + 1;
78 | end loop;
79 | if I < Phrase_Length then
80 | Result (I) := ' ';
81 | I := I + 1;
82 | end if;
83 | end loop;
84 | return Result;
85 | end;
86 | end To_String;
87 |
88 | function Is_Valid
89 | (This : Mnemonic; Password : String := "";
90 | List : Wordlist := English_Words) return Boolean
91 | is
92 | begin
93 | for Word of This loop
94 | declare
95 | use Words.Bounded_Words;
96 | Found : Boolean := False;
97 | begin
98 | for List_Word of List loop
99 | if Word = List_Word then
100 | Found := True;
101 | end if;
102 | exit when Found;
103 | end loop;
104 |
105 | if not Found then
106 | return False;
107 | end if;
108 | end;
109 | end loop;
110 |
111 | declare
112 | Entropy : constant Byte_Array := To_Entropy (This, Password);
113 | begin
114 | if Password'Length > 0 and then not Is_Password_Needed (Entropy) then
115 | return False;
116 | end if;
117 |
118 | return Is_Basic_Seed (Entropy);
119 | end;
120 | end Is_Valid;
121 |
122 | function To_Entropy
123 | (This : Mnemonic; Password : String := "") return Byte_Array is
124 | (HMAC_SHA512 (To_String (This), Password));
125 |
126 | function To_Seed
127 | (This : Mnemonic; Password : String := "") return Byte_Array is
128 | (PBKDF2_SHA512
129 | (To_Entropy (This, Password), "TON default seed", PBKDF_ITERATIONS)
130 | (1 .. 32));
131 |
132 | function To_Key_Pair
133 | (This : Mnemonic; Password : String := "") return Key_Pair is
134 | (From_Seed (To_Seed (This, Password)));
135 |
136 | function Is_Basic_Seed (Entropy : Byte_Array) return Boolean is
137 | (PBKDF2_SHA512
138 | (Entropy, "TON seed version",
139 | Natural'Max
140 | (1, Natural (Float'Floor (Float (PBKDF_ITERATIONS) / 256.0))))
141 | (1) =
142 | 0);
143 | function Is_Password_Seed (Entropy : Byte_Array) return Boolean is
144 | (PBKDF2_SHA512 (Entropy, "TON fast seed version", 1) (1) = 1);
145 | function Is_Password_Needed (Entropy : Byte_Array) return Boolean is
146 | (Is_Password_Seed (Entropy) and not Is_Basic_Seed (Entropy));
147 | end Mnemonics;
148 |
--------------------------------------------------------------------------------
/source/mnemonics.ads:
--------------------------------------------------------------------------------
1 | with Cryptography; use Cryptography;
2 | with Words; use Words;
3 | with Types; use Types;
4 |
5 | package Mnemonics is
6 | type Mnemonic is array (Positive range <>) of Bounded_Word;
7 |
8 | function Generate
9 | (Words_Count : Positive := 24; Password : String := "";
10 | List : Wordlist := English_Words) return Mnemonic;
11 | function From_String (Input : String) return Mnemonic;
12 | function To_String (This : Mnemonic) return String;
13 | function Is_Valid
14 | (This : Mnemonic; Password : String := "";
15 | List : Wordlist := English_Words) return Boolean;
16 | function To_Entropy
17 | (This : Mnemonic; Password : String := "") return Byte_Array;
18 | function To_Seed
19 | (This : Mnemonic; Password : String := "") return Byte_Array;
20 | function To_Key_Pair
21 | (This : Mnemonic; Password : String := "") return Key_Pair;
22 | function Is_Basic_Seed (Entropy : Byte_Array) return Boolean;
23 | function Is_Password_Seed (Entropy : Byte_Array) return Boolean;
24 | function Is_Password_Needed (Entropy : Byte_Array) return Boolean;
25 | end Mnemonics;
26 |
--------------------------------------------------------------------------------
/source/types.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Ada.Unchecked_Conversion;
4 |
5 | package body Types is
6 | function To_Triboolean (Value : Boolean) return Triboolean is
7 | (if Value then Triboolean'(True) else Triboolean'(False));
8 | function To_Boolean (Value : Triboolean) return Boolean is
9 | (Value = Triboolean'(True));
10 |
11 | function To_Byte_Array (Item : in String) return Byte_Array is
12 | Result : Byte_Array (Item'First .. Item'Last);
13 | begin
14 | for I in Item'Range loop
15 | Result (I) := Character'Pos (Item (I));
16 | end loop;
17 |
18 | return Result;
19 | end To_Byte_Array;
20 |
21 | function To_String (Item : in Byte_Array) return String is
22 | Result : String (Item'First .. Item'Last);
23 | begin
24 | for I in Item'Range loop
25 | Result (I) := Character'Val (Item (I));
26 | end loop;
27 |
28 | return Result;
29 | end To_String;
30 |
31 | function To_Byte_Array (Item : in Bit_Array) return Byte_Array is
32 | Result : Byte_Array (1 .. Item'Length / 8) := (others => 0);
33 | Index : Positive := 1;
34 | Chunk : Positive := 1;
35 | begin
36 | if (Item'Length rem 8) /= 0 then
37 | raise Program_Error;
38 | end if;
39 |
40 | while Chunk < Item'Length loop
41 | Result (Index) :=
42 | Unsigned_8 (2#1000_0000#) *
43 | Unsigned_8 (if Item (Chunk) then 1 else 0) +
44 | Unsigned_8 (2#0100_0000#) *
45 | Unsigned_8 (if Item (Chunk + 1) then 1 else 0) +
46 | Unsigned_8 (2#0010_0000#) *
47 | Unsigned_8 (if Item (Chunk + 2) then 1 else 0) +
48 | Unsigned_8 (2#0001_0000#) *
49 | Unsigned_8 (if Item (Chunk + 3) then 1 else 0) +
50 | Unsigned_8 (2#0000_1000#) *
51 | Unsigned_8 (if Item (Chunk + 4) then 1 else 0) +
52 | Unsigned_8 (2#0000_0100#) *
53 | Unsigned_8 (if Item (Chunk + 5) then 1 else 0) +
54 | Unsigned_8 (2#0000_0010#) *
55 | Unsigned_8 (if Item (Chunk + 6) then 1 else 0) +
56 | Unsigned_8 (2#0000_0001#) *
57 | Unsigned_8 (if Item (Chunk + 7) then 1 else 0);
58 |
59 | Index := Index + 1;
60 | Chunk := Chunk + 8;
61 | end loop;
62 |
63 | return Result;
64 | end To_Byte_Array;
65 |
66 | function To_Bit_Array (Item : in Byte_Array) return Bit_Array is
67 | Result : Bit_Array (1 .. Item'Length * 8) := (others => False);
68 |
69 | Chunk : Positive := 1;
70 | begin
71 | for Byte of Item loop
72 | Result (Chunk + 0) := (Byte and Unsigned_8 (2#1000_0000#)) /= 0;
73 | Result (Chunk + 1) := (Byte and Unsigned_8 (2#0100_0000#)) /= 0;
74 | Result (Chunk + 2) := (Byte and Unsigned_8 (2#0010_0000#)) /= 0;
75 | Result (Chunk + 3) := (Byte and Unsigned_8 (2#0001_0000#)) /= 0;
76 | Result (Chunk + 4) := (Byte and Unsigned_8 (2#0000_1000#)) /= 0;
77 | Result (Chunk + 5) := (Byte and Unsigned_8 (2#0000_0100#)) /= 0;
78 | Result (Chunk + 6) := (Byte and Unsigned_8 (2#0000_0010#)) /= 0;
79 | Result (Chunk + 7) := (Byte and Unsigned_8 (2#0000_0001#)) /= 0;
80 | Chunk := Chunk + 8;
81 | end loop;
82 |
83 | return Result;
84 | end To_Bit_Array;
85 |
86 | function Padded_Length (Length : in Natural) return Natural is
87 | (Natural (Float'Ceiling (Float (Length) / Float (8))) * 8);
88 |
89 | function Pad (Item : in Bit_Array) return Bit_Array is
90 | Result : Bit_Array (1 .. Padded_Length (Item'Length)) :=
91 | (others => False);
92 | begin
93 | Result (1 .. Item'Length) := Item;
94 | return Result;
95 | end Pad;
96 |
97 | function To_Hex_String (Item : in Byte_Array) return String is
98 | To_Hex_Digit : constant array (Unsigned_8 range 0 .. 15) of Character :=
99 | "0123456789abcdef";
100 | Result : String (1 .. Item'Length * 2);
101 | Index : Positive := 1;
102 | begin
103 | for Element of Item loop
104 | Result (Index) := To_Hex_Digit (Shift_Right (Element, 4));
105 | Result (Index + 1) := To_Hex_Digit (Element and 16#0F#);
106 |
107 | Index := Index + 2;
108 | end loop;
109 |
110 | return Result;
111 | end To_Hex_String;
112 |
113 | function From_Hex_String (Item : in String) return Byte_Array is
114 | Result : Byte_Array (1 .. Item'Length / 2) := (others => Unsigned_8 (0));
115 | I : Natural := Result'First;
116 | begin
117 | for C in Item'Range loop
118 | declare
119 | Value : Unsigned_8;
120 | begin
121 | case Item (C) is
122 | when '0' .. '9' =>
123 | Value :=
124 | Unsigned_8
125 | (Character'Pos (Item (C)) - Character'Pos ('0'));
126 | when 'a' .. 'f' =>
127 | Value :=
128 | Unsigned_8
129 | (Character'Pos (Item (C)) - Character'Pos ('a') + 10);
130 | when 'A' .. 'F' =>
131 | Value :=
132 | Unsigned_8
133 | (Character'Pos (Item (C)) - Character'Pos ('A') + 10);
134 | when others =>
135 | raise Program_Error;
136 | end case;
137 |
138 | Result (I) := Shift_Left (Result (I), 4) or Value;
139 | end;
140 |
141 | if (C mod 2) = 0 then
142 | I := I + 1;
143 | end if;
144 | end loop;
145 |
146 | return Result;
147 | end From_Hex_String;
148 |
149 | function To_Hex_String (Item : in Bit_Array) return String is
150 | (To_Hex_String (To_Byte_Array (Item)));
151 | function From_Hex_String (Item : in String) return Bit_Array is
152 | (To_Bit_Array (From_Hex_String (Item)));
153 |
154 | function Reverse_Bytes (Item : in Byte_Array) return Byte_Array is
155 | Result : Byte_Array (Item'First .. Item'Last);
156 | begin
157 | for I in Item'Range loop
158 | Result (Result'Last - I + 1) := Item (I);
159 | end loop;
160 | return Result;
161 | end Reverse_Bytes;
162 |
163 | function CRC16 (Data : Byte_Array) return Unsigned_16 is
164 | Result : Unsigned_16 := 0;
165 | begin
166 | for Byte of Data loop
167 | Result := Result xor Shift_Left (Unsigned_16 (Byte), 8);
168 |
169 | for I in 1 .. 8 loop
170 | if (Result and Unsigned_16 (16#8000#)) /= 0 then
171 | Result := Shift_Left (Result, 1) xor Unsigned_16 (16#1021#);
172 | else
173 | Result := Shift_Left (Result, 1);
174 | end if;
175 | end loop;
176 | end loop;
177 |
178 | return Result;
179 | end CRC16;
180 |
181 | function CRC16 (Data : Byte_Array) return Byte_Array is
182 | subtype Output_Type is Byte_Array (1 .. 2);
183 | function Convert is new Ada.Unchecked_Conversion
184 | (Unsigned_16, Output_Type);
185 | begin
186 | return Reverse_Bytes (Convert (CRC16 (Data)));
187 | end CRC16;
188 | end Types;
189 |
--------------------------------------------------------------------------------
/source/types.ads:
--------------------------------------------------------------------------------
1 | with Interfaces; use Interfaces;
2 |
3 | package Types is
4 | type Triboolean is (True, False, Indeterminate);
5 | function To_Triboolean (Value : Boolean) return Triboolean;
6 | function To_Boolean (Value : Triboolean) return Boolean;
7 |
8 | type Bit_Array is array (Natural range <>) of Boolean;
9 | pragma Pack (Bit_Array);
10 | type Byte_Array is array (Natural range <>) of aliased Unsigned_8;
11 |
12 | type Unsigned_16_Array is array (Natural range <>) of Unsigned_16;
13 | type Unsigned_32_Array is array (Natural range <>) of Unsigned_32;
14 |
15 | function To_Byte_Array (Item : in String) return Byte_Array;
16 | function To_String (Item : in Byte_Array) return String;
17 |
18 | function To_Byte_Array (Item : in Bit_Array) return Byte_Array;
19 | function To_Bit_Array (Item : in Byte_Array) return Bit_Array;
20 |
21 | function Padded_Length (Length : in Natural) return Natural;
22 | function Pad (Item : in Bit_Array) return Bit_Array;
23 |
24 | function To_Hex_String (Item : in Byte_Array) return String;
25 | function From_Hex_String (Item : in String) return Byte_Array with
26 | Pre => (Item'Length mod 2) = 0;
27 |
28 | function To_Hex_String (Item : in Bit_Array) return String;
29 | function From_Hex_String (Item : in String) return Bit_Array;
30 |
31 | function Reverse_Bytes (Item : in Byte_Array) return Byte_Array;
32 |
33 | function CRC16 (Data : Byte_Array) return Unsigned_16;
34 | function CRC16 (Data : Byte_Array) return Byte_Array;
35 | end Types;
36 |
--------------------------------------------------------------------------------
/source/vaniton.adb:
--------------------------------------------------------------------------------
1 | with Ada.Exceptions; use Ada.Exceptions;
2 | with Ada.Text_IO; use Ada.Text_IO;
3 |
4 | with GNAT.Ctrl_C; use GNAT.Ctrl_C;
5 | with GNAT.Command_Line; use GNAT.Command_Line;
6 | with GNAT.Strings; use GNAT.Strings;
7 | with GNAT.OS_Lib;
8 |
9 | with Wallets;
10 | with Workers; use Workers;
11 |
12 | procedure Vaniton is
13 | Config : Command_Line_Configuration;
14 | Number_Of_Workers : aliased Integer;
15 | Wallet_Kind_String : aliased String_Access := new String'("V3_R2");
16 | Case_Sensitive : aliased Boolean := False;
17 | Log_File : aliased String_Access := new String'("");
18 | Test_Only : aliased Boolean := False;
19 | Bounceable : aliased Boolean := True;
20 |
21 | type Worker_Array_Type is array (Natural range <>) of Worker;
22 | type Worker_Array_Access is access all Worker_Array_Type;
23 | Worker_Array : Worker_Array_Access := null;
24 | The_Writer : Writer;
25 | begin
26 | Install_Handler (Workers.Stop'Access);
27 |
28 | --!pp off
29 | Set_Usage
30 | (Config, Usage => "[switches] [pattern]",
31 | Help =>
32 | "Vanity address generator for The Open Network " &
33 | " blockchain wallets." & ASCII.LF &
34 | "Generates 24-word secret phrases and computes wallet address for" &
35 | " the selected wallet" & ASCII.LF &
36 | " contract version (default: " & Wallet_Kind_String.all & ")." &
37 | ASCII.LF &
38 | "Optionally, addresses are filtered out by matching against" &
39 | " [pattern]." & ASCII.LF &
40 | "Project page: " & ASCII.LF);
41 | --!pp on
42 |
43 | Define_Switch
44 | (Config, Number_Of_Workers'Access, "-j:", "--threads=",
45 | "Number of working threads running in parallel", Initial => 1);
46 | Define_Switch
47 | (Config, Wallet_Kind_String'Access, "-w:", "--wallet=",
48 | "Wallet version to use (default: " & Wallet_Kind_String.all & ")");
49 | Define_Switch
50 | (Config, Case_Sensitive'Access, "-c", "--case-sensitive",
51 | "Match case-sensitive (default: " & Case_Sensitive'Img & ")", "",
52 | not Case_Sensitive);
53 | Define_Switch
54 | (Config, Log_File'Access, "-l:", "--log=",
55 | "Log program output to file (default: '" & Log_File.all & "')");
56 | Define_Switch
57 | (Config, Test_Only'Access, "-t", "--test-only",
58 | "Generate mainnet/test-only addresses (default: " & Test_Only'Img & ")",
59 | "", not Test_Only);
60 | Define_Switch
61 | (Config, Bounceable'Access, "-b", "--bounceable",
62 | "Generate bounceable/non-bounceable addresses (default: " &
63 | Bounceable'Img & ")",
64 | "", not Bounceable);
65 |
66 | Define_Alias (Config, "-wsimpler1", "--wallet=Simple_R1");
67 | Define_Alias (Config, "-wsimpler2", "--wallet=Simple_R2");
68 | Define_Alias (Config, "-wsimpler3", "--wallet=Simple_R3");
69 | Define_Alias (Config, "-wsimple", "--wallet=Simple_R3");
70 | Define_Alias (Config, "-wv2r1", "--wallet=V2_R1");
71 | Define_Alias (Config, "-wv2r2", "--wallet=V2_R2");
72 | Define_Alias (Config, "-wv2", "--wallet=V2_R2");
73 | Define_Alias (Config, "-wv3r1", "--wallet=V3_R1");
74 | Define_Alias (Config, "-wv3r2", "--wallet=V3_R2");
75 | Define_Alias (Config, "-wv3", "--wallet=V3_R2");
76 | Define_Alias (Config, "-wv4r1", "--wallet=V4_R1");
77 | Define_Alias (Config, "-wv4r2", "--wallet=V4_R2");
78 | Define_Alias (Config, "-wv4", "--wallet=V4_R2");
79 |
80 | Getopt (Config);
81 |
82 | declare
83 | Pattern : constant String := Get_Argument;
84 | Wallet_Kind : constant Wallets.Wallet_Kind :=
85 | Wallets.Wallet_Kind'Value (Wallet_Kind_String.all);
86 | begin
87 | Worker_Array :=
88 | new Worker_Array_Type (0 .. Natural (Number_Of_Workers) - 1);
89 | for I in Worker_Array.all'Range loop
90 | Worker_Array.all (I).Start
91 | (Wallet_Kind, Test_Only, Bounceable, Pattern, Case_Sensitive);
92 | end loop;
93 | end;
94 |
95 | The_Writer.Start (Log_File.all);
96 |
97 | Put_Line (Standard_Error, "[main] Press Ctrl+C to exit");
98 | loop
99 | exit when Control.Stop;
100 | delay 1.0;
101 | end loop;
102 |
103 | Put_Line (Standard_Error, "[main] All done!");
104 | exception
105 | when Exit_From_Command_Line =>
106 | GNAT.OS_Lib.OS_Exit (0); -- All chill
107 | when Error : others =>
108 | Put (Exception_Information (Error));
109 | GNAT.OS_Lib.OS_Exit (-1);
110 | end Vaniton;
111 |
--------------------------------------------------------------------------------
/source/wallets.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Cells; use Cells;
4 |
5 | package body Wallets is
6 | Wallet_Code_Simple_R1 : constant Cell :=
7 | From_BoC
8 | ("B5EE9C72410101010044000084FF0020DDA4F260810200D71820D70B1FED44D0D31" &
9 | "FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB" &
10 | "00DED1A4C8CB1FCBFFC9ED5441FDF089");
11 | Wallet_Code_Simple_R2 : constant Cell :=
12 | From_BoC
13 | ("B5EE9C724101010100530000A2FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F" &
14 | "260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2" &
15 | "F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54D0E2786F");
16 |
17 | Wallet_Code_Simple_R3 : constant Cell :=
18 | From_BoC
19 | ("B5EE9C7241010101005F0000BAFF0020DD2082014C97BA218201339CBAB19C71B0E" &
20 | "D44D0D31FD70BFFE304E0A4F260810200D71820D70B1FED44D0D31FD3FFD15112BA" &
21 | "F2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1" &
22 | "FCBFFC9ED54B5B86E42");
23 |
24 | Wallet_Code_V2_R1 : constant Cell :=
25 | From_BoC
26 | ("B5EE9C724101010100570000AAFF0020DD2082014C97BA9730ED44D0D70B1FE0A4F" &
27 | "2608308D71820D31FD31F01F823BBF263ED44D0D31FD3FFD15131BAF2A103F90154" &
28 | "1042F910F2A2F800029320D74A96D307D402FB00E8D1A4C8CB1FCBFFC9ED54A1370" &
29 | "BB6");
30 |
31 | Wallet_Code_V2_R2 : constant Cell :=
32 | From_BoC
33 | ("B5EE9C724101010100630000C2FF0020DD2082014C97BA218201339CBAB19C71B0E" &
34 | "D44D0D31FD70BFFE304E0A4F2608308D71820D31FD31F01F823BBF263ED44D0D31F" &
35 | "D3FFD15131BAF2A103F901541042F910F2A2F800029320D74A96D307D402FB00E8D" &
36 | "1A4C8CB1FCBFFC9ED54044CD7A1");
37 |
38 | Wallet_Code_V3_R1 : constant Cell :=
39 | From_BoC
40 | ("B5EE9C724101010100620000C0FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F" &
41 | "2608308D71820D31FD31FD31FF82313BBF263ED44D0D31FD31FD3FFD15132BAF2A1" &
42 | "5144BAF2A204F901541055F910F2A3F8009320D74A96D307D402FB00E8D101A4C8C" &
43 | "B1FCB1FCBFFC9ED543FBE6EE0");
44 |
45 | Wallet_Code_V3_R2 : constant Cell :=
46 | From_BoC
47 | ("B5EE9C724101010100710000DEFF0020DD2082014C97BA218201339CBAB19F71B0E" &
48 | "D44D0D31FD31F31D70BFFE304E0A4F2608308D71820D31FD31FD31FF82313BBF263" &
49 | "ED44D0D31FD31FD3FFD15132BAF2A15144BAF2A204F901541055F910F2A3F800932" &
50 | "0D74A96D307D402FB00E8D101A4C8CB1FCB1FCBFFC9ED5410BD6DAD");
51 |
52 | Wallet_Code_V4_R1 : constant Cell :=
53 | From_BoC
54 | ("B5EE9C72410215010002F5000114FF00F4A413F4BCF2C80B0102012002030201480" &
55 | "40504F8F28308D71820D31FD31FD31F02F823BBF263ED44D0D31FD31FD3FFF404D1" &
56 | "5143BAF2A15151BAF2A205F901541064F910F2A3F80024A4C8CB1F5240CB1F5230C" &
57 | "BFF5210F400C9ED54F80F01D30721C0009F6C519320D74A96D307D402FB00E830E0" &
58 | "21C001E30021C002E30001C0039130E30D03A4C8CB1F12CB1FCBFF1112131403EED" &
59 | "001D0D3030171B0915BE021D749C120915BE001D31F218210706C7567BD22821062" &
60 | "6C6E63BDB022821064737472BDB0925F03E002FA403020FA4401C8CA07CBFFC9D0E" &
61 | "D44D0810140D721F404305C810108F40A6FA131B3925F05E004D33FC8258210706C" &
62 | "7567BA9131E30D248210626C6E63BAE30004060708020120090A005001FA00F4043" &
63 | "08210706C7567831EB17080185005CB0527CF165003FA02F40012CB69CB1F5210CB" &
64 | "3F0052F8276F228210626C6E63831EB17080185005CB0527CF1624FA0214CB6A13C" &
65 | "B1F5230CB3F01FA02F4000092821064737472BA8E3504810108F45930ED44D08101" &
66 | "40D720C801CF16F400C9ED54821064737472831EB17080185004CB0558CF1622FA0" &
67 | "212CB6ACB1FCB3F9410345F04E2C98040FB000201200B0C0059BD242B6F6A268408" &
68 | "0A06B90FA0218470D4080847A4937D29910CE6903E9FF9837812801B78101489871" &
69 | "59F31840201580D0E0011B8C97ED44D0D70B1F8003DB29DFB513420405035C87D01" &
70 | "0C00B23281F2FFF274006040423D029BE84C600201200F100019ADCE76A26840206" &
71 | "B90EB85FFC00019AF1DF6A26840106B90EB858FC0006ED207FA00D4D422F90005C8" &
72 | "CA0715CBFFC9D077748018C8CB05CB0222CF165005FA0214CB6B12CCCCC971FB00C" &
73 | "84014810108F451F2A702006C810108D718C8542025810108F451F2A782106E6F74" &
74 | "6570748018C8CB05CB025004CF16821005F5E100FA0213CB6A12CB1FC971FB00020" &
75 | "072810108D718305202810108F459F2A7F82582106473747270748018C8CB05CB02" &
76 | "5005CF16821005F5E100FA0214CB6A13CB1F12CB3FC973FB00000AF400C9ED5446A" &
77 | "9F34F");
78 |
79 | Wallet_Code_V4_R2 : constant Cell :=
80 | From_BoC
81 | ("B5EE9C72410214010002D4000114FF00F4A413F4BCF2C80B0102012002030201480" &
82 | "40504F8F28308D71820D31FD31FD31F02F823BBF264ED44D0D31FD31FD3FFF404D1" &
83 | "5143BAF2A15151BAF2A205F901541064F910F2A3F80024A4C8CB1F5240CB1F5230C" &
84 | "BFF5210F400C9ED54F80F01D30721C0009F6C519320D74A96D307D402FB00E830E0" &
85 | "21C001E30021C002E30001C0039130E30D03A4C8CB1F12CB1FCBFF1011121302E6D" &
86 | "001D0D3032171B0925F04E022D749C120925F04E002D31F218210706C7567BD2282" &
87 | "1064737472BDB0925F05E003FA403020FA4401C8CA07CBFFC9D0ED44D0810140D72" &
88 | "1F404305C810108F40A6FA131B3925F07E005D33FC8258210706C7567BA923830E3" &
89 | "0D03821064737472BA925F06E30D06070201200809007801FA00F40430F8276F223" &
90 | "0500AA121BEF2E0508210706C7567831EB17080185004CB0526CF1658FA0219F400" &
91 | "CB6917CB1F5260CB3F20C98040FB0006008A5004810108F45930ED44D0810140D72" &
92 | "0C801CF16F400C9ED540172B08E23821064737472831EB17080185005CB055003CF" &
93 | "1623FA0213CB6ACB1FCB3FC98040FB00925F03E20201200A0B0059BD242B6F6A268" &
94 | "4080A06B90FA0218470D4080847A4937D29910CE6903E9FF9837812801B78101489" &
95 | "87159F31840201580C0D0011B8C97ED44D0D70B1F8003DB29DFB513420405035C87" &
96 | "D010C00B23281F2FFF274006040423D029BE84C600201200E0F0019ADCE76A26840" &
97 | "206B90EB85FFC00019AF1DF6A26840106B90EB858FC0006ED207FA00D4D422F9000" &
98 | "5C8CA0715CBFFC9D077748018C8CB05CB0222CF165005FA0214CB6B12CCCCC973FB" &
99 | "00C84014810108F451F2A7020070810108D718FA00D33FC8542047810108F451F2A" &
100 | "782106E6F746570748018C8CB05CB025006CF165004FA0214CB6A12CB1FCB3FC973" &
101 | "FB0002006C810108D718FA00D33F305224810108F459F2A78210647374727074801" &
102 | "8C8CB05CB025005CF165003FA0213CB6ACB1F12CB3FC973FB00000AF400C9ED5469" &
103 | "6225E5");
104 |
105 | function Get_Wallet_Address
106 | (Public_Key : Byte_Array; Workchain : Integer_8 := 0;
107 | Kind : Wallet_Kind := V3_R2; Test_Only : Boolean := False;
108 | Bounceable : Boolean := True) return Address
109 | is
110 | Result : Address;
111 |
112 | Code : aliased Cell;
113 | Data : aliased Cell := Empty_Cell;
114 |
115 | State_Init : Cell := Empty_Cell;
116 | State_Init_Array : constant Bit_Array (1 .. 5) :=
117 | (False, -- split depth
118 | False, -- tick tock
119 | True, -- code
120 | True, -- data
121 | False -- library
122 | );
123 | begin
124 | case Kind is
125 | when Simple_R1 =>
126 | Code := Wallet_Code_Simple_R1;
127 | when Simple_R2 =>
128 | Code := Wallet_Code_Simple_R2;
129 | when Simple_R3 =>
130 | Code := Wallet_Code_Simple_R3;
131 | when V2_R1 =>
132 | Code := Wallet_Code_V2_R1;
133 | when V2_R2 =>
134 | Code := Wallet_Code_V2_R2;
135 | when V3_R1 =>
136 | Code := Wallet_Code_V3_R1;
137 | when V3_R2 =>
138 | Code := Wallet_Code_V3_R2;
139 | when V4_R1 =>
140 | Code := Wallet_Code_V4_R1;
141 | when V4_R2 =>
142 | Code := Wallet_Code_V4_R2;
143 | end case;
144 |
145 | case Kind is
146 | when Simple_R1 | Simple_R2 | Simple_R3 | V2_R1 | V2_R2 =>
147 | Write (Data, Unsigned_32 (0));
148 | Write (Data, Public_Key);
149 | when V3_R1 | V3_R2 =>
150 | Data := Empty_Cell;
151 | Write (Data, Unsigned_32 (0));
152 | Write (Data, Unsigned_32 (698_983_191 + Integer (Workchain)));
153 | Write (Data, Public_Key);
154 | when V4_R1 | V4_R2 =>
155 | Write (Data, Unsigned_32 (0));
156 | Write (Data, Unsigned_32 (698_983_191 + Integer (Workchain)));
157 | Write (Data, Public_Key);
158 | Write (Data, False);
159 | end case;
160 |
161 | Write (State_Init, State_Init_Array);
162 | Append_Reference (State_Init, Code);
163 | Append_Reference (State_Init, Data);
164 |
165 | Result := Create (Test_Only, Bounceable, Workchain, Hash (State_Init));
166 |
167 | return Result;
168 | end Get_Wallet_Address;
169 | end Wallets;
170 |
--------------------------------------------------------------------------------
/source/wallets.ads:
--------------------------------------------------------------------------------
1 | with Interfaces; use Interfaces;
2 |
3 | with Addresses; use Addresses;
4 | with Types; use Types;
5 |
6 | package Wallets is
7 | type Wallet_Kind is
8 | (Simple_R1, Simple_R2, Simple_R3, V2_R1, V2_R2, V3_R1, V3_R2, V4_R1, V4_R2);
9 |
10 | function Get_Wallet_Address
11 | (Public_Key : Byte_Array; Workchain : Integer_8 := 0;
12 | Kind : Wallet_Kind := V3_R2; Test_Only : Boolean := False;
13 | Bounceable : Boolean := True) return Address;
14 | end Wallets;
15 |
--------------------------------------------------------------------------------
/source/words.ads:
--------------------------------------------------------------------------------
1 | with Ada.Strings.Bounded; use Ada.Strings.Bounded;
2 |
3 | package Words is
4 | package Bounded_Words is new Ada.Strings.Bounded.Generic_Bounded_Length
5 | (Max => 8);
6 | use Bounded_Words;
7 | subtype Bounded_Word is Bounded_Words.Bounded_String;
8 |
9 | type Wordlist is array (Natural range <>) of Bounded_Word;
10 |
11 | English_Words : constant Wordlist (0 .. 2_047) :=
12 | (To_Bounded_String ("abandon"), To_Bounded_String ("ability"),
13 | To_Bounded_String ("able"), To_Bounded_String ("about"),
14 | To_Bounded_String ("above"), To_Bounded_String ("absent"),
15 | To_Bounded_String ("absorb"), To_Bounded_String ("abstract"),
16 | To_Bounded_String ("absurd"), To_Bounded_String ("abuse"),
17 | To_Bounded_String ("access"), To_Bounded_String ("accident"),
18 | To_Bounded_String ("account"), To_Bounded_String ("accuse"),
19 | To_Bounded_String ("achieve"), To_Bounded_String ("acid"),
20 | To_Bounded_String ("acoustic"), To_Bounded_String ("acquire"),
21 | To_Bounded_String ("across"), To_Bounded_String ("act"),
22 | To_Bounded_String ("action"), To_Bounded_String ("actor"),
23 | To_Bounded_String ("actress"), To_Bounded_String ("actual"),
24 | To_Bounded_String ("adapt"), To_Bounded_String ("add"),
25 | To_Bounded_String ("addict"), To_Bounded_String ("address"),
26 | To_Bounded_String ("adjust"), To_Bounded_String ("admit"),
27 | To_Bounded_String ("adult"), To_Bounded_String ("advance"),
28 | To_Bounded_String ("advice"), To_Bounded_String ("aerobic"),
29 | To_Bounded_String ("affair"), To_Bounded_String ("afford"),
30 | To_Bounded_String ("afraid"), To_Bounded_String ("again"),
31 | To_Bounded_String ("age"), To_Bounded_String ("agent"),
32 | To_Bounded_String ("agree"), To_Bounded_String ("ahead"),
33 | To_Bounded_String ("aim"), To_Bounded_String ("air"),
34 | To_Bounded_String ("airport"), To_Bounded_String ("aisle"),
35 | To_Bounded_String ("alarm"), To_Bounded_String ("album"),
36 | To_Bounded_String ("alcohol"), To_Bounded_String ("alert"),
37 | To_Bounded_String ("alien"), To_Bounded_String ("all"),
38 | To_Bounded_String ("alley"), To_Bounded_String ("allow"),
39 | To_Bounded_String ("almost"), To_Bounded_String ("alone"),
40 | To_Bounded_String ("alpha"), To_Bounded_String ("already"),
41 | To_Bounded_String ("also"), To_Bounded_String ("alter"),
42 | To_Bounded_String ("always"), To_Bounded_String ("amateur"),
43 | To_Bounded_String ("amazing"), To_Bounded_String ("among"),
44 | To_Bounded_String ("amount"), To_Bounded_String ("amused"),
45 | To_Bounded_String ("analyst"), To_Bounded_String ("anchor"),
46 | To_Bounded_String ("ancient"), To_Bounded_String ("anger"),
47 | To_Bounded_String ("angle"), To_Bounded_String ("angry"),
48 | To_Bounded_String ("animal"), To_Bounded_String ("ankle"),
49 | To_Bounded_String ("announce"), To_Bounded_String ("annual"),
50 | To_Bounded_String ("another"), To_Bounded_String ("answer"),
51 | To_Bounded_String ("antenna"), To_Bounded_String ("antique"),
52 | To_Bounded_String ("anxiety"), To_Bounded_String ("any"),
53 | To_Bounded_String ("apart"), To_Bounded_String ("apology"),
54 | To_Bounded_String ("appear"), To_Bounded_String ("apple"),
55 | To_Bounded_String ("approve"), To_Bounded_String ("april"),
56 | To_Bounded_String ("arch"), To_Bounded_String ("arctic"),
57 | To_Bounded_String ("area"), To_Bounded_String ("arena"),
58 | To_Bounded_String ("argue"), To_Bounded_String ("arm"),
59 | To_Bounded_String ("armed"), To_Bounded_String ("armor"),
60 | To_Bounded_String ("army"), To_Bounded_String ("around"),
61 | To_Bounded_String ("arrange"), To_Bounded_String ("arrest"),
62 | To_Bounded_String ("arrive"), To_Bounded_String ("arrow"),
63 | To_Bounded_String ("art"), To_Bounded_String ("artefact"),
64 | To_Bounded_String ("artist"), To_Bounded_String ("artwork"),
65 | To_Bounded_String ("ask"), To_Bounded_String ("aspect"),
66 | To_Bounded_String ("assault"), To_Bounded_String ("asset"),
67 | To_Bounded_String ("assist"), To_Bounded_String ("assume"),
68 | To_Bounded_String ("asthma"), To_Bounded_String ("athlete"),
69 | To_Bounded_String ("atom"), To_Bounded_String ("attack"),
70 | To_Bounded_String ("attend"), To_Bounded_String ("attitude"),
71 | To_Bounded_String ("attract"), To_Bounded_String ("auction"),
72 | To_Bounded_String ("audit"), To_Bounded_String ("august"),
73 | To_Bounded_String ("aunt"), To_Bounded_String ("author"),
74 | To_Bounded_String ("auto"), To_Bounded_String ("autumn"),
75 | To_Bounded_String ("average"), To_Bounded_String ("avocado"),
76 | To_Bounded_String ("avoid"), To_Bounded_String ("awake"),
77 | To_Bounded_String ("aware"), To_Bounded_String ("away"),
78 | To_Bounded_String ("awesome"), To_Bounded_String ("awful"),
79 | To_Bounded_String ("awkward"), To_Bounded_String ("axis"),
80 | To_Bounded_String ("baby"), To_Bounded_String ("bachelor"),
81 | To_Bounded_String ("bacon"), To_Bounded_String ("badge"),
82 | To_Bounded_String ("bag"), To_Bounded_String ("balance"),
83 | To_Bounded_String ("balcony"), To_Bounded_String ("ball"),
84 | To_Bounded_String ("bamboo"), To_Bounded_String ("banana"),
85 | To_Bounded_String ("banner"), To_Bounded_String ("bar"),
86 | To_Bounded_String ("barely"), To_Bounded_String ("bargain"),
87 | To_Bounded_String ("barrel"), To_Bounded_String ("base"),
88 | To_Bounded_String ("basic"), To_Bounded_String ("basket"),
89 | To_Bounded_String ("battle"), To_Bounded_String ("beach"),
90 | To_Bounded_String ("bean"), To_Bounded_String ("beauty"),
91 | To_Bounded_String ("because"), To_Bounded_String ("become"),
92 | To_Bounded_String ("beef"), To_Bounded_String ("before"),
93 | To_Bounded_String ("begin"), To_Bounded_String ("behave"),
94 | To_Bounded_String ("behind"), To_Bounded_String ("believe"),
95 | To_Bounded_String ("below"), To_Bounded_String ("belt"),
96 | To_Bounded_String ("bench"), To_Bounded_String ("benefit"),
97 | To_Bounded_String ("best"), To_Bounded_String ("betray"),
98 | To_Bounded_String ("better"), To_Bounded_String ("between"),
99 | To_Bounded_String ("beyond"), To_Bounded_String ("bicycle"),
100 | To_Bounded_String ("bid"), To_Bounded_String ("bike"),
101 | To_Bounded_String ("bind"), To_Bounded_String ("biology"),
102 | To_Bounded_String ("bird"), To_Bounded_String ("birth"),
103 | To_Bounded_String ("bitter"), To_Bounded_String ("black"),
104 | To_Bounded_String ("blade"), To_Bounded_String ("blame"),
105 | To_Bounded_String ("blanket"), To_Bounded_String ("blast"),
106 | To_Bounded_String ("bleak"), To_Bounded_String ("bless"),
107 | To_Bounded_String ("blind"), To_Bounded_String ("blood"),
108 | To_Bounded_String ("blossom"), To_Bounded_String ("blouse"),
109 | To_Bounded_String ("blue"), To_Bounded_String ("blur"),
110 | To_Bounded_String ("blush"), To_Bounded_String ("board"),
111 | To_Bounded_String ("boat"), To_Bounded_String ("body"),
112 | To_Bounded_String ("boil"), To_Bounded_String ("bomb"),
113 | To_Bounded_String ("bone"), To_Bounded_String ("bonus"),
114 | To_Bounded_String ("book"), To_Bounded_String ("boost"),
115 | To_Bounded_String ("border"), To_Bounded_String ("boring"),
116 | To_Bounded_String ("borrow"), To_Bounded_String ("boss"),
117 | To_Bounded_String ("bottom"), To_Bounded_String ("bounce"),
118 | To_Bounded_String ("box"), To_Bounded_String ("boy"),
119 | To_Bounded_String ("bracket"), To_Bounded_String ("brain"),
120 | To_Bounded_String ("brand"), To_Bounded_String ("brass"),
121 | To_Bounded_String ("brave"), To_Bounded_String ("bread"),
122 | To_Bounded_String ("breeze"), To_Bounded_String ("brick"),
123 | To_Bounded_String ("bridge"), To_Bounded_String ("brief"),
124 | To_Bounded_String ("bright"), To_Bounded_String ("bring"),
125 | To_Bounded_String ("brisk"), To_Bounded_String ("broccoli"),
126 | To_Bounded_String ("broken"), To_Bounded_String ("bronze"),
127 | To_Bounded_String ("broom"), To_Bounded_String ("brother"),
128 | To_Bounded_String ("brown"), To_Bounded_String ("brush"),
129 | To_Bounded_String ("bubble"), To_Bounded_String ("buddy"),
130 | To_Bounded_String ("budget"), To_Bounded_String ("buffalo"),
131 | To_Bounded_String ("build"), To_Bounded_String ("bulb"),
132 | To_Bounded_String ("bulk"), To_Bounded_String ("bullet"),
133 | To_Bounded_String ("bundle"), To_Bounded_String ("bunker"),
134 | To_Bounded_String ("burden"), To_Bounded_String ("burger"),
135 | To_Bounded_String ("burst"), To_Bounded_String ("bus"),
136 | To_Bounded_String ("business"), To_Bounded_String ("busy"),
137 | To_Bounded_String ("butter"), To_Bounded_String ("buyer"),
138 | To_Bounded_String ("buzz"), To_Bounded_String ("cabbage"),
139 | To_Bounded_String ("cabin"), To_Bounded_String ("cable"),
140 | To_Bounded_String ("cactus"), To_Bounded_String ("cage"),
141 | To_Bounded_String ("cake"), To_Bounded_String ("call"),
142 | To_Bounded_String ("calm"), To_Bounded_String ("camera"),
143 | To_Bounded_String ("camp"), To_Bounded_String ("can"),
144 | To_Bounded_String ("canal"), To_Bounded_String ("cancel"),
145 | To_Bounded_String ("candy"), To_Bounded_String ("cannon"),
146 | To_Bounded_String ("canoe"), To_Bounded_String ("canvas"),
147 | To_Bounded_String ("canyon"), To_Bounded_String ("capable"),
148 | To_Bounded_String ("capital"), To_Bounded_String ("captain"),
149 | To_Bounded_String ("car"), To_Bounded_String ("carbon"),
150 | To_Bounded_String ("card"), To_Bounded_String ("cargo"),
151 | To_Bounded_String ("carpet"), To_Bounded_String ("carry"),
152 | To_Bounded_String ("cart"), To_Bounded_String ("case"),
153 | To_Bounded_String ("cash"), To_Bounded_String ("casino"),
154 | To_Bounded_String ("castle"), To_Bounded_String ("casual"),
155 | To_Bounded_String ("cat"), To_Bounded_String ("catalog"),
156 | To_Bounded_String ("catch"), To_Bounded_String ("category"),
157 | To_Bounded_String ("cattle"), To_Bounded_String ("caught"),
158 | To_Bounded_String ("cause"), To_Bounded_String ("caution"),
159 | To_Bounded_String ("cave"), To_Bounded_String ("ceiling"),
160 | To_Bounded_String ("celery"), To_Bounded_String ("cement"),
161 | To_Bounded_String ("census"), To_Bounded_String ("century"),
162 | To_Bounded_String ("cereal"), To_Bounded_String ("certain"),
163 | To_Bounded_String ("chair"), To_Bounded_String ("chalk"),
164 | To_Bounded_String ("champion"), To_Bounded_String ("change"),
165 | To_Bounded_String ("chaos"), To_Bounded_String ("chapter"),
166 | To_Bounded_String ("charge"), To_Bounded_String ("chase"),
167 | To_Bounded_String ("chat"), To_Bounded_String ("cheap"),
168 | To_Bounded_String ("check"), To_Bounded_String ("cheese"),
169 | To_Bounded_String ("chef"), To_Bounded_String ("cherry"),
170 | To_Bounded_String ("chest"), To_Bounded_String ("chicken"),
171 | To_Bounded_String ("chief"), To_Bounded_String ("child"),
172 | To_Bounded_String ("chimney"), To_Bounded_String ("choice"),
173 | To_Bounded_String ("choose"), To_Bounded_String ("chronic"),
174 | To_Bounded_String ("chuckle"), To_Bounded_String ("chunk"),
175 | To_Bounded_String ("churn"), To_Bounded_String ("cigar"),
176 | To_Bounded_String ("cinnamon"), To_Bounded_String ("circle"),
177 | To_Bounded_String ("citizen"), To_Bounded_String ("city"),
178 | To_Bounded_String ("civil"), To_Bounded_String ("claim"),
179 | To_Bounded_String ("clap"), To_Bounded_String ("clarify"),
180 | To_Bounded_String ("claw"), To_Bounded_String ("clay"),
181 | To_Bounded_String ("clean"), To_Bounded_String ("clerk"),
182 | To_Bounded_String ("clever"), To_Bounded_String ("click"),
183 | To_Bounded_String ("client"), To_Bounded_String ("cliff"),
184 | To_Bounded_String ("climb"), To_Bounded_String ("clinic"),
185 | To_Bounded_String ("clip"), To_Bounded_String ("clock"),
186 | To_Bounded_String ("clog"), To_Bounded_String ("close"),
187 | To_Bounded_String ("cloth"), To_Bounded_String ("cloud"),
188 | To_Bounded_String ("clown"), To_Bounded_String ("club"),
189 | To_Bounded_String ("clump"), To_Bounded_String ("cluster"),
190 | To_Bounded_String ("clutch"), To_Bounded_String ("coach"),
191 | To_Bounded_String ("coast"), To_Bounded_String ("coconut"),
192 | To_Bounded_String ("code"), To_Bounded_String ("coffee"),
193 | To_Bounded_String ("coil"), To_Bounded_String ("coin"),
194 | To_Bounded_String ("collect"), To_Bounded_String ("color"),
195 | To_Bounded_String ("column"), To_Bounded_String ("combine"),
196 | To_Bounded_String ("come"), To_Bounded_String ("comfort"),
197 | To_Bounded_String ("comic"), To_Bounded_String ("common"),
198 | To_Bounded_String ("company"), To_Bounded_String ("concert"),
199 | To_Bounded_String ("conduct"), To_Bounded_String ("confirm"),
200 | To_Bounded_String ("congress"), To_Bounded_String ("connect"),
201 | To_Bounded_String ("consider"), To_Bounded_String ("control"),
202 | To_Bounded_String ("convince"), To_Bounded_String ("cook"),
203 | To_Bounded_String ("cool"), To_Bounded_String ("copper"),
204 | To_Bounded_String ("copy"), To_Bounded_String ("coral"),
205 | To_Bounded_String ("core"), To_Bounded_String ("corn"),
206 | To_Bounded_String ("correct"), To_Bounded_String ("cost"),
207 | To_Bounded_String ("cotton"), To_Bounded_String ("couch"),
208 | To_Bounded_String ("country"), To_Bounded_String ("couple"),
209 | To_Bounded_String ("course"), To_Bounded_String ("cousin"),
210 | To_Bounded_String ("cover"), To_Bounded_String ("coyote"),
211 | To_Bounded_String ("crack"), To_Bounded_String ("cradle"),
212 | To_Bounded_String ("craft"), To_Bounded_String ("cram"),
213 | To_Bounded_String ("crane"), To_Bounded_String ("crash"),
214 | To_Bounded_String ("crater"), To_Bounded_String ("crawl"),
215 | To_Bounded_String ("crazy"), To_Bounded_String ("cream"),
216 | To_Bounded_String ("credit"), To_Bounded_String ("creek"),
217 | To_Bounded_String ("crew"), To_Bounded_String ("cricket"),
218 | To_Bounded_String ("crime"), To_Bounded_String ("crisp"),
219 | To_Bounded_String ("critic"), To_Bounded_String ("crop"),
220 | To_Bounded_String ("cross"), To_Bounded_String ("crouch"),
221 | To_Bounded_String ("crowd"), To_Bounded_String ("crucial"),
222 | To_Bounded_String ("cruel"), To_Bounded_String ("cruise"),
223 | To_Bounded_String ("crumble"), To_Bounded_String ("crunch"),
224 | To_Bounded_String ("crush"), To_Bounded_String ("cry"),
225 | To_Bounded_String ("crystal"), To_Bounded_String ("cube"),
226 | To_Bounded_String ("culture"), To_Bounded_String ("cup"),
227 | To_Bounded_String ("cupboard"), To_Bounded_String ("curious"),
228 | To_Bounded_String ("current"), To_Bounded_String ("curtain"),
229 | To_Bounded_String ("curve"), To_Bounded_String ("cushion"),
230 | To_Bounded_String ("custom"), To_Bounded_String ("cute"),
231 | To_Bounded_String ("cycle"), To_Bounded_String ("dad"),
232 | To_Bounded_String ("damage"), To_Bounded_String ("damp"),
233 | To_Bounded_String ("dance"), To_Bounded_String ("danger"),
234 | To_Bounded_String ("daring"), To_Bounded_String ("dash"),
235 | To_Bounded_String ("daughter"), To_Bounded_String ("dawn"),
236 | To_Bounded_String ("day"), To_Bounded_String ("deal"),
237 | To_Bounded_String ("debate"), To_Bounded_String ("debris"),
238 | To_Bounded_String ("decade"), To_Bounded_String ("december"),
239 | To_Bounded_String ("decide"), To_Bounded_String ("decline"),
240 | To_Bounded_String ("decorate"), To_Bounded_String ("decrease"),
241 | To_Bounded_String ("deer"), To_Bounded_String ("defense"),
242 | To_Bounded_String ("define"), To_Bounded_String ("defy"),
243 | To_Bounded_String ("degree"), To_Bounded_String ("delay"),
244 | To_Bounded_String ("deliver"), To_Bounded_String ("demand"),
245 | To_Bounded_String ("demise"), To_Bounded_String ("denial"),
246 | To_Bounded_String ("dentist"), To_Bounded_String ("deny"),
247 | To_Bounded_String ("depart"), To_Bounded_String ("depend"),
248 | To_Bounded_String ("deposit"), To_Bounded_String ("depth"),
249 | To_Bounded_String ("deputy"), To_Bounded_String ("derive"),
250 | To_Bounded_String ("describe"), To_Bounded_String ("desert"),
251 | To_Bounded_String ("design"), To_Bounded_String ("desk"),
252 | To_Bounded_String ("despair"), To_Bounded_String ("destroy"),
253 | To_Bounded_String ("detail"), To_Bounded_String ("detect"),
254 | To_Bounded_String ("develop"), To_Bounded_String ("device"),
255 | To_Bounded_String ("devote"), To_Bounded_String ("diagram"),
256 | To_Bounded_String ("dial"), To_Bounded_String ("diamond"),
257 | To_Bounded_String ("diary"), To_Bounded_String ("dice"),
258 | To_Bounded_String ("diesel"), To_Bounded_String ("diet"),
259 | To_Bounded_String ("differ"), To_Bounded_String ("digital"),
260 | To_Bounded_String ("dignity"), To_Bounded_String ("dilemma"),
261 | To_Bounded_String ("dinner"), To_Bounded_String ("dinosaur"),
262 | To_Bounded_String ("direct"), To_Bounded_String ("dirt"),
263 | To_Bounded_String ("disagree"), To_Bounded_String ("discover"),
264 | To_Bounded_String ("disease"), To_Bounded_String ("dish"),
265 | To_Bounded_String ("dismiss"), To_Bounded_String ("disorder"),
266 | To_Bounded_String ("display"), To_Bounded_String ("distance"),
267 | To_Bounded_String ("divert"), To_Bounded_String ("divide"),
268 | To_Bounded_String ("divorce"), To_Bounded_String ("dizzy"),
269 | To_Bounded_String ("doctor"), To_Bounded_String ("document"),
270 | To_Bounded_String ("dog"), To_Bounded_String ("doll"),
271 | To_Bounded_String ("dolphin"), To_Bounded_String ("domain"),
272 | To_Bounded_String ("donate"), To_Bounded_String ("donkey"),
273 | To_Bounded_String ("donor"), To_Bounded_String ("door"),
274 | To_Bounded_String ("dose"), To_Bounded_String ("double"),
275 | To_Bounded_String ("dove"), To_Bounded_String ("draft"),
276 | To_Bounded_String ("dragon"), To_Bounded_String ("drama"),
277 | To_Bounded_String ("drastic"), To_Bounded_String ("draw"),
278 | To_Bounded_String ("dream"), To_Bounded_String ("dress"),
279 | To_Bounded_String ("drift"), To_Bounded_String ("drill"),
280 | To_Bounded_String ("drink"), To_Bounded_String ("drip"),
281 | To_Bounded_String ("drive"), To_Bounded_String ("drop"),
282 | To_Bounded_String ("drum"), To_Bounded_String ("dry"),
283 | To_Bounded_String ("duck"), To_Bounded_String ("dumb"),
284 | To_Bounded_String ("dune"), To_Bounded_String ("during"),
285 | To_Bounded_String ("dust"), To_Bounded_String ("dutch"),
286 | To_Bounded_String ("duty"), To_Bounded_String ("dwarf"),
287 | To_Bounded_String ("dynamic"), To_Bounded_String ("eager"),
288 | To_Bounded_String ("eagle"), To_Bounded_String ("early"),
289 | To_Bounded_String ("earn"), To_Bounded_String ("earth"),
290 | To_Bounded_String ("easily"), To_Bounded_String ("east"),
291 | To_Bounded_String ("easy"), To_Bounded_String ("echo"),
292 | To_Bounded_String ("ecology"), To_Bounded_String ("economy"),
293 | To_Bounded_String ("edge"), To_Bounded_String ("edit"),
294 | To_Bounded_String ("educate"), To_Bounded_String ("effort"),
295 | To_Bounded_String ("egg"), To_Bounded_String ("eight"),
296 | To_Bounded_String ("either"), To_Bounded_String ("elbow"),
297 | To_Bounded_String ("elder"), To_Bounded_String ("electric"),
298 | To_Bounded_String ("elegant"), To_Bounded_String ("element"),
299 | To_Bounded_String ("elephant"), To_Bounded_String ("elevator"),
300 | To_Bounded_String ("elite"), To_Bounded_String ("else"),
301 | To_Bounded_String ("embark"), To_Bounded_String ("embody"),
302 | To_Bounded_String ("embrace"), To_Bounded_String ("emerge"),
303 | To_Bounded_String ("emotion"), To_Bounded_String ("employ"),
304 | To_Bounded_String ("empower"), To_Bounded_String ("empty"),
305 | To_Bounded_String ("enable"), To_Bounded_String ("enact"),
306 | To_Bounded_String ("end"), To_Bounded_String ("endless"),
307 | To_Bounded_String ("endorse"), To_Bounded_String ("enemy"),
308 | To_Bounded_String ("energy"), To_Bounded_String ("enforce"),
309 | To_Bounded_String ("engage"), To_Bounded_String ("engine"),
310 | To_Bounded_String ("enhance"), To_Bounded_String ("enjoy"),
311 | To_Bounded_String ("enlist"), To_Bounded_String ("enough"),
312 | To_Bounded_String ("enrich"), To_Bounded_String ("enroll"),
313 | To_Bounded_String ("ensure"), To_Bounded_String ("enter"),
314 | To_Bounded_String ("entire"), To_Bounded_String ("entry"),
315 | To_Bounded_String ("envelope"), To_Bounded_String ("episode"),
316 | To_Bounded_String ("equal"), To_Bounded_String ("equip"),
317 | To_Bounded_String ("era"), To_Bounded_String ("erase"),
318 | To_Bounded_String ("erode"), To_Bounded_String ("erosion"),
319 | To_Bounded_String ("error"), To_Bounded_String ("erupt"),
320 | To_Bounded_String ("escape"), To_Bounded_String ("essay"),
321 | To_Bounded_String ("essence"), To_Bounded_String ("estate"),
322 | To_Bounded_String ("eternal"), To_Bounded_String ("ethics"),
323 | To_Bounded_String ("evidence"), To_Bounded_String ("evil"),
324 | To_Bounded_String ("evoke"), To_Bounded_String ("evolve"),
325 | To_Bounded_String ("exact"), To_Bounded_String ("example"),
326 | To_Bounded_String ("excess"), To_Bounded_String ("exchange"),
327 | To_Bounded_String ("excite"), To_Bounded_String ("exclude"),
328 | To_Bounded_String ("excuse"), To_Bounded_String ("execute"),
329 | To_Bounded_String ("exercise"), To_Bounded_String ("exhaust"),
330 | To_Bounded_String ("exhibit"), To_Bounded_String ("exile"),
331 | To_Bounded_String ("exist"), To_Bounded_String ("exit"),
332 | To_Bounded_String ("exotic"), To_Bounded_String ("expand"),
333 | To_Bounded_String ("expect"), To_Bounded_String ("expire"),
334 | To_Bounded_String ("explain"), To_Bounded_String ("expose"),
335 | To_Bounded_String ("express"), To_Bounded_String ("extend"),
336 | To_Bounded_String ("extra"), To_Bounded_String ("eye"),
337 | To_Bounded_String ("eyebrow"), To_Bounded_String ("fabric"),
338 | To_Bounded_String ("face"), To_Bounded_String ("faculty"),
339 | To_Bounded_String ("fade"), To_Bounded_String ("faint"),
340 | To_Bounded_String ("faith"), To_Bounded_String ("fall"),
341 | To_Bounded_String ("false"), To_Bounded_String ("fame"),
342 | To_Bounded_String ("family"), To_Bounded_String ("famous"),
343 | To_Bounded_String ("fan"), To_Bounded_String ("fancy"),
344 | To_Bounded_String ("fantasy"), To_Bounded_String ("farm"),
345 | To_Bounded_String ("fashion"), To_Bounded_String ("fat"),
346 | To_Bounded_String ("fatal"), To_Bounded_String ("father"),
347 | To_Bounded_String ("fatigue"), To_Bounded_String ("fault"),
348 | To_Bounded_String ("favorite"), To_Bounded_String ("feature"),
349 | To_Bounded_String ("february"), To_Bounded_String ("federal"),
350 | To_Bounded_String ("fee"), To_Bounded_String ("feed"),
351 | To_Bounded_String ("feel"), To_Bounded_String ("female"),
352 | To_Bounded_String ("fence"), To_Bounded_String ("festival"),
353 | To_Bounded_String ("fetch"), To_Bounded_String ("fever"),
354 | To_Bounded_String ("few"), To_Bounded_String ("fiber"),
355 | To_Bounded_String ("fiction"), To_Bounded_String ("field"),
356 | To_Bounded_String ("figure"), To_Bounded_String ("file"),
357 | To_Bounded_String ("film"), To_Bounded_String ("filter"),
358 | To_Bounded_String ("final"), To_Bounded_String ("find"),
359 | To_Bounded_String ("fine"), To_Bounded_String ("finger"),
360 | To_Bounded_String ("finish"), To_Bounded_String ("fire"),
361 | To_Bounded_String ("firm"), To_Bounded_String ("first"),
362 | To_Bounded_String ("fiscal"), To_Bounded_String ("fish"),
363 | To_Bounded_String ("fit"), To_Bounded_String ("fitness"),
364 | To_Bounded_String ("fix"), To_Bounded_String ("flag"),
365 | To_Bounded_String ("flame"), To_Bounded_String ("flash"),
366 | To_Bounded_String ("flat"), To_Bounded_String ("flavor"),
367 | To_Bounded_String ("flee"), To_Bounded_String ("flight"),
368 | To_Bounded_String ("flip"), To_Bounded_String ("float"),
369 | To_Bounded_String ("flock"), To_Bounded_String ("floor"),
370 | To_Bounded_String ("flower"), To_Bounded_String ("fluid"),
371 | To_Bounded_String ("flush"), To_Bounded_String ("fly"),
372 | To_Bounded_String ("foam"), To_Bounded_String ("focus"),
373 | To_Bounded_String ("fog"), To_Bounded_String ("foil"),
374 | To_Bounded_String ("fold"), To_Bounded_String ("follow"),
375 | To_Bounded_String ("food"), To_Bounded_String ("foot"),
376 | To_Bounded_String ("force"), To_Bounded_String ("forest"),
377 | To_Bounded_String ("forget"), To_Bounded_String ("fork"),
378 | To_Bounded_String ("fortune"), To_Bounded_String ("forum"),
379 | To_Bounded_String ("forward"), To_Bounded_String ("fossil"),
380 | To_Bounded_String ("foster"), To_Bounded_String ("found"),
381 | To_Bounded_String ("fox"), To_Bounded_String ("fragile"),
382 | To_Bounded_String ("frame"), To_Bounded_String ("frequent"),
383 | To_Bounded_String ("fresh"), To_Bounded_String ("friend"),
384 | To_Bounded_String ("fringe"), To_Bounded_String ("frog"),
385 | To_Bounded_String ("front"), To_Bounded_String ("frost"),
386 | To_Bounded_String ("frown"), To_Bounded_String ("frozen"),
387 | To_Bounded_String ("fruit"), To_Bounded_String ("fuel"),
388 | To_Bounded_String ("fun"), To_Bounded_String ("funny"),
389 | To_Bounded_String ("furnace"), To_Bounded_String ("fury"),
390 | To_Bounded_String ("future"), To_Bounded_String ("gadget"),
391 | To_Bounded_String ("gain"), To_Bounded_String ("galaxy"),
392 | To_Bounded_String ("gallery"), To_Bounded_String ("game"),
393 | To_Bounded_String ("gap"), To_Bounded_String ("garage"),
394 | To_Bounded_String ("garbage"), To_Bounded_String ("garden"),
395 | To_Bounded_String ("garlic"), To_Bounded_String ("garment"),
396 | To_Bounded_String ("gas"), To_Bounded_String ("gasp"),
397 | To_Bounded_String ("gate"), To_Bounded_String ("gather"),
398 | To_Bounded_String ("gauge"), To_Bounded_String ("gaze"),
399 | To_Bounded_String ("general"), To_Bounded_String ("genius"),
400 | To_Bounded_String ("genre"), To_Bounded_String ("gentle"),
401 | To_Bounded_String ("genuine"), To_Bounded_String ("gesture"),
402 | To_Bounded_String ("ghost"), To_Bounded_String ("giant"),
403 | To_Bounded_String ("gift"), To_Bounded_String ("giggle"),
404 | To_Bounded_String ("ginger"), To_Bounded_String ("giraffe"),
405 | To_Bounded_String ("girl"), To_Bounded_String ("give"),
406 | To_Bounded_String ("glad"), To_Bounded_String ("glance"),
407 | To_Bounded_String ("glare"), To_Bounded_String ("glass"),
408 | To_Bounded_String ("glide"), To_Bounded_String ("glimpse"),
409 | To_Bounded_String ("globe"), To_Bounded_String ("gloom"),
410 | To_Bounded_String ("glory"), To_Bounded_String ("glove"),
411 | To_Bounded_String ("glow"), To_Bounded_String ("glue"),
412 | To_Bounded_String ("goat"), To_Bounded_String ("goddess"),
413 | To_Bounded_String ("gold"), To_Bounded_String ("good"),
414 | To_Bounded_String ("goose"), To_Bounded_String ("gorilla"),
415 | To_Bounded_String ("gospel"), To_Bounded_String ("gossip"),
416 | To_Bounded_String ("govern"), To_Bounded_String ("gown"),
417 | To_Bounded_String ("grab"), To_Bounded_String ("grace"),
418 | To_Bounded_String ("grain"), To_Bounded_String ("grant"),
419 | To_Bounded_String ("grape"), To_Bounded_String ("grass"),
420 | To_Bounded_String ("gravity"), To_Bounded_String ("great"),
421 | To_Bounded_String ("green"), To_Bounded_String ("grid"),
422 | To_Bounded_String ("grief"), To_Bounded_String ("grit"),
423 | To_Bounded_String ("grocery"), To_Bounded_String ("group"),
424 | To_Bounded_String ("grow"), To_Bounded_String ("grunt"),
425 | To_Bounded_String ("guard"), To_Bounded_String ("guess"),
426 | To_Bounded_String ("guide"), To_Bounded_String ("guilt"),
427 | To_Bounded_String ("guitar"), To_Bounded_String ("gun"),
428 | To_Bounded_String ("gym"), To_Bounded_String ("habit"),
429 | To_Bounded_String ("hair"), To_Bounded_String ("half"),
430 | To_Bounded_String ("hammer"), To_Bounded_String ("hamster"),
431 | To_Bounded_String ("hand"), To_Bounded_String ("happy"),
432 | To_Bounded_String ("harbor"), To_Bounded_String ("hard"),
433 | To_Bounded_String ("harsh"), To_Bounded_String ("harvest"),
434 | To_Bounded_String ("hat"), To_Bounded_String ("have"),
435 | To_Bounded_String ("hawk"), To_Bounded_String ("hazard"),
436 | To_Bounded_String ("head"), To_Bounded_String ("health"),
437 | To_Bounded_String ("heart"), To_Bounded_String ("heavy"),
438 | To_Bounded_String ("hedgehog"), To_Bounded_String ("height"),
439 | To_Bounded_String ("hello"), To_Bounded_String ("helmet"),
440 | To_Bounded_String ("help"), To_Bounded_String ("hen"),
441 | To_Bounded_String ("hero"), To_Bounded_String ("hidden"),
442 | To_Bounded_String ("high"), To_Bounded_String ("hill"),
443 | To_Bounded_String ("hint"), To_Bounded_String ("hip"),
444 | To_Bounded_String ("hire"), To_Bounded_String ("history"),
445 | To_Bounded_String ("hobby"), To_Bounded_String ("hockey"),
446 | To_Bounded_String ("hold"), To_Bounded_String ("hole"),
447 | To_Bounded_String ("holiday"), To_Bounded_String ("hollow"),
448 | To_Bounded_String ("home"), To_Bounded_String ("honey"),
449 | To_Bounded_String ("hood"), To_Bounded_String ("hope"),
450 | To_Bounded_String ("horn"), To_Bounded_String ("horror"),
451 | To_Bounded_String ("horse"), To_Bounded_String ("hospital"),
452 | To_Bounded_String ("host"), To_Bounded_String ("hotel"),
453 | To_Bounded_String ("hour"), To_Bounded_String ("hover"),
454 | To_Bounded_String ("hub"), To_Bounded_String ("huge"),
455 | To_Bounded_String ("human"), To_Bounded_String ("humble"),
456 | To_Bounded_String ("humor"), To_Bounded_String ("hundred"),
457 | To_Bounded_String ("hungry"), To_Bounded_String ("hunt"),
458 | To_Bounded_String ("hurdle"), To_Bounded_String ("hurry"),
459 | To_Bounded_String ("hurt"), To_Bounded_String ("husband"),
460 | To_Bounded_String ("hybrid"), To_Bounded_String ("ice"),
461 | To_Bounded_String ("icon"), To_Bounded_String ("idea"),
462 | To_Bounded_String ("identify"), To_Bounded_String ("idle"),
463 | To_Bounded_String ("ignore"), To_Bounded_String ("ill"),
464 | To_Bounded_String ("illegal"), To_Bounded_String ("illness"),
465 | To_Bounded_String ("image"), To_Bounded_String ("imitate"),
466 | To_Bounded_String ("immense"), To_Bounded_String ("immune"),
467 | To_Bounded_String ("impact"), To_Bounded_String ("impose"),
468 | To_Bounded_String ("improve"), To_Bounded_String ("impulse"),
469 | To_Bounded_String ("inch"), To_Bounded_String ("include"),
470 | To_Bounded_String ("income"), To_Bounded_String ("increase"),
471 | To_Bounded_String ("index"), To_Bounded_String ("indicate"),
472 | To_Bounded_String ("indoor"), To_Bounded_String ("industry"),
473 | To_Bounded_String ("infant"), To_Bounded_String ("inflict"),
474 | To_Bounded_String ("inform"), To_Bounded_String ("inhale"),
475 | To_Bounded_String ("inherit"), To_Bounded_String ("initial"),
476 | To_Bounded_String ("inject"), To_Bounded_String ("injury"),
477 | To_Bounded_String ("inmate"), To_Bounded_String ("inner"),
478 | To_Bounded_String ("innocent"), To_Bounded_String ("input"),
479 | To_Bounded_String ("inquiry"), To_Bounded_String ("insane"),
480 | To_Bounded_String ("insect"), To_Bounded_String ("inside"),
481 | To_Bounded_String ("inspire"), To_Bounded_String ("install"),
482 | To_Bounded_String ("intact"), To_Bounded_String ("interest"),
483 | To_Bounded_String ("into"), To_Bounded_String ("invest"),
484 | To_Bounded_String ("invite"), To_Bounded_String ("involve"),
485 | To_Bounded_String ("iron"), To_Bounded_String ("island"),
486 | To_Bounded_String ("isolate"), To_Bounded_String ("issue"),
487 | To_Bounded_String ("item"), To_Bounded_String ("ivory"),
488 | To_Bounded_String ("jacket"), To_Bounded_String ("jaguar"),
489 | To_Bounded_String ("jar"), To_Bounded_String ("jazz"),
490 | To_Bounded_String ("jealous"), To_Bounded_String ("jeans"),
491 | To_Bounded_String ("jelly"), To_Bounded_String ("jewel"),
492 | To_Bounded_String ("job"), To_Bounded_String ("join"),
493 | To_Bounded_String ("joke"), To_Bounded_String ("journey"),
494 | To_Bounded_String ("joy"), To_Bounded_String ("judge"),
495 | To_Bounded_String ("juice"), To_Bounded_String ("jump"),
496 | To_Bounded_String ("jungle"), To_Bounded_String ("junior"),
497 | To_Bounded_String ("junk"), To_Bounded_String ("just"),
498 | To_Bounded_String ("kangaroo"), To_Bounded_String ("keen"),
499 | To_Bounded_String ("keep"), To_Bounded_String ("ketchup"),
500 | To_Bounded_String ("key"), To_Bounded_String ("kick"),
501 | To_Bounded_String ("kid"), To_Bounded_String ("kidney"),
502 | To_Bounded_String ("kind"), To_Bounded_String ("kingdom"),
503 | To_Bounded_String ("kiss"), To_Bounded_String ("kit"),
504 | To_Bounded_String ("kitchen"), To_Bounded_String ("kite"),
505 | To_Bounded_String ("kitten"), To_Bounded_String ("kiwi"),
506 | To_Bounded_String ("knee"), To_Bounded_String ("knife"),
507 | To_Bounded_String ("knock"), To_Bounded_String ("know"),
508 | To_Bounded_String ("lab"), To_Bounded_String ("label"),
509 | To_Bounded_String ("labor"), To_Bounded_String ("ladder"),
510 | To_Bounded_String ("lady"), To_Bounded_String ("lake"),
511 | To_Bounded_String ("lamp"), To_Bounded_String ("language"),
512 | To_Bounded_String ("laptop"), To_Bounded_String ("large"),
513 | To_Bounded_String ("later"), To_Bounded_String ("latin"),
514 | To_Bounded_String ("laugh"), To_Bounded_String ("laundry"),
515 | To_Bounded_String ("lava"), To_Bounded_String ("law"),
516 | To_Bounded_String ("lawn"), To_Bounded_String ("lawsuit"),
517 | To_Bounded_String ("layer"), To_Bounded_String ("lazy"),
518 | To_Bounded_String ("leader"), To_Bounded_String ("leaf"),
519 | To_Bounded_String ("learn"), To_Bounded_String ("leave"),
520 | To_Bounded_String ("lecture"), To_Bounded_String ("left"),
521 | To_Bounded_String ("leg"), To_Bounded_String ("legal"),
522 | To_Bounded_String ("legend"), To_Bounded_String ("leisure"),
523 | To_Bounded_String ("lemon"), To_Bounded_String ("lend"),
524 | To_Bounded_String ("length"), To_Bounded_String ("lens"),
525 | To_Bounded_String ("leopard"), To_Bounded_String ("lesson"),
526 | To_Bounded_String ("letter"), To_Bounded_String ("level"),
527 | To_Bounded_String ("liar"), To_Bounded_String ("liberty"),
528 | To_Bounded_String ("library"), To_Bounded_String ("license"),
529 | To_Bounded_String ("life"), To_Bounded_String ("lift"),
530 | To_Bounded_String ("light"), To_Bounded_String ("like"),
531 | To_Bounded_String ("limb"), To_Bounded_String ("limit"),
532 | To_Bounded_String ("link"), To_Bounded_String ("lion"),
533 | To_Bounded_String ("liquid"), To_Bounded_String ("list"),
534 | To_Bounded_String ("little"), To_Bounded_String ("live"),
535 | To_Bounded_String ("lizard"), To_Bounded_String ("load"),
536 | To_Bounded_String ("loan"), To_Bounded_String ("lobster"),
537 | To_Bounded_String ("local"), To_Bounded_String ("lock"),
538 | To_Bounded_String ("logic"), To_Bounded_String ("lonely"),
539 | To_Bounded_String ("long"), To_Bounded_String ("loop"),
540 | To_Bounded_String ("lottery"), To_Bounded_String ("loud"),
541 | To_Bounded_String ("lounge"), To_Bounded_String ("love"),
542 | To_Bounded_String ("loyal"), To_Bounded_String ("lucky"),
543 | To_Bounded_String ("luggage"), To_Bounded_String ("lumber"),
544 | To_Bounded_String ("lunar"), To_Bounded_String ("lunch"),
545 | To_Bounded_String ("luxury"), To_Bounded_String ("lyrics"),
546 | To_Bounded_String ("machine"), To_Bounded_String ("mad"),
547 | To_Bounded_String ("magic"), To_Bounded_String ("magnet"),
548 | To_Bounded_String ("maid"), To_Bounded_String ("mail"),
549 | To_Bounded_String ("main"), To_Bounded_String ("major"),
550 | To_Bounded_String ("make"), To_Bounded_String ("mammal"),
551 | To_Bounded_String ("man"), To_Bounded_String ("manage"),
552 | To_Bounded_String ("mandate"), To_Bounded_String ("mango"),
553 | To_Bounded_String ("mansion"), To_Bounded_String ("manual"),
554 | To_Bounded_String ("maple"), To_Bounded_String ("marble"),
555 | To_Bounded_String ("march"), To_Bounded_String ("margin"),
556 | To_Bounded_String ("marine"), To_Bounded_String ("market"),
557 | To_Bounded_String ("marriage"), To_Bounded_String ("mask"),
558 | To_Bounded_String ("mass"), To_Bounded_String ("master"),
559 | To_Bounded_String ("match"), To_Bounded_String ("material"),
560 | To_Bounded_String ("math"), To_Bounded_String ("matrix"),
561 | To_Bounded_String ("matter"), To_Bounded_String ("maximum"),
562 | To_Bounded_String ("maze"), To_Bounded_String ("meadow"),
563 | To_Bounded_String ("mean"), To_Bounded_String ("measure"),
564 | To_Bounded_String ("meat"), To_Bounded_String ("mechanic"),
565 | To_Bounded_String ("medal"), To_Bounded_String ("media"),
566 | To_Bounded_String ("melody"), To_Bounded_String ("melt"),
567 | To_Bounded_String ("member"), To_Bounded_String ("memory"),
568 | To_Bounded_String ("mention"), To_Bounded_String ("menu"),
569 | To_Bounded_String ("mercy"), To_Bounded_String ("merge"),
570 | To_Bounded_String ("merit"), To_Bounded_String ("merry"),
571 | To_Bounded_String ("mesh"), To_Bounded_String ("message"),
572 | To_Bounded_String ("metal"), To_Bounded_String ("method"),
573 | To_Bounded_String ("middle"), To_Bounded_String ("midnight"),
574 | To_Bounded_String ("milk"), To_Bounded_String ("million"),
575 | To_Bounded_String ("mimic"), To_Bounded_String ("mind"),
576 | To_Bounded_String ("minimum"), To_Bounded_String ("minor"),
577 | To_Bounded_String ("minute"), To_Bounded_String ("miracle"),
578 | To_Bounded_String ("mirror"), To_Bounded_String ("misery"),
579 | To_Bounded_String ("miss"), To_Bounded_String ("mistake"),
580 | To_Bounded_String ("mix"), To_Bounded_String ("mixed"),
581 | To_Bounded_String ("mixture"), To_Bounded_String ("mobile"),
582 | To_Bounded_String ("model"), To_Bounded_String ("modify"),
583 | To_Bounded_String ("mom"), To_Bounded_String ("moment"),
584 | To_Bounded_String ("monitor"), To_Bounded_String ("monkey"),
585 | To_Bounded_String ("monster"), To_Bounded_String ("month"),
586 | To_Bounded_String ("moon"), To_Bounded_String ("moral"),
587 | To_Bounded_String ("more"), To_Bounded_String ("morning"),
588 | To_Bounded_String ("mosquito"), To_Bounded_String ("mother"),
589 | To_Bounded_String ("motion"), To_Bounded_String ("motor"),
590 | To_Bounded_String ("mountain"), To_Bounded_String ("mouse"),
591 | To_Bounded_String ("move"), To_Bounded_String ("movie"),
592 | To_Bounded_String ("much"), To_Bounded_String ("muffin"),
593 | To_Bounded_String ("mule"), To_Bounded_String ("multiply"),
594 | To_Bounded_String ("muscle"), To_Bounded_String ("museum"),
595 | To_Bounded_String ("mushroom"), To_Bounded_String ("music"),
596 | To_Bounded_String ("must"), To_Bounded_String ("mutual"),
597 | To_Bounded_String ("myself"), To_Bounded_String ("mystery"),
598 | To_Bounded_String ("myth"), To_Bounded_String ("naive"),
599 | To_Bounded_String ("name"), To_Bounded_String ("napkin"),
600 | To_Bounded_String ("narrow"), To_Bounded_String ("nasty"),
601 | To_Bounded_String ("nation"), To_Bounded_String ("nature"),
602 | To_Bounded_String ("near"), To_Bounded_String ("neck"),
603 | To_Bounded_String ("need"), To_Bounded_String ("negative"),
604 | To_Bounded_String ("neglect"), To_Bounded_String ("neither"),
605 | To_Bounded_String ("nephew"), To_Bounded_String ("nerve"),
606 | To_Bounded_String ("nest"), To_Bounded_String ("net"),
607 | To_Bounded_String ("network"), To_Bounded_String ("neutral"),
608 | To_Bounded_String ("never"), To_Bounded_String ("news"),
609 | To_Bounded_String ("next"), To_Bounded_String ("nice"),
610 | To_Bounded_String ("night"), To_Bounded_String ("noble"),
611 | To_Bounded_String ("noise"), To_Bounded_String ("nominee"),
612 | To_Bounded_String ("noodle"), To_Bounded_String ("normal"),
613 | To_Bounded_String ("north"), To_Bounded_String ("nose"),
614 | To_Bounded_String ("notable"), To_Bounded_String ("note"),
615 | To_Bounded_String ("nothing"), To_Bounded_String ("notice"),
616 | To_Bounded_String ("novel"), To_Bounded_String ("now"),
617 | To_Bounded_String ("nuclear"), To_Bounded_String ("number"),
618 | To_Bounded_String ("nurse"), To_Bounded_String ("nut"),
619 | To_Bounded_String ("oak"), To_Bounded_String ("obey"),
620 | To_Bounded_String ("object"), To_Bounded_String ("oblige"),
621 | To_Bounded_String ("obscure"), To_Bounded_String ("observe"),
622 | To_Bounded_String ("obtain"), To_Bounded_String ("obvious"),
623 | To_Bounded_String ("occur"), To_Bounded_String ("ocean"),
624 | To_Bounded_String ("october"), To_Bounded_String ("odor"),
625 | To_Bounded_String ("off"), To_Bounded_String ("offer"),
626 | To_Bounded_String ("office"), To_Bounded_String ("often"),
627 | To_Bounded_String ("oil"), To_Bounded_String ("okay"),
628 | To_Bounded_String ("old"), To_Bounded_String ("olive"),
629 | To_Bounded_String ("olympic"), To_Bounded_String ("omit"),
630 | To_Bounded_String ("once"), To_Bounded_String ("one"),
631 | To_Bounded_String ("onion"), To_Bounded_String ("online"),
632 | To_Bounded_String ("only"), To_Bounded_String ("open"),
633 | To_Bounded_String ("opera"), To_Bounded_String ("opinion"),
634 | To_Bounded_String ("oppose"), To_Bounded_String ("option"),
635 | To_Bounded_String ("orange"), To_Bounded_String ("orbit"),
636 | To_Bounded_String ("orchard"), To_Bounded_String ("order"),
637 | To_Bounded_String ("ordinary"), To_Bounded_String ("organ"),
638 | To_Bounded_String ("orient"), To_Bounded_String ("original"),
639 | To_Bounded_String ("orphan"), To_Bounded_String ("ostrich"),
640 | To_Bounded_String ("other"), To_Bounded_String ("outdoor"),
641 | To_Bounded_String ("outer"), To_Bounded_String ("output"),
642 | To_Bounded_String ("outside"), To_Bounded_String ("oval"),
643 | To_Bounded_String ("oven"), To_Bounded_String ("over"),
644 | To_Bounded_String ("own"), To_Bounded_String ("owner"),
645 | To_Bounded_String ("oxygen"), To_Bounded_String ("oyster"),
646 | To_Bounded_String ("ozone"), To_Bounded_String ("pact"),
647 | To_Bounded_String ("paddle"), To_Bounded_String ("page"),
648 | To_Bounded_String ("pair"), To_Bounded_String ("palace"),
649 | To_Bounded_String ("palm"), To_Bounded_String ("panda"),
650 | To_Bounded_String ("panel"), To_Bounded_String ("panic"),
651 | To_Bounded_String ("panther"), To_Bounded_String ("paper"),
652 | To_Bounded_String ("parade"), To_Bounded_String ("parent"),
653 | To_Bounded_String ("park"), To_Bounded_String ("parrot"),
654 | To_Bounded_String ("party"), To_Bounded_String ("pass"),
655 | To_Bounded_String ("patch"), To_Bounded_String ("path"),
656 | To_Bounded_String ("patient"), To_Bounded_String ("patrol"),
657 | To_Bounded_String ("pattern"), To_Bounded_String ("pause"),
658 | To_Bounded_String ("pave"), To_Bounded_String ("payment"),
659 | To_Bounded_String ("peace"), To_Bounded_String ("peanut"),
660 | To_Bounded_String ("pear"), To_Bounded_String ("peasant"),
661 | To_Bounded_String ("pelican"), To_Bounded_String ("pen"),
662 | To_Bounded_String ("penalty"), To_Bounded_String ("pencil"),
663 | To_Bounded_String ("people"), To_Bounded_String ("pepper"),
664 | To_Bounded_String ("perfect"), To_Bounded_String ("permit"),
665 | To_Bounded_String ("person"), To_Bounded_String ("pet"),
666 | To_Bounded_String ("phone"), To_Bounded_String ("photo"),
667 | To_Bounded_String ("phrase"), To_Bounded_String ("physical"),
668 | To_Bounded_String ("piano"), To_Bounded_String ("picnic"),
669 | To_Bounded_String ("picture"), To_Bounded_String ("piece"),
670 | To_Bounded_String ("pig"), To_Bounded_String ("pigeon"),
671 | To_Bounded_String ("pill"), To_Bounded_String ("pilot"),
672 | To_Bounded_String ("pink"), To_Bounded_String ("pioneer"),
673 | To_Bounded_String ("pipe"), To_Bounded_String ("pistol"),
674 | To_Bounded_String ("pitch"), To_Bounded_String ("pizza"),
675 | To_Bounded_String ("place"), To_Bounded_String ("planet"),
676 | To_Bounded_String ("plastic"), To_Bounded_String ("plate"),
677 | To_Bounded_String ("play"), To_Bounded_String ("please"),
678 | To_Bounded_String ("pledge"), To_Bounded_String ("pluck"),
679 | To_Bounded_String ("plug"), To_Bounded_String ("plunge"),
680 | To_Bounded_String ("poem"), To_Bounded_String ("poet"),
681 | To_Bounded_String ("point"), To_Bounded_String ("polar"),
682 | To_Bounded_String ("pole"), To_Bounded_String ("police"),
683 | To_Bounded_String ("pond"), To_Bounded_String ("pony"),
684 | To_Bounded_String ("pool"), To_Bounded_String ("popular"),
685 | To_Bounded_String ("portion"), To_Bounded_String ("position"),
686 | To_Bounded_String ("possible"), To_Bounded_String ("post"),
687 | To_Bounded_String ("potato"), To_Bounded_String ("pottery"),
688 | To_Bounded_String ("poverty"), To_Bounded_String ("powder"),
689 | To_Bounded_String ("power"), To_Bounded_String ("practice"),
690 | To_Bounded_String ("praise"), To_Bounded_String ("predict"),
691 | To_Bounded_String ("prefer"), To_Bounded_String ("prepare"),
692 | To_Bounded_String ("present"), To_Bounded_String ("pretty"),
693 | To_Bounded_String ("prevent"), To_Bounded_String ("price"),
694 | To_Bounded_String ("pride"), To_Bounded_String ("primary"),
695 | To_Bounded_String ("print"), To_Bounded_String ("priority"),
696 | To_Bounded_String ("prison"), To_Bounded_String ("private"),
697 | To_Bounded_String ("prize"), To_Bounded_String ("problem"),
698 | To_Bounded_String ("process"), To_Bounded_String ("produce"),
699 | To_Bounded_String ("profit"), To_Bounded_String ("program"),
700 | To_Bounded_String ("project"), To_Bounded_String ("promote"),
701 | To_Bounded_String ("proof"), To_Bounded_String ("property"),
702 | To_Bounded_String ("prosper"), To_Bounded_String ("protect"),
703 | To_Bounded_String ("proud"), To_Bounded_String ("provide"),
704 | To_Bounded_String ("public"), To_Bounded_String ("pudding"),
705 | To_Bounded_String ("pull"), To_Bounded_String ("pulp"),
706 | To_Bounded_String ("pulse"), To_Bounded_String ("pumpkin"),
707 | To_Bounded_String ("punch"), To_Bounded_String ("pupil"),
708 | To_Bounded_String ("puppy"), To_Bounded_String ("purchase"),
709 | To_Bounded_String ("purity"), To_Bounded_String ("purpose"),
710 | To_Bounded_String ("purse"), To_Bounded_String ("push"),
711 | To_Bounded_String ("put"), To_Bounded_String ("puzzle"),
712 | To_Bounded_String ("pyramid"), To_Bounded_String ("quality"),
713 | To_Bounded_String ("quantum"), To_Bounded_String ("quarter"),
714 | To_Bounded_String ("question"), To_Bounded_String ("quick"),
715 | To_Bounded_String ("quit"), To_Bounded_String ("quiz"),
716 | To_Bounded_String ("quote"), To_Bounded_String ("rabbit"),
717 | To_Bounded_String ("raccoon"), To_Bounded_String ("race"),
718 | To_Bounded_String ("rack"), To_Bounded_String ("radar"),
719 | To_Bounded_String ("radio"), To_Bounded_String ("rail"),
720 | To_Bounded_String ("rain"), To_Bounded_String ("raise"),
721 | To_Bounded_String ("rally"), To_Bounded_String ("ramp"),
722 | To_Bounded_String ("ranch"), To_Bounded_String ("random"),
723 | To_Bounded_String ("range"), To_Bounded_String ("rapid"),
724 | To_Bounded_String ("rare"), To_Bounded_String ("rate"),
725 | To_Bounded_String ("rather"), To_Bounded_String ("raven"),
726 | To_Bounded_String ("raw"), To_Bounded_String ("razor"),
727 | To_Bounded_String ("ready"), To_Bounded_String ("real"),
728 | To_Bounded_String ("reason"), To_Bounded_String ("rebel"),
729 | To_Bounded_String ("rebuild"), To_Bounded_String ("recall"),
730 | To_Bounded_String ("receive"), To_Bounded_String ("recipe"),
731 | To_Bounded_String ("record"), To_Bounded_String ("recycle"),
732 | To_Bounded_String ("reduce"), To_Bounded_String ("reflect"),
733 | To_Bounded_String ("reform"), To_Bounded_String ("refuse"),
734 | To_Bounded_String ("region"), To_Bounded_String ("regret"),
735 | To_Bounded_String ("regular"), To_Bounded_String ("reject"),
736 | To_Bounded_String ("relax"), To_Bounded_String ("release"),
737 | To_Bounded_String ("relief"), To_Bounded_String ("rely"),
738 | To_Bounded_String ("remain"), To_Bounded_String ("remember"),
739 | To_Bounded_String ("remind"), To_Bounded_String ("remove"),
740 | To_Bounded_String ("render"), To_Bounded_String ("renew"),
741 | To_Bounded_String ("rent"), To_Bounded_String ("reopen"),
742 | To_Bounded_String ("repair"), To_Bounded_String ("repeat"),
743 | To_Bounded_String ("replace"), To_Bounded_String ("report"),
744 | To_Bounded_String ("require"), To_Bounded_String ("rescue"),
745 | To_Bounded_String ("resemble"), To_Bounded_String ("resist"),
746 | To_Bounded_String ("resource"), To_Bounded_String ("response"),
747 | To_Bounded_String ("result"), To_Bounded_String ("retire"),
748 | To_Bounded_String ("retreat"), To_Bounded_String ("return"),
749 | To_Bounded_String ("reunion"), To_Bounded_String ("reveal"),
750 | To_Bounded_String ("review"), To_Bounded_String ("reward"),
751 | To_Bounded_String ("rhythm"), To_Bounded_String ("rib"),
752 | To_Bounded_String ("ribbon"), To_Bounded_String ("rice"),
753 | To_Bounded_String ("rich"), To_Bounded_String ("ride"),
754 | To_Bounded_String ("ridge"), To_Bounded_String ("rifle"),
755 | To_Bounded_String ("right"), To_Bounded_String ("rigid"),
756 | To_Bounded_String ("ring"), To_Bounded_String ("riot"),
757 | To_Bounded_String ("ripple"), To_Bounded_String ("risk"),
758 | To_Bounded_String ("ritual"), To_Bounded_String ("rival"),
759 | To_Bounded_String ("river"), To_Bounded_String ("road"),
760 | To_Bounded_String ("roast"), To_Bounded_String ("robot"),
761 | To_Bounded_String ("robust"), To_Bounded_String ("rocket"),
762 | To_Bounded_String ("romance"), To_Bounded_String ("roof"),
763 | To_Bounded_String ("rookie"), To_Bounded_String ("room"),
764 | To_Bounded_String ("rose"), To_Bounded_String ("rotate"),
765 | To_Bounded_String ("rough"), To_Bounded_String ("round"),
766 | To_Bounded_String ("route"), To_Bounded_String ("royal"),
767 | To_Bounded_String ("rubber"), To_Bounded_String ("rude"),
768 | To_Bounded_String ("rug"), To_Bounded_String ("rule"),
769 | To_Bounded_String ("run"), To_Bounded_String ("runway"),
770 | To_Bounded_String ("rural"), To_Bounded_String ("sad"),
771 | To_Bounded_String ("saddle"), To_Bounded_String ("sadness"),
772 | To_Bounded_String ("safe"), To_Bounded_String ("sail"),
773 | To_Bounded_String ("salad"), To_Bounded_String ("salmon"),
774 | To_Bounded_String ("salon"), To_Bounded_String ("salt"),
775 | To_Bounded_String ("salute"), To_Bounded_String ("same"),
776 | To_Bounded_String ("sample"), To_Bounded_String ("sand"),
777 | To_Bounded_String ("satisfy"), To_Bounded_String ("satoshi"),
778 | To_Bounded_String ("sauce"), To_Bounded_String ("sausage"),
779 | To_Bounded_String ("save"), To_Bounded_String ("say"),
780 | To_Bounded_String ("scale"), To_Bounded_String ("scan"),
781 | To_Bounded_String ("scare"), To_Bounded_String ("scatter"),
782 | To_Bounded_String ("scene"), To_Bounded_String ("scheme"),
783 | To_Bounded_String ("school"), To_Bounded_String ("science"),
784 | To_Bounded_String ("scissors"), To_Bounded_String ("scorpion"),
785 | To_Bounded_String ("scout"), To_Bounded_String ("scrap"),
786 | To_Bounded_String ("screen"), To_Bounded_String ("script"),
787 | To_Bounded_String ("scrub"), To_Bounded_String ("sea"),
788 | To_Bounded_String ("search"), To_Bounded_String ("season"),
789 | To_Bounded_String ("seat"), To_Bounded_String ("second"),
790 | To_Bounded_String ("secret"), To_Bounded_String ("section"),
791 | To_Bounded_String ("security"), To_Bounded_String ("seed"),
792 | To_Bounded_String ("seek"), To_Bounded_String ("segment"),
793 | To_Bounded_String ("select"), To_Bounded_String ("sell"),
794 | To_Bounded_String ("seminar"), To_Bounded_String ("senior"),
795 | To_Bounded_String ("sense"), To_Bounded_String ("sentence"),
796 | To_Bounded_String ("series"), To_Bounded_String ("service"),
797 | To_Bounded_String ("session"), To_Bounded_String ("settle"),
798 | To_Bounded_String ("setup"), To_Bounded_String ("seven"),
799 | To_Bounded_String ("shadow"), To_Bounded_String ("shaft"),
800 | To_Bounded_String ("shallow"), To_Bounded_String ("share"),
801 | To_Bounded_String ("shed"), To_Bounded_String ("shell"),
802 | To_Bounded_String ("sheriff"), To_Bounded_String ("shield"),
803 | To_Bounded_String ("shift"), To_Bounded_String ("shine"),
804 | To_Bounded_String ("ship"), To_Bounded_String ("shiver"),
805 | To_Bounded_String ("shock"), To_Bounded_String ("shoe"),
806 | To_Bounded_String ("shoot"), To_Bounded_String ("shop"),
807 | To_Bounded_String ("short"), To_Bounded_String ("shoulder"),
808 | To_Bounded_String ("shove"), To_Bounded_String ("shrimp"),
809 | To_Bounded_String ("shrug"), To_Bounded_String ("shuffle"),
810 | To_Bounded_String ("shy"), To_Bounded_String ("sibling"),
811 | To_Bounded_String ("sick"), To_Bounded_String ("side"),
812 | To_Bounded_String ("siege"), To_Bounded_String ("sight"),
813 | To_Bounded_String ("sign"), To_Bounded_String ("silent"),
814 | To_Bounded_String ("silk"), To_Bounded_String ("silly"),
815 | To_Bounded_String ("silver"), To_Bounded_String ("similar"),
816 | To_Bounded_String ("simple"), To_Bounded_String ("since"),
817 | To_Bounded_String ("sing"), To_Bounded_String ("siren"),
818 | To_Bounded_String ("sister"), To_Bounded_String ("situate"),
819 | To_Bounded_String ("six"), To_Bounded_String ("size"),
820 | To_Bounded_String ("skate"), To_Bounded_String ("sketch"),
821 | To_Bounded_String ("ski"), To_Bounded_String ("skill"),
822 | To_Bounded_String ("skin"), To_Bounded_String ("skirt"),
823 | To_Bounded_String ("skull"), To_Bounded_String ("slab"),
824 | To_Bounded_String ("slam"), To_Bounded_String ("sleep"),
825 | To_Bounded_String ("slender"), To_Bounded_String ("slice"),
826 | To_Bounded_String ("slide"), To_Bounded_String ("slight"),
827 | To_Bounded_String ("slim"), To_Bounded_String ("slogan"),
828 | To_Bounded_String ("slot"), To_Bounded_String ("slow"),
829 | To_Bounded_String ("slush"), To_Bounded_String ("small"),
830 | To_Bounded_String ("smart"), To_Bounded_String ("smile"),
831 | To_Bounded_String ("smoke"), To_Bounded_String ("smooth"),
832 | To_Bounded_String ("snack"), To_Bounded_String ("snake"),
833 | To_Bounded_String ("snap"), To_Bounded_String ("sniff"),
834 | To_Bounded_String ("snow"), To_Bounded_String ("soap"),
835 | To_Bounded_String ("soccer"), To_Bounded_String ("social"),
836 | To_Bounded_String ("sock"), To_Bounded_String ("soda"),
837 | To_Bounded_String ("soft"), To_Bounded_String ("solar"),
838 | To_Bounded_String ("soldier"), To_Bounded_String ("solid"),
839 | To_Bounded_String ("solution"), To_Bounded_String ("solve"),
840 | To_Bounded_String ("someone"), To_Bounded_String ("song"),
841 | To_Bounded_String ("soon"), To_Bounded_String ("sorry"),
842 | To_Bounded_String ("sort"), To_Bounded_String ("soul"),
843 | To_Bounded_String ("sound"), To_Bounded_String ("soup"),
844 | To_Bounded_String ("source"), To_Bounded_String ("south"),
845 | To_Bounded_String ("space"), To_Bounded_String ("spare"),
846 | To_Bounded_String ("spatial"), To_Bounded_String ("spawn"),
847 | To_Bounded_String ("speak"), To_Bounded_String ("special"),
848 | To_Bounded_String ("speed"), To_Bounded_String ("spell"),
849 | To_Bounded_String ("spend"), To_Bounded_String ("sphere"),
850 | To_Bounded_String ("spice"), To_Bounded_String ("spider"),
851 | To_Bounded_String ("spike"), To_Bounded_String ("spin"),
852 | To_Bounded_String ("spirit"), To_Bounded_String ("split"),
853 | To_Bounded_String ("spoil"), To_Bounded_String ("sponsor"),
854 | To_Bounded_String ("spoon"), To_Bounded_String ("sport"),
855 | To_Bounded_String ("spot"), To_Bounded_String ("spray"),
856 | To_Bounded_String ("spread"), To_Bounded_String ("spring"),
857 | To_Bounded_String ("spy"), To_Bounded_String ("square"),
858 | To_Bounded_String ("squeeze"), To_Bounded_String ("squirrel"),
859 | To_Bounded_String ("stable"), To_Bounded_String ("stadium"),
860 | To_Bounded_String ("staff"), To_Bounded_String ("stage"),
861 | To_Bounded_String ("stairs"), To_Bounded_String ("stamp"),
862 | To_Bounded_String ("stand"), To_Bounded_String ("start"),
863 | To_Bounded_String ("state"), To_Bounded_String ("stay"),
864 | To_Bounded_String ("steak"), To_Bounded_String ("steel"),
865 | To_Bounded_String ("stem"), To_Bounded_String ("step"),
866 | To_Bounded_String ("stereo"), To_Bounded_String ("stick"),
867 | To_Bounded_String ("still"), To_Bounded_String ("sting"),
868 | To_Bounded_String ("stock"), To_Bounded_String ("stomach"),
869 | To_Bounded_String ("stone"), To_Bounded_String ("stool"),
870 | To_Bounded_String ("story"), To_Bounded_String ("stove"),
871 | To_Bounded_String ("strategy"), To_Bounded_String ("street"),
872 | To_Bounded_String ("strike"), To_Bounded_String ("strong"),
873 | To_Bounded_String ("struggle"), To_Bounded_String ("student"),
874 | To_Bounded_String ("stuff"), To_Bounded_String ("stumble"),
875 | To_Bounded_String ("style"), To_Bounded_String ("subject"),
876 | To_Bounded_String ("submit"), To_Bounded_String ("subway"),
877 | To_Bounded_String ("success"), To_Bounded_String ("such"),
878 | To_Bounded_String ("sudden"), To_Bounded_String ("suffer"),
879 | To_Bounded_String ("sugar"), To_Bounded_String ("suggest"),
880 | To_Bounded_String ("suit"), To_Bounded_String ("summer"),
881 | To_Bounded_String ("sun"), To_Bounded_String ("sunny"),
882 | To_Bounded_String ("sunset"), To_Bounded_String ("super"),
883 | To_Bounded_String ("supply"), To_Bounded_String ("supreme"),
884 | To_Bounded_String ("sure"), To_Bounded_String ("surface"),
885 | To_Bounded_String ("surge"), To_Bounded_String ("surprise"),
886 | To_Bounded_String ("surround"), To_Bounded_String ("survey"),
887 | To_Bounded_String ("suspect"), To_Bounded_String ("sustain"),
888 | To_Bounded_String ("swallow"), To_Bounded_String ("swamp"),
889 | To_Bounded_String ("swap"), To_Bounded_String ("swarm"),
890 | To_Bounded_String ("swear"), To_Bounded_String ("sweet"),
891 | To_Bounded_String ("swift"), To_Bounded_String ("swim"),
892 | To_Bounded_String ("swing"), To_Bounded_String ("switch"),
893 | To_Bounded_String ("sword"), To_Bounded_String ("symbol"),
894 | To_Bounded_String ("symptom"), To_Bounded_String ("syrup"),
895 | To_Bounded_String ("system"), To_Bounded_String ("table"),
896 | To_Bounded_String ("tackle"), To_Bounded_String ("tag"),
897 | To_Bounded_String ("tail"), To_Bounded_String ("talent"),
898 | To_Bounded_String ("talk"), To_Bounded_String ("tank"),
899 | To_Bounded_String ("tape"), To_Bounded_String ("target"),
900 | To_Bounded_String ("task"), To_Bounded_String ("taste"),
901 | To_Bounded_String ("tattoo"), To_Bounded_String ("taxi"),
902 | To_Bounded_String ("teach"), To_Bounded_String ("team"),
903 | To_Bounded_String ("tell"), To_Bounded_String ("ten"),
904 | To_Bounded_String ("tenant"), To_Bounded_String ("tennis"),
905 | To_Bounded_String ("tent"), To_Bounded_String ("term"),
906 | To_Bounded_String ("test"), To_Bounded_String ("text"),
907 | To_Bounded_String ("thank"), To_Bounded_String ("that"),
908 | To_Bounded_String ("theme"), To_Bounded_String ("then"),
909 | To_Bounded_String ("theory"), To_Bounded_String ("there"),
910 | To_Bounded_String ("they"), To_Bounded_String ("thing"),
911 | To_Bounded_String ("this"), To_Bounded_String ("thought"),
912 | To_Bounded_String ("three"), To_Bounded_String ("thrive"),
913 | To_Bounded_String ("throw"), To_Bounded_String ("thumb"),
914 | To_Bounded_String ("thunder"), To_Bounded_String ("ticket"),
915 | To_Bounded_String ("tide"), To_Bounded_String ("tiger"),
916 | To_Bounded_String ("tilt"), To_Bounded_String ("timber"),
917 | To_Bounded_String ("time"), To_Bounded_String ("tiny"),
918 | To_Bounded_String ("tip"), To_Bounded_String ("tired"),
919 | To_Bounded_String ("tissue"), To_Bounded_String ("title"),
920 | To_Bounded_String ("toast"), To_Bounded_String ("tobacco"),
921 | To_Bounded_String ("today"), To_Bounded_String ("toddler"),
922 | To_Bounded_String ("toe"), To_Bounded_String ("together"),
923 | To_Bounded_String ("toilet"), To_Bounded_String ("token"),
924 | To_Bounded_String ("tomato"), To_Bounded_String ("tomorrow"),
925 | To_Bounded_String ("tone"), To_Bounded_String ("tongue"),
926 | To_Bounded_String ("tonight"), To_Bounded_String ("tool"),
927 | To_Bounded_String ("tooth"), To_Bounded_String ("top"),
928 | To_Bounded_String ("topic"), To_Bounded_String ("topple"),
929 | To_Bounded_String ("torch"), To_Bounded_String ("tornado"),
930 | To_Bounded_String ("tortoise"), To_Bounded_String ("toss"),
931 | To_Bounded_String ("total"), To_Bounded_String ("tourist"),
932 | To_Bounded_String ("toward"), To_Bounded_String ("tower"),
933 | To_Bounded_String ("town"), To_Bounded_String ("toy"),
934 | To_Bounded_String ("track"), To_Bounded_String ("trade"),
935 | To_Bounded_String ("traffic"), To_Bounded_String ("tragic"),
936 | To_Bounded_String ("train"), To_Bounded_String ("transfer"),
937 | To_Bounded_String ("trap"), To_Bounded_String ("trash"),
938 | To_Bounded_String ("travel"), To_Bounded_String ("tray"),
939 | To_Bounded_String ("treat"), To_Bounded_String ("tree"),
940 | To_Bounded_String ("trend"), To_Bounded_String ("trial"),
941 | To_Bounded_String ("tribe"), To_Bounded_String ("trick"),
942 | To_Bounded_String ("trigger"), To_Bounded_String ("trim"),
943 | To_Bounded_String ("trip"), To_Bounded_String ("trophy"),
944 | To_Bounded_String ("trouble"), To_Bounded_String ("truck"),
945 | To_Bounded_String ("true"), To_Bounded_String ("truly"),
946 | To_Bounded_String ("trumpet"), To_Bounded_String ("trust"),
947 | To_Bounded_String ("truth"), To_Bounded_String ("try"),
948 | To_Bounded_String ("tube"), To_Bounded_String ("tuition"),
949 | To_Bounded_String ("tumble"), To_Bounded_String ("tuna"),
950 | To_Bounded_String ("tunnel"), To_Bounded_String ("turkey"),
951 | To_Bounded_String ("turn"), To_Bounded_String ("turtle"),
952 | To_Bounded_String ("twelve"), To_Bounded_String ("twenty"),
953 | To_Bounded_String ("twice"), To_Bounded_String ("twin"),
954 | To_Bounded_String ("twist"), To_Bounded_String ("two"),
955 | To_Bounded_String ("type"), To_Bounded_String ("typical"),
956 | To_Bounded_String ("ugly"), To_Bounded_String ("umbrella"),
957 | To_Bounded_String ("unable"), To_Bounded_String ("unaware"),
958 | To_Bounded_String ("uncle"), To_Bounded_String ("uncover"),
959 | To_Bounded_String ("under"), To_Bounded_String ("undo"),
960 | To_Bounded_String ("unfair"), To_Bounded_String ("unfold"),
961 | To_Bounded_String ("unhappy"), To_Bounded_String ("uniform"),
962 | To_Bounded_String ("unique"), To_Bounded_String ("unit"),
963 | To_Bounded_String ("universe"), To_Bounded_String ("unknown"),
964 | To_Bounded_String ("unlock"), To_Bounded_String ("until"),
965 | To_Bounded_String ("unusual"), To_Bounded_String ("unveil"),
966 | To_Bounded_String ("update"), To_Bounded_String ("upgrade"),
967 | To_Bounded_String ("uphold"), To_Bounded_String ("upon"),
968 | To_Bounded_String ("upper"), To_Bounded_String ("upset"),
969 | To_Bounded_String ("urban"), To_Bounded_String ("urge"),
970 | To_Bounded_String ("usage"), To_Bounded_String ("use"),
971 | To_Bounded_String ("used"), To_Bounded_String ("useful"),
972 | To_Bounded_String ("useless"), To_Bounded_String ("usual"),
973 | To_Bounded_String ("utility"), To_Bounded_String ("vacant"),
974 | To_Bounded_String ("vacuum"), To_Bounded_String ("vague"),
975 | To_Bounded_String ("valid"), To_Bounded_String ("valley"),
976 | To_Bounded_String ("valve"), To_Bounded_String ("van"),
977 | To_Bounded_String ("vanish"), To_Bounded_String ("vapor"),
978 | To_Bounded_String ("various"), To_Bounded_String ("vast"),
979 | To_Bounded_String ("vault"), To_Bounded_String ("vehicle"),
980 | To_Bounded_String ("velvet"), To_Bounded_String ("vendor"),
981 | To_Bounded_String ("venture"), To_Bounded_String ("venue"),
982 | To_Bounded_String ("verb"), To_Bounded_String ("verify"),
983 | To_Bounded_String ("version"), To_Bounded_String ("very"),
984 | To_Bounded_String ("vessel"), To_Bounded_String ("veteran"),
985 | To_Bounded_String ("viable"), To_Bounded_String ("vibrant"),
986 | To_Bounded_String ("vicious"), To_Bounded_String ("victory"),
987 | To_Bounded_String ("video"), To_Bounded_String ("view"),
988 | To_Bounded_String ("village"), To_Bounded_String ("vintage"),
989 | To_Bounded_String ("violin"), To_Bounded_String ("virtual"),
990 | To_Bounded_String ("virus"), To_Bounded_String ("visa"),
991 | To_Bounded_String ("visit"), To_Bounded_String ("visual"),
992 | To_Bounded_String ("vital"), To_Bounded_String ("vivid"),
993 | To_Bounded_String ("vocal"), To_Bounded_String ("voice"),
994 | To_Bounded_String ("void"), To_Bounded_String ("volcano"),
995 | To_Bounded_String ("volume"), To_Bounded_String ("vote"),
996 | To_Bounded_String ("voyage"), To_Bounded_String ("wage"),
997 | To_Bounded_String ("wagon"), To_Bounded_String ("wait"),
998 | To_Bounded_String ("walk"), To_Bounded_String ("wall"),
999 | To_Bounded_String ("walnut"), To_Bounded_String ("want"),
1000 | To_Bounded_String ("warfare"), To_Bounded_String ("warm"),
1001 | To_Bounded_String ("warrior"), To_Bounded_String ("wash"),
1002 | To_Bounded_String ("wasp"), To_Bounded_String ("waste"),
1003 | To_Bounded_String ("water"), To_Bounded_String ("wave"),
1004 | To_Bounded_String ("way"), To_Bounded_String ("wealth"),
1005 | To_Bounded_String ("weapon"), To_Bounded_String ("wear"),
1006 | To_Bounded_String ("weasel"), To_Bounded_String ("weather"),
1007 | To_Bounded_String ("web"), To_Bounded_String ("wedding"),
1008 | To_Bounded_String ("weekend"), To_Bounded_String ("weird"),
1009 | To_Bounded_String ("welcome"), To_Bounded_String ("west"),
1010 | To_Bounded_String ("wet"), To_Bounded_String ("whale"),
1011 | To_Bounded_String ("what"), To_Bounded_String ("wheat"),
1012 | To_Bounded_String ("wheel"), To_Bounded_String ("when"),
1013 | To_Bounded_String ("where"), To_Bounded_String ("whip"),
1014 | To_Bounded_String ("whisper"), To_Bounded_String ("wide"),
1015 | To_Bounded_String ("width"), To_Bounded_String ("wife"),
1016 | To_Bounded_String ("wild"), To_Bounded_String ("will"),
1017 | To_Bounded_String ("win"), To_Bounded_String ("window"),
1018 | To_Bounded_String ("wine"), To_Bounded_String ("wing"),
1019 | To_Bounded_String ("wink"), To_Bounded_String ("winner"),
1020 | To_Bounded_String ("winter"), To_Bounded_String ("wire"),
1021 | To_Bounded_String ("wisdom"), To_Bounded_String ("wise"),
1022 | To_Bounded_String ("wish"), To_Bounded_String ("witness"),
1023 | To_Bounded_String ("wolf"), To_Bounded_String ("woman"),
1024 | To_Bounded_String ("wonder"), To_Bounded_String ("wood"),
1025 | To_Bounded_String ("wool"), To_Bounded_String ("word"),
1026 | To_Bounded_String ("work"), To_Bounded_String ("world"),
1027 | To_Bounded_String ("worry"), To_Bounded_String ("worth"),
1028 | To_Bounded_String ("wrap"), To_Bounded_String ("wreck"),
1029 | To_Bounded_String ("wrestle"), To_Bounded_String ("wrist"),
1030 | To_Bounded_String ("write"), To_Bounded_String ("wrong"),
1031 | To_Bounded_String ("yard"), To_Bounded_String ("year"),
1032 | To_Bounded_String ("yellow"), To_Bounded_String ("you"),
1033 | To_Bounded_String ("young"), To_Bounded_String ("youth"),
1034 | To_Bounded_String ("zebra"), To_Bounded_String ("zero"),
1035 | To_Bounded_String ("zone"), To_Bounded_String ("zoo"));
1036 | end Words;
1037 |
--------------------------------------------------------------------------------
/source/workers.adb:
--------------------------------------------------------------------------------
1 | pragma Ada_2012;
2 |
3 | with Ada.Containers; use Ada.Containers;
4 | with Ada.Calendar; use Ada.Calendar;
5 | with Ada.Directories;
6 | with Ada.Task_Identification; use Ada.Task_Identification;
7 | with Ada.Text_IO; use Ada.Text_IO;
8 | with GNAT.Regexp;
9 | with GNAT.Formatted_String; use GNAT.Formatted_String;
10 |
11 | with Interfaces; use Interfaces;
12 |
13 | with Addresses;
14 | with Cryptography;
15 |
16 | package body Workers is
17 | protected body Control is
18 | procedure Signal_Stop is
19 | begin
20 | Flag_Stop := True;
21 | end Signal_Stop;
22 |
23 | function Stop return Boolean is (Flag_Stop);
24 | end Control;
25 |
26 | procedure Stop is
27 | begin
28 | Put_Line (Standard_Error, "Exiting...");
29 | Control.Signal_Stop;
30 | end Stop;
31 |
32 | task body Worker is
33 | use GNAT.Regexp;
34 |
35 | Current : Work_Unit;
36 | Kind : Wallets.Wallet_Kind;
37 | Test_Only : Boolean;
38 | Bounceable : Boolean;
39 | Expression : Regexp;
40 | Start_Time : Time;
41 | Index : Unsigned_64 := 1;
42 | begin
43 | accept Start
44 | (Kind : Wallets.Wallet_Kind;
45 | Test_Only : Boolean;
46 | Bounceable : Boolean;
47 | Pattern : String;
48 | Case_Sensitive : Boolean)
49 | do
50 | Worker.Kind := Kind;
51 | Worker.Test_Only := Test_Only;
52 | Worker.Bounceable := Bounceable;
53 | Expression := Compile (Pattern, False, Case_Sensitive);
54 | Start_Time := Clock;
55 | end Start;
56 |
57 | while not Control.Stop loop
58 | Current.Phrase := Generate;
59 | declare
60 | use Cryptography;
61 |
62 | KP : constant Key_Pair := To_Key_Pair (Current.Phrase);
63 | begin
64 | Current.Address :=
65 | Addresses.To_String
66 | (Wallets.Get_Wallet_Address
67 | (Public_Key => KP.Public_Key, Kind => Kind, Test_Only => Test_Only,
68 | Bounceable => Bounceable));
69 |
70 | if Match (Current.Address, Expression) then
71 | Work_Queue.Enqueue (Current);
72 | end if;
73 | end;
74 |
75 | if (Index and Unsigned_64 (16#FFF#)) = 0 then
76 | declare
77 | Taken : constant Duration := Clock - Start_Time;
78 | begin
79 | Put_Line
80 | (Standard_Error,
81 | -(+"[%s] Progress: %s, last %d took %fs (%f addr/sec)" &
82 | Image (Current_Task) & Index'Image & Integer (16#FFF#) &
83 | Taken & ((16#FFF# * 1.0) / Taken)));
84 | Start_Time := Clock;
85 | end;
86 | end if;
87 |
88 | Index := Index + 1;
89 | end loop;
90 | Put_Line (Standard_Error, -(+"[%s] Finished" & Image (Current_Task)));
91 | end Worker;
92 |
93 | task body Writer is
94 | Current : Work_Unit;
95 |
96 | type File_Access_Array is array (Positive range <>) of File_Access;
97 | type File_Access_Array_Access is access File_Access_Array;
98 | Outputs_Array : File_Access_Array_Access;
99 |
100 | Output_File : aliased File_Type;
101 | begin
102 | select
103 | accept Start (File_Name : String := "") do
104 | if File_Name = "" then
105 | Outputs_Array := new File_Access_Array (1 .. 1);
106 | Outputs_Array.all (1) := Standard_Output;
107 | else
108 | if Ada.Directories.Exists (File_Name) then
109 | Put_Line
110 | (Standard_Error,
111 | -(+"[%s] Logging program output to %s" &
112 | Image (Current_Task) & File_Name));
113 | Open (Output_File, Append_File, File_Name);
114 | else
115 | Put_Line
116 | (Standard_Error,
117 | -(+"[%s] Log file %s does not exist, creating a new one" &
118 | Image (Current_Task) & File_Name));
119 | Create (Output_File, Append_File, File_Name);
120 | end if;
121 |
122 | Outputs_Array := new File_Access_Array (1 .. 2);
123 | Outputs_Array.all (1) := Standard_Output;
124 | Outputs_Array.all (2) := Output_File'Unchecked_Access;
125 | end if;
126 | end Start;
127 | or
128 | terminate;
129 | end select;
130 |
131 | while (not Control.Stop) or else (Work_Queue.Current_Use /= 0) loop
132 | if Work_Queue.Current_Use /= 0 then
133 | Work_Queue.Dequeue (Current);
134 |
135 | for File of Outputs_Array.all loop
136 | Put_Line
137 | (File.all,
138 | Current.Address & "|" & To_String (Current.Phrase));
139 | end loop;
140 | end if;
141 | end loop;
142 |
143 | Close (Output_File);
144 | Put_Line (Standard_Error, -(+"[%s] Finished" & Image (Current_Task)));
145 | end Writer;
146 | end Workers;
147 |
--------------------------------------------------------------------------------
/source/workers.ads:
--------------------------------------------------------------------------------
1 | with Ada.Containers;
2 | with Ada.Containers.Bounded_Synchronized_Queues;
3 | with Ada.Containers.Synchronized_Queue_Interfaces;
4 |
5 | with Wallets;
6 | with Mnemonics; use Mnemonics;
7 |
8 | package Workers is
9 | subtype Mnemonic24 is Mnemonic (1 .. 24);
10 |
11 | type Work_Unit is record
12 | Address : String (1 .. 48);
13 | Phrase : Mnemonic24;
14 | end record;
15 |
16 | package Work_Queue_Interfaces is new Ada.Containers
17 | .Synchronized_Queue_Interfaces
18 | (Element_Type => Work_Unit);
19 |
20 | package Work_Queues is new Ada.Containers.Bounded_Synchronized_Queues
21 | (Queue_Interfaces => Work_Queue_Interfaces, Default_Capacity => 16#FFFF#);
22 |
23 | Work_Queue : Work_Queues.Queue;
24 |
25 | protected Control is
26 | procedure Signal_Stop;
27 | function Stop return Boolean;
28 | private
29 | Flag_Stop : Boolean := False;
30 | end Control;
31 |
32 | procedure Stop;
33 |
34 | task type Worker is
35 | entry Start
36 | (Kind : Wallets.Wallet_Kind;
37 | Test_Only : Boolean;
38 | Bounceable : Boolean;
39 | Pattern : String;
40 | Case_Sensitive : Boolean);
41 | end Worker;
42 |
43 | task type Writer is
44 | entry Start (File_Name : String := "");
45 | end Writer;
46 | end Workers;
47 |
--------------------------------------------------------------------------------
/vaniton.gpr:
--------------------------------------------------------------------------------
1 | with "third-party/sparknacl/sparknacl.gpr";
2 |
3 | project Vaniton is
4 | Source_Directories := (
5 | "source/**",
6 | "third-party/fastpbkdf2"
7 | );
8 | Excluded_Sources := (
9 | "bench.c",
10 | "benchmulti.c",
11 | "testfastpbkdf2.c"
12 | );
13 |
14 | Global_Switches_Ada := (
15 | -- "-gnat2022", -- HOLY SHIT THE FUTURE
16 | "-gnatiw", -- Support wide-character codes in identifiers
17 | "-gnatW8" -- Utf-8 encoding for wide characters
18 | );
19 |
20 | Global_Switches_C := ();
21 |
22 | type Build_Type is ("DEBUG", "RELEASE");
23 | Build_Mode : Build_Type := External ("BUILD", "DEBUG");
24 |
25 | type OS_Type is ("Windows_NT", "LINUX");
26 | OS : Os_Type := EXTERNAL("OS", "LINUX");
27 | case OS is
28 | when "Windows_NT" =>
29 |
30 | when "LINUX" =>
31 |
32 | end case;
33 |
34 | for Languages use ("Ada", "C");
35 |
36 | for Create_Missing_Dirs use "True";
37 | for Source_Dirs use Source_Directories;
38 | for Excluded_Source_Files use Excluded_Sources;
39 | for Object_Dir use "build";
40 | for Exec_Dir use "bin";
41 | for Main use ("vaniton.adb", "mnemonic2address.adb", "benchmark.adb");
42 |
43 | package Builder is
44 | --
45 | end Builder;
46 |
47 | package Compiler is
48 | Compiler_Switches_Ada := ();
49 | Compiler_Switches_C := ();
50 |
51 | case Build_Mode is
52 | when "DEBUG" =>
53 | Compiler_Switches_Ada := Compiler_Switches_Ada & (
54 | -- "-gnatv", -- Verbose
55 | "-gnatU", -- Unique string errors
56 | "-gnatQ", -- Force generate ALI files
57 | "-gnatwa", -- Activate most optional warnings
58 | "-gnatwd", -- Implicit dereferencing
59 | "-gnatw.d", -- Tag warnings
60 | "-gnatwh", -- Hiding
61 | "-gnatw.h", -- Holes in record layouts
62 | "-gnatw.j", -- Late primitives of tagged types
63 | "-gnatw.k", -- Redefinition of names in standard
64 | "-gnatwl", -- Elaboration warnings
65 | "-gnatw.l", -- Inherited aspects
66 | "-gnatw.n", -- Atomic synchronization
67 | "-gnatwo", -- Address clause overlay
68 | "-gnatw.o", -- Values set by out parameters ignored
69 | "-gnatw.q", -- Questionable layout of record types
70 | "-gnatw_r", -- Out-of-order record representation clauses
71 | "-gnatw.s", -- Overriden size clause
72 | "-gnatwt", -- Tracking of deleted conditional code
73 | "-gnatw.u", -- Unordered enumeration
74 | "-gnatw.w", -- Use of Warnings Off
75 | -- "-gnatw.y", -- Reasons for package needing body
76 | "-Wall", -- Most warnings from the GCC back end
77 | "-gnata", -- Enable assertions and contracts
78 | "-gnatVa", -- All validity checks
79 | "-gnatyy", -- Set all standard style check options
80 | -- "-gnatE", -- Enable dynamic checks for access-before-elaboration
81 | "-fstack-check", -- Enable stack check
82 |
83 | "-g", -- Debug info
84 | "-O0" -- No optimization
85 | );
86 | Compiler_Switches_C := Compiler_Switches_C & (
87 | "-g"
88 | );
89 | when "RELEASE" =>
90 | Compiler_Switches_Ada := Compiler_Switches_Ada & (
91 | "-O3", -- Optimization
92 | "-gnatn" -- Enable inlining
93 | );
94 | Compiler_Switches_C := Compiler_Switches_C & (
95 | "-O3",
96 | "-DNDEBUG"
97 | );
98 | end case;
99 |
100 | for Switches ("Ada") use Global_Switches_Ada & Compiler_Switches_Ada;
101 | for Switches ("C") use Global_Switches_C & Compiler_Switches_C;
102 | end Compiler;
103 |
104 | package Binder is
105 | for Switches ("Ada") use (
106 | "-Es", -- Symbolic traceback
107 | "-static"
108 | );
109 | end Binder;
110 |
111 | package Naming is
112 | --
113 | end Naming;
114 |
115 | package Linker is
116 | for Required_Switches use ("-lcrypto");
117 | end Linker;
118 | end Vaniton;
119 |
120 |
--------------------------------------------------------------------------------