├── .dockerignore
├── .github
└── workflows
│ ├── linter.yml
│ ├── linux.yml
│ └── macOS.yml
├── .gitignore
├── .gitmodules
├── .vscode
├── c_cpp_properties.json
├── launch.json
├── settings.json
└── tasks.json
├── CLA-signed
├── CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc
├── CLA.secinthenet.4da78f8447e15659ab7e06db0409549979ff5b43.asc
└── CLA.wolfmcnally.943652EE38441760C3DC35364B6C2FCF894780AE.asc
├── CLA.md
├── CODEOWNERS
├── CONTRIBUTING.md
├── Dockerfile
├── Docs
├── Install-Windows.md
├── MANUAL.md
└── Usage.md
├── LICENSE
├── Makefile.in
├── README.md
├── bootstrap.sh
├── build-aux
├── config.guess
├── config.sub
└── install-sh
├── build.sh
├── build
├── build-tailsOS.Dockerfile
└── packaging.md
├── configure
├── configure.ac
├── debian
├── README.Debian
├── README.source
├── changelog
├── clean
├── control
├── copyright
├── manpage.1.ex
├── manpage.md.ex
├── manpage.sgml.ex
├── manpage.xml.ex
├── patches
│ ├── fix-build.diff
│ └── series
├── postinst.ex
├── postrm.ex
├── preinst.ex
├── prerm.ex
├── rules
├── salsa-ci.yml.ex
├── seedtool-cli-docs.docs
├── seedtool-cli.cron.d.ex
├── seedtool-cli.doc-base.ex
├── source
│ ├── format
│ ├── include-binaries
│ └── options
├── upstream
│ └── metadata.ex
└── watch.ex
├── example-scripts
├── bip39-to-sskr.sh
└── sskr-to-bip39.sh
├── images
└── logos
│ ├── README.md
│ ├── seedtool-logo-black.jpg
│ ├── seedtool-logo-black.png
│ ├── seedtool-logo-black.psd
│ ├── seedtool-logo-shapes.ai
│ ├── seedtool-logo-white.jpg
│ ├── seedtool-logo-white.png
│ ├── seedtool-logo-white.psd
│ ├── seedtool-screen.jpg
│ ├── seedtool-screen.png
│ └── seedtool-screen.psd
├── install-sh
├── manual-images
└── seedqrcode.png
├── set_build_paths.sh
└── src
├── .gitignore
├── Makefile.in
├── cbor-utils.hpp
├── config.h.in
├── format-base10.cpp
├── format-base10.hpp
├── format-base6.cpp
├── format-base6.hpp
├── format-bip39.cpp
├── format-bip39.hpp
├── format-bits.cpp
├── format-bits.hpp
├── format-bytewords-minimal.cpp
├── format-bytewords-minimal.hpp
├── format-bytewords-uri.cpp
├── format-bytewords-uri.hpp
├── format-bytewords.cpp
├── format-bytewords.hpp
├── format-cards.cpp
├── format-cards.hpp
├── format-dice.cpp
├── format-dice.hpp
├── format-hex.cpp
├── format-hex.hpp
├── format-ints.cpp
├── format-ints.hpp
├── format-random.cpp
├── format-random.hpp
├── format-sskr.cpp
├── format-sskr.hpp
├── format.cpp
├── format.hpp
├── formats-all.hpp
├── hkdf.c
├── hkdf.h
├── params.cpp
├── params.hpp
├── random.cpp
├── random.hpp
├── randombytes.c
├── randombytes.h
├── seedtool.cpp
├── test.sh
├── utils.cpp
└── utils.hpp
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Exclude docker related files so that the docker layer cache won't be
2 | # invalidated when editing them because the build context changes.
3 | Dockerfile
4 | .dockerignore
5 |
6 | # Created by https://www.gitignore.io/api/macos
7 |
8 | ### macOS ###
9 | # General
10 | .DS_Store
11 | .AppleDouble
12 | .LSOverride
13 |
14 | # Icon must end with two \r
15 | Icon
16 |
17 | # Thumbnails
18 | ._*
19 |
20 | # Files that might appear in the root of a volume
21 | .DocumentRevisions-V100
22 | .fseventsd
23 | .Spotlight-V100
24 | .TemporaryItems
25 | .Trashes
26 | .VolumeIcon.icns
27 | .com.apple.timemachine.donotpresent
28 |
29 | # Directories potentially created on remote AFP share
30 | .AppleDB
31 | .AppleDesktop
32 | Network Trash Folder
33 | Temporary Items
34 | .apdisk
35 |
36 | # End of https://www.gitignore.io/api/macos
37 |
38 | # Created by https://www.gitignore.io/api/c
39 |
40 | ### C ###
41 | # Prerequisites
42 | *.d
43 |
44 | # Object files
45 | *.o
46 | *.ko
47 | *.obj
48 | *.elf
49 |
50 | # Linker output
51 | *.ilk
52 | *.map
53 | *.exp
54 |
55 | # Precompiled Headers
56 | *.gch
57 | *.pch
58 |
59 | # Libraries
60 | *.lib
61 | *.a
62 | *.la
63 | *.lo
64 |
65 | # Shared objects (inc. Windows DLLs)
66 | *.dll
67 | *.so
68 | *.so.*
69 | *.dylib
70 |
71 | # Executables
72 | *.exe
73 | *.out
74 | *.app
75 | *.i*86
76 | *.x86_64
77 | *.hex
78 |
79 | # Debug files
80 | *.dSYM/
81 | *.su
82 | *.idb
83 | *.pdb
84 |
85 | # Kernel Module Compile Results
86 | *.mod*
87 | *.cmd
88 | .tmp_versions/
89 | modules.order
90 | Module.symvers
91 | Mkfile.old
92 | dkms.conf
93 |
94 | # End of https://www.gitignore.io/api/c
95 |
96 | autom4te.cache
97 | autoscan.log
98 | Makefile
99 | config.log
100 | config.status
101 | configure.scan
102 | config.h
103 | sysroot/
104 |
--------------------------------------------------------------------------------
/.github/workflows/linter.yml:
--------------------------------------------------------------------------------
1 | name: linter
2 | on: [push, pull_request]
3 | jobs:
4 | Lint:
5 | runs-on: macos-latest
6 | steps:
7 | - uses: actions/checkout@v2
8 | - run: brew install cppcheck
9 | - run: cppcheck --enable=all --error-exitcode=1 --inline-suppr --suppress=missingInclude --suppress=ConfigurationNotChecked .
10 |
--------------------------------------------------------------------------------
/.github/workflows/linux.yml:
--------------------------------------------------------------------------------
1 | name: linux
2 | on: [push, pull_request]
3 | jobs:
4 | build-Linux:
5 | runs-on: ubuntu-18.04
6 | steps:
7 | - uses: actions/checkout@v2
8 | - run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - || exit 1
9 | - run: sudo apt-add-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main" || exit 1
10 | - run: sudo apt-get update || exit 1
11 | - run: sudo apt-get install -y clang-10 libc++-10-dev libc++abi-10-dev shunit2 make || exit 1
12 | - run: export CC="clang-10" && export CXX="clang++-10" && ./build.sh
13 | - run: sudo make install
14 | - run: make distclean
15 |
--------------------------------------------------------------------------------
/.github/workflows/macOS.yml:
--------------------------------------------------------------------------------
1 | name: macOS
2 | on: [push, pull_request]
3 | jobs:
4 | build-MacOS:
5 | runs-on: macos-latest
6 | steps:
7 | - uses: actions/checkout@v2
8 | - run: brew install autoconf automake libtool shunit2 cppcheck
9 | - run: ./build.sh
10 | - run: sudo make install
11 | - run: make distclean
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/macos
2 |
3 | ### macOS ###
4 | # General
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 |
9 | # Icon must end with two \r
10 | Icon
11 |
12 | # Thumbnails
13 | ._*
14 |
15 | # Files that might appear in the root of a volume
16 | .DocumentRevisions-V100
17 | .fseventsd
18 | .Spotlight-V100
19 | .TemporaryItems
20 | .Trashes
21 | .VolumeIcon.icns
22 | .com.apple.timemachine.donotpresent
23 |
24 | # Directories potentially created on remote AFP share
25 | .AppleDB
26 | .AppleDesktop
27 | Network Trash Folder
28 | Temporary Items
29 | .apdisk
30 |
31 | # End of https://www.gitignore.io/api/macos
32 |
33 | # Created by https://www.gitignore.io/api/c
34 |
35 | ### C ###
36 | # Prerequisites
37 | *.d
38 |
39 | # Object files
40 | *.o
41 | *.ko
42 | *.obj
43 | *.elf
44 |
45 | # Linker output
46 | *.ilk
47 | *.map
48 | *.exp
49 |
50 | # Precompiled Headers
51 | *.gch
52 | *.pch
53 |
54 | # Libraries
55 | *.lib
56 | *.a
57 | *.la
58 | *.lo
59 |
60 | # Shared objects (inc. Windows DLLs)
61 | *.dll
62 | *.so
63 | *.so.*
64 | *.dylib
65 |
66 | # Executables
67 | *.exe
68 | *.out
69 | *.app
70 | *.i*86
71 | *.x86_64
72 | *.hex
73 |
74 | # Debug files
75 | *.dSYM/
76 | *.su
77 | *.idb
78 | *.pdb
79 |
80 | # Kernel Module Compile Results
81 | *.mod*
82 | *.cmd
83 | .tmp_versions/
84 | modules.order
85 | Module.symvers
86 | Mkfile.old
87 | dkms.conf
88 |
89 | # End of https://www.gitignore.io/api/c
90 |
91 | autom4te.cache
92 | autoscan.log
93 | Makefile
94 | config.log
95 | config.status
96 | configure.scan
97 | config.h
98 | sysroot/
99 | .vscode/configurationCache.log
100 | .vscode/dryrun.log
101 | .vscode/targets.log
102 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "deps/bc-crypto-base"]
2 | path = deps/bc-crypto-base
3 | url = https://github.com/BlockchainCommons/bc-crypto-base.git
4 | [submodule "deps/bc-shamir"]
5 | path = deps/bc-shamir
6 | url = https://github.com/blockchaincommons/bc-shamir.git
7 | [submodule "deps/bc-bip39"]
8 | path = deps/bc-bip39
9 | url = https://github.com/blockchaincommons/bc-bip39.git
10 | [submodule "deps/argp-standalone"]
11 | path = deps/argp-standalone
12 | url = https://github.com/BlockchainCommons/argp-standalone.git
13 | ignore = dirty
14 | [submodule "deps/bc-ur"]
15 | path = deps/bc-ur
16 | url = https://github.com/BlockchainCommons/bc-ur.git
17 | [submodule "deps/bc-sskr"]
18 | path = deps/bc-sskr
19 | url = https://github.com/BlockchainCommons/bc-sskr.git
20 | [submodule "deps/shunit2"]
21 | path = deps/shunit2
22 | url = https://github.com/kward/shunit2
23 |
--------------------------------------------------------------------------------
/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": [
3 | {
4 | "name": "Mac",
5 | "includePath": [
6 | "${workspaceFolder}/**"
7 | ],
8 | "defines": [],
9 | "macFrameworkPath": [
10 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
11 | ],
12 | "compilerPath": "/usr/bin/clang",
13 | "cStandard": "c11",
14 | "intelliSenseMode": "clang-x64"
15 | }
16 | ],
17 | "version": 4
18 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | // You may need to install the extension "CodeLLDB" for debugging to work on Macs with Catalina.
6 | "name": "Build and Debug",
7 | "type": "lldb",
8 | "request": "launch",
9 | "program": "${workspaceFolder}/src/seedtool",
10 | "args": [ ],
11 | "cwd": "${workspaceFolder}/src",
12 | "preLaunchTask": "Build"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "Makefile.in": "makefile"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Configure",
6 | "type": "shell",
7 | "command": "source set_build_paths.sh && ./configure",
8 | "problemMatcher": []
9 | },
10 | {
11 | "label": "Build",
12 | "type": "shell",
13 | "command": "source set_build_paths.sh && make all && dsymutil src/seedtool",
14 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] },
15 | "group": {
16 | "kind": "build",
17 | "isDefault": true
18 | }
19 | },
20 | {
21 | "label": "Test",
22 | "type": "shell",
23 | "command": "source set_build_paths.sh && make check",
24 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] },
25 | "group": {
26 | "kind": "test",
27 | "isDefault": true
28 | }
29 | },
30 | {
31 | "label": "Distribution Test",
32 | "type": "shell",
33 | "command": "source set_build_paths.sh && make distcheck",
34 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] },
35 | "group": "test"
36 | },
37 | {
38 | "label": "Distribution",
39 | "type": "shell",
40 | "command": "source set_build_paths.sh && make dist",
41 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] }
42 | },
43 | {
44 | "label": "Distribution Clean",
45 | "type": "shell",
46 | "command": "source set_build_paths.sh && make distclean",
47 | "problemMatcher": []
48 | },
49 | {
50 | "label": "Distribution Build",
51 | "type": "shell",
52 | "command": "source set_build_paths.sh && ./build.sh",
53 | "problemMatcher": []
54 | },
55 | {
56 | "label": "Clean",
57 | "type": "shell",
58 | "command": "source set_build_paths.sh && make clean",
59 | "problemMatcher": []
60 | },
61 | {
62 | "label": "Install",
63 | "type": "shell",
64 | "command": "sudo make install",
65 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] }
66 | },
67 | {
68 | "label": "Uninstall",
69 | "type": "shell",
70 | "command": "sudo make uninstall",
71 | "problemMatcher": { "base": "$gcc", "fileLocation": ["relative", "${workspaceRoot}/src"] }
72 | },
73 | {
74 | "label": "Lint",
75 | "type": "shell",
76 | "command": "make lint",
77 | "problemMatcher": {
78 | "fileLocation": ["relative", "${workspaceRoot}/src"],
79 | "severity": "warning",
80 | "pattern": {
81 | "regexp": "^(.*?):(\\d+):(\\d+):\\s+(error|warning|style|performance|portability|note|information):(.*)$",
82 | "file": 1,
83 | "line": 2,
84 | "column": 3,
85 | "severity": 4,
86 | "message": 5
87 | }
88 | }
89 | }
90 | ]
91 | }
92 |
--------------------------------------------------------------------------------
/CLA-signed/CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc:
--------------------------------------------------------------------------------
1 | -----BEGIN PGP SIGNED MESSAGE-----
2 | Hash: SHA512
3 |
4 | # Contributor License Agreement
5 |
6 | Version 1.0
7 |
8 | Name: Gorazd Kovacic
9 |
10 | E-Mail: gorazdko@gmail.com
11 |
12 | Legal Jurisdiction: Wyoming, United States of America
13 |
14 | Project: https://github.com/BlockchainCommons/bc-seedtool-cli
15 |
16 | Date: 09-03-2020
17 |
18 | ## Purpose
19 |
20 | This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
21 |
22 | ## License
23 |
24 | I hereby license Blockchain Commons, LLC to:
25 |
26 | 1. do anything with my contributions that would otherwise infringe my copyright in them
27 |
28 | 2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
29 |
30 | 3. sublicense these rights to others on any terms they like
31 |
32 | ## Reliability
33 |
34 | I understand that Blockchain Commons will rely on this license. I may not revoke this license.
35 |
36 | ## Awareness
37 |
38 | I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
39 |
40 | ## Copyright Guarantee
41 |
42 | I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
43 |
44 | ## Patent Guarantee
45 |
46 | I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
47 |
48 | ## Open Source Guarantee
49 |
50 | I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
51 |
52 | ## Disclaimers
53 |
54 | ***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
55 |
56 | - ---
57 |
58 | To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
59 |
60 | -----BEGIN PGP SIGNATURE-----
61 |
62 | iQIzBAEBCgAdFiEEQfDqFpmnTB4vpBtTjPlrw/+du84FAmCQE4IACgkQjPlrw/+d
63 | u87qQA/9EHBvCPS9E2w29hBQVjEZTWBEJIaPRQCEU0THzwZ+Sf/06ND8Gcajw0mW
64 | EjCtgQ2zVPo8fvtqHjWBV+PMGpUAmMtW0r2LjOkC6MGNe5Re0q0QBlBhUf2BV8FH
65 | /LD5bJ3IJRZp8EEUKsLR2uDWRpcCr20DShInsvaXZBy8+ZZoFCjvqKbrkLOt7/xU
66 | 9hcyb3DIyRrHj/JddpmbSksA4LwJA2s4j8uzwRVf7DJxvKatH2M2RRATKYOhTxRo
67 | P/UW9JLVCHh8JunxFLikx2rZ+05qKNC1XqT8oUrnJFMqswWoBk+U7N3xdtl+imfg
68 | gi5ki6FiIjavwCRRmBAxyI2Y4emE92rEwCjF0FhP2wRGYyeOTuchM2dWMYtk8e/+
69 | 9a6s2YuiTurQBpKiHQm98AC8VvEqCGnY9ellekNQAWhsVg5ALR73yeZReB0rolr/
70 | qFKq/nIeBtigxqoSvHn4HeHNiwoFIx3w5KOhMKPk64j4GHglaK7qMBs3AG03rbVK
71 | rc7IhbkydCYiUDCAL3UKuxRtS+f6uEK378ounFIgxuo4ZCVb4EUijTv4E8q0foBZ
72 | TFj7IpQno+HkEqOSkzq30gCSsXxC/CorF42PJ5qm5jpYc9LtiaMKhc/WHkRc9SpH
73 | A1Xe/UBqgN5fITplHIAjLrYSYmj2NLctVGx5A2MmCbtrHz8B5jI=
74 | =xYXb
75 | -----END PGP SIGNATURE-----
76 |
--------------------------------------------------------------------------------
/CLA-signed/CLA.secinthenet.4da78f8447e15659ab7e06db0409549979ff5b43.asc:
--------------------------------------------------------------------------------
1 | -----BEGIN PGP SIGNED MESSAGE-----
2 | Hash: SHA512
3 |
4 | # Contributor License Agreement
5 |
6 | Version 1.0
7 |
8 | Name: `Sylvia G`
9 |
10 | E-Mail: `q0h8xdveje@gmail.com`
11 |
12 | Legal Jurisdiction: Wyoming, United States of America
13 |
14 | Project: https://github.com/BlockchainCommons/bc-seedtool-cli
15 |
16 | Date: `March 31, 2021`
17 |
18 | ## Purpose
19 |
20 | This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
21 |
22 | ## License
23 |
24 | I hereby license Blockchain Commons, LLC to:
25 |
26 | 1. do anything with my contributions that would otherwise infringe my copyright in them
27 |
28 | 2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
29 |
30 | 3. sublicense these rights to others on any terms they like
31 |
32 | ## Reliability
33 |
34 | I understand that Blockchain Commons will rely on this license. I may not revoke this license.
35 |
36 | ## Awareness
37 |
38 | I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
39 |
40 | ## Copyright Guarantee
41 |
42 | I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
43 |
44 | ## Patent Guarantee
45 |
46 | I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
47 |
48 | ## Open Source Guarantee
49 |
50 | I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
51 |
52 | ## Disclaimers
53 |
54 | ***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
55 |
56 | - ---
57 |
58 | To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
59 |
60 | -----BEGIN PGP SIGNATURE-----
61 |
62 | iQGzBAEBCgAdFiEETaePhEfhVlmrfgbbBAlUmXn/W0MFAmBkXvgACgkQBAlUmXn/
63 | W0NjyQwAme1hxmXo4vEK5q8VZFxk8/Dqy43ZnQlSxFpFceoB12GJhpce1OxiHi7d
64 | LLErPnUV2AQAoo9L5qKTv0w3NRGsWur89s1EfSJCUtsqXPtqkzZS5GC47cAoEGxM
65 | cN0KIoJozIz2d0c7EFDy1p9bvb+r8H6FIkH/qNKSvuonLLaK+q0xgt6PUQcjY+NI
66 | CbiOjGiHBz4/BgYQOMa6E3knwM8WKQlRnhoL6JyjfVnD8QRkaus0NEFW/BBnw/cP
67 | GvlK61IdOaea1bGu68qmv45R6l9JilL7OKaY4tQnmTp3fMw/NYxnTpRIiW+kMXSn
68 | dOPNdeyk8UM6dJuLlxh9BstOhOER+UZ/zEAiim5vjYbBXzGMyP25gA9hkUXwX2a8
69 | Q0oocAoU+WwFqCHe7NyJeGieZhIFcBYNS2mdjsxfjjzWiz8huB407CN0+Kg0qLfQ
70 | 3VIUeFY70QTXPLwtci+eOI2sahGA0orYDjoC8/dpT/OyRhfT24kfH9U9UG39Mm5w
71 | mCm0wIUa
72 | =IUqj
73 | -----END PGP SIGNATURE-----
74 |
--------------------------------------------------------------------------------
/CLA-signed/CLA.wolfmcnally.943652EE38441760C3DC35364B6C2FCF894780AE.asc:
--------------------------------------------------------------------------------
1 | -----BEGIN PGP SIGNED MESSAGE-----
2 | Hash: SHA256
3 |
4 | # Contributor License Agreement
5 |
6 | Version 1.0
7 |
8 | Name: `Wolf McNally`
9 |
10 | E-Mail: `wolf@wolfmcnally.com`
11 |
12 | Legal Jurisdiction: Wyoming, United States of America
13 |
14 | Project: https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli
15 |
16 | Date: `April 3, 2020`
17 |
18 | ## Purpose
19 |
20 | This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
21 |
22 | ## License
23 |
24 | I hereby license Blockchain Commons, LLC to:
25 |
26 | 1. do anything with my contributions that would otherwise infringe my copyright in them
27 |
28 | 2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
29 |
30 | 3. sublicense these rights to others on any terms they like
31 |
32 | ## Reliability
33 |
34 | I understand that Blockchain Commons will rely on this license. I may not revoke this license.
35 |
36 | ## Awareness
37 |
38 | I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
39 |
40 | ## Copyright Guarantee
41 |
42 | I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
43 |
44 | ## Patent Guarantee
45 |
46 | I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
47 |
48 | ## Open Source Guarantee
49 |
50 | I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
51 |
52 | ## Disclaimers
53 |
54 | ***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
55 | -----BEGIN PGP SIGNATURE-----
56 |
57 | iQIzBAEBCAAdFiEElDZS7jhEF2DD3DU2S2wvz4lHgK4FAmJGD8UACgkQS2wvz4lH
58 | gK4iKRAAsKfTUg/c1015APiSHO9yte8Q8eA2tuxV5kxK+OzA0PTRIlvw8RHLFyx+
59 | /ToqCZHKlny/m7BZYqJyFSXCOeF99FDJqUZL9AxODBUx/S1dqQ9ppEGqH5LDMm0c
60 | vwsqWtkSEj/T3XNyIId7etidbdrnyKPFNXl4lDHRsdrMvhSQHImb1d/FPACAdJTl
61 | i3dDc9Y4Z75JYOjWKPoBYjAIh2gY3+8lk2bghQtQfs1Crf7kHxWjtjMHMoUv+Qo3
62 | d6f4F6R2rpI5cr9pDHYa+IWe9Dfi3FgWA/Vvk/QC/FAvIm2BKY6f8xcX6XsSRPuK
63 | UJEmNJt1VTZz6HKw9s/vvaXybkZ6F+vLHE+Fjbn3zzjd1foiY6RXVF+XNcCOCppz
64 | lT1bWI9BU9rfNMj1x2WPQ1pJHO9m12Z/j7qjJTYZgQod6artiq2NXrHHZaMjSi0A
65 | wNz7tcH5MKahWAlIXBkPGevExXA5ncYU0CHKAABj0TVAy9bn9Gic68z0vPYwl+N9
66 | lfi0htPmAx5gL5u8+4eY/8y7BSzHp7NZHbYSAI36rbHc4JoaFAwyWIMo87bzD04B
67 | FXEJBNS8NYAjXPYKzp43mds0b7174XXFY6o2+uJDNDseNt93fDzgBa4UyUBUhdql
68 | iM8XELPLhgmEW1eRwwseRykDodQizJezPmPJxWNMjgOH1RZiT3k=
69 | =I4QP
70 | -----END PGP SIGNATURE-----
71 |
--------------------------------------------------------------------------------
/CLA.md:
--------------------------------------------------------------------------------
1 | # Contributor License Agreement
2 |
3 | Version 1.0
4 |
5 | Name: `$name`
6 |
7 | E-Mail: `$email`
8 |
9 | Legal Jurisdiction: Wyoming, United States of America
10 |
11 | Project: https://github.com/BlockchainCommons/seedtool-cli
12 |
13 | Date: `$date`
14 |
15 | ## Purpose
16 |
17 | This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
18 |
19 | ## License
20 |
21 | I hereby license Blockchain Commons, LLC to:
22 |
23 | 1. do anything with my contributions that would otherwise infringe my copyright in them
24 |
25 | 2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
26 |
27 | 3. sublicense these rights to others on any terms they like
28 |
29 | ## Reliability
30 |
31 | I understand that Blockchain Commons will rely on this license. I may not revoke this license.
32 |
33 | ## Awareness
34 |
35 | I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
36 |
37 | ## Copyright Guarantee
38 |
39 | I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
40 |
41 | ## Patent Guarantee
42 |
43 | I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
44 |
45 | ## Open Source Guarantee
46 |
47 | I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
48 |
49 | ## Disclaimers
50 |
51 | ***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
52 |
53 | ---
54 |
55 | To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
56 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These owners will be the default owners for everything in this repo.
2 |
3 | * @ChristopherA @wolfmcnally
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
4 |
5 | - Reporting a bug
6 | - Discussing the current state of the code
7 | - Submitting a fix
8 | - Proposing new features
9 | - Becoming a maintainer
10 |
11 | ## We Develop with Github
12 | We use GitHub to host code, to track issues and feature requests, as well as accept Pull Requests.
13 |
14 | ## Report bugs using Github's [issues](https://github.com/BlockchainCommons/seedtool-cli/issues)
15 | We use GitHub issues to track public bugs.
16 |
17 | If you find bugs, mistakes, inconsistencies in this project's code or documents, please let us know by [opening a new issue](https://github.com/BlockchainCommons/seedtool-cli/issues), but consider searching through existing issues first to check and see if the problem has already been reported. If it has, it never hurts to add a quick "+1" or "I have this problem too". This helps prioritize the most common problems and requests.
18 |
19 | ## Write bug reports with detail, background, and sample code
20 | [This is an example](http://stackoverflow.com/q/12488905/180626) of a good bug report by @briandk. Here's [another example from craig.hockenberry](http://www.openradar.me/11905408).
21 |
22 | **Great Bug Reports** tend to have:
23 |
24 | - A quick summary and/or background
25 | - Steps to reproduce
26 | - Be specific!
27 | - Give sample code if you can. [The stackoverflow bug report](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing
28 | - What you expected would happen
29 | - What actually happens
30 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
31 |
32 | People *love* thorough bug reports. I'm not even kidding.
33 |
34 | ## Submitting code changes through Pull Requests
35 |
36 | Simple Pull Requests to fix typos, document, or fix small bugs are always welcome.
37 |
38 | We ask that more significant improvements to the project be first proposed before anybody starts to code as an [issue](https://github.com/BlockchainCommons/seedtool-cli/issues) or as a [draft Pull Request](https://github.com/BlockchainCommons/seedtool-cli/pulls) (GitHub has a nice new feature for simple Pull Requests called [Draft Pull Requests](https://github.blog/2019-02-14-introducing-draft-pull-requests/). This gives other contributors a chance to point you in the right direction, give feedback on the design, and maybe point out if related work is already under way.
39 |
40 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
41 | Pull Requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your Pull Requests:
42 |
43 | 1. Fork the repo and create your branch from `master`.
44 | 2. If you've added code that should be tested, add tests.
45 | 3. If you've changed APIs, update the documentation.
46 | 4. Ensure the test suite passes.
47 | 5. Make sure your code lints.
48 | 6. Issue that Pull Request!
49 |
50 | ## Any code contributions you make will be under the BSD-2-Clause Plus Patent License
51 | In short, when you submit code changes, your submissions are understood will be available under the same [BSD-2-Clause Plus Patent License](./LICENSE.md) that covers the project. We also ask all code contributors to GPG sign the [Contributor License Agreement (CLA.md)](./CLA.md) to protect future users of this project. Feel free to contact the maintainers if that's a concern.
52 |
53 | ## Use a Consistent Coding Style
54 | * We indent using two spaces (soft tabs)
55 | * We ALWAYS put spaces after list items and method parameters ([1, 2, 3], not [1,2,3]), around operators (x += 1, not x+=1), and around hash arrows.
56 | * This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible.
57 |
58 | ## References
59 |
60 | Portions of this CONTRIBUTING.md document were adopted from best practices of a number of open source projects, including:
61 | * [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
62 | * [IPFS Contributing](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
63 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:20.04 as build-stage
2 | ARG DEBIAN_FRONTEND=noninteractive
3 | RUN apt-get update -y
4 | # Install build dependencies
5 | RUN apt-get install -y git
6 | RUN apt-get install -y build-essential
7 | RUN apt-get install -y libc++-10-dev libc++abi-10-dev
8 | RUN apt-get install -y lsb-release wget software-properties-common
9 | RUN wget https://apt.llvm.org/llvm.sh
10 | RUN chmod +x llvm.sh
11 | RUN ./llvm.sh 10 # version 10
12 | # Build seedtool-cli
13 | ENV CC="clang-10"
14 | ENV CXX="clang++-10"
15 | COPY . /seedtool-cli
16 | WORKDIR /seedtool-cli
17 | RUN git submodule update --init --recursive
18 | RUN CC="clang-10" CXX="clang++-10" ./build.sh
19 |
20 | # Export built executable to a minimal runtime image and run as an unprivileged
21 | # user.
22 | FROM ubuntu:20.04
23 | ARG DEBIAN_FRONTEND=noninteractive
24 | # Install runtime dependencies
25 | RUN apt-get update -y
26 | RUN apt-get install -y libc++1 libc++abi1
27 | # Install binary
28 | COPY --from=build-stage /seedtool-cli/src/seedtool /usr/local/bin/seedtool
29 | # Create an unprivileged user
30 | RUN useradd --create-home --user-group user
31 | USER user
32 | ENTRYPOINT ["seedtool"]
33 |
--------------------------------------------------------------------------------
/Docs/Install-Windows.md:
--------------------------------------------------------------------------------
1 | # Building Seedtool on Windows
2 |
3 | This document describes building `seedtool` with `MSYS2` and its usage on `Windows 10` 64-bit.
4 |
5 | ## Installing MSYS2 and Packages
6 |
7 | 1. Install `MSYS2` by downloading the installer and following the installation guide in [www.msys2.org](www.msys2.org).
8 | 2. Run `MSYS2` and make sure the package database is updated:
9 | ```bash
10 | # pacman -Syu
11 | # pacman -Su
12 | ```
13 | 3. Next, install the compiler and the required packages:
14 | ```bash
15 | # pacman -S mingw-w64-x86_64-clang
16 | # pacman -S patch
17 | # pacman -S git
18 | # pacman -S make
19 | # pacman -S mingw-w64-x86_64-libc++
20 | # pacman -S autoconf
21 | # pacman -S automake1.8
22 | ```
23 |
24 | ## Compiling Seedtool
25 |
26 | 1. Clone `seedtool-cli`, e.g. into `C:\msys64\home`
27 | 2. Open `MSYS2 MinGW 64-bit` application and `cd` into `C:\msys64\home\seedtool-cli`
28 | 3. Run the build script with:
29 | ```bash
30 | # export CC="clang" && export CXX="clang++" && ./build.sh
31 | ```
32 | 4. Install:
33 | ```bash
34 | # make install
35 | ```
36 | You can now freely use `seedtool` inside `MSYS2 MinGW 64-bit` console.
37 |
38 | ### Running Seedtool as a Native Windows App
39 |
40 | To be able to use `seedtool` as a native app on Windows outside `msys2/mingw64`, you have to expose three files to the system: `seedtool.exe`, `libc++.dll`, and `libunwind.dll`, which all reside in `C:\msys64\mingw64\bin`.
41 |
42 | To do so, add that folder to the `Windows PATH` by the following command in `Windows Cmd`:
43 | ```bash
44 | # set PATH=%PATH%;C:\msys64\mingw64\bin
45 | ```
46 | That's it. Now you can use `seedtool` as a native Windows app in the Windows command-line tool.
47 |
48 | *Note:* If you want to pipe seedtool ouput into a QR code generator, you could use:
49 |
50 | ```bash
51 | # seedtool --ur | python -c "import sys; print(sys.stdin.readlines()[0].upper())" | qr > seedqrcode.png
52 | ```
53 |
54 | For this you'll need `Python` and the following package:
55 |
56 | ```bash
57 | # pip install qrcode[pil]
58 | ```
59 |
60 |
--------------------------------------------------------------------------------
/Docs/Usage.md:
--------------------------------------------------------------------------------
1 | # 🌱 Seedtool Usage Examples
2 |
3 | ## Basic Information
4 |
5 | ### Display usage and help information
6 |
7 | ```
8 | $ seedtool --help
9 | ```
10 |
11 | ## Seed Generation
12 |
13 | ### Generate a cryptographically-strong 16-byte seed
14 |
15 | ```
16 | $ seedtool
17 | 8935a8068526d84da555cdb741a3b8a8
18 | ```
19 |
20 | ### Generate a seed using entropy provided as coin flips
21 |
22 | ```
23 | $ seedtool --in bits 1110110001110111
24 | 8d933e43b1bc8f2e3fc27adc98ad4534
25 | ```
26 |
27 | ### Generate a 32-byte seed using entropy provided as cards drawn from a deck of playing cards
28 |
29 | ```
30 | $ seedtool --count 32 --in cards 6c9s8c7c9c4cah6c2sjs7d5c2s4c4dqs
31 | 7df301924511326d7350be14c9e7176d98e945f9ad0ed034726ad4ee0de59c25
32 | ```
33 |
34 | ## BIP-39 Mnemonics
35 |
36 | ### Encode a 16-byte seed as BIP-39
37 |
38 | ```
39 | $ seedtool --in hex --out bip39 8935a8068526d84da555cdb741a3b8a8
40 | matrix pull accuse apart horn chat next rifle resemble artist until eye
41 | ```
42 |
43 | ### Decode BIP-39 mnemonics to hex
44 |
45 | ```
46 | $ seedtool --in bip39 "matrix pull accuse apart horn chat next rifle resemble artist until eye"
47 | 8935a8068526d84da555cdb741a3b8a8
48 | ```
49 |
50 | ## Bytewords
51 |
52 | ### Decode Bytewords to hex
53 |
54 | ```
55 | $ seedtool --in btw "deli need cats taxi dice door webs vows free zero legs wall half waxy trip oval memo sets rock hill"
56 | 279b18d0282aefe845fb83e956eed8a6
57 | ```
58 |
59 | ## SSKR
60 |
61 | ### Generate a 16-byte seed and encode it using SSKR as 3 shares, 2 of which are required for recovery
62 |
63 | ```
64 | $ seedtool --out sskr --group 2-of-3
65 | tuna acid epic gyro many meow able acid able mild fern pool door purr calm trip cyan flew zest cats tuna omit figs bias acid aunt keys play frog
66 | tuna acid epic gyro many meow able acid acid keep undo peck poem kiwi jazz cola luck hope rock into film jolt lava flux rust gala sets ruin toil
67 | tuna acid epic gyro many meow able acid also girl void oval fish exam veto gala inky keys jump visa barn cusp high miss monk jazz numb dice foxy
68 | ```
69 |
70 | ### Recover a SSKR-encoded seed using 2 of the 3 shares
71 |
72 | ```
73 | $ seedtool --in sskr
74 | tuna acid epic gyro many meow able acid able mild fern pool door purr calm trip cyan flew zest cats tuna omit figs bias acid aunt keys play frog
75 | tuna acid epic gyro many meow able acid also girl void oval fish exam veto gala inky keys jump visa barn cusp high miss monk jazz numb dice foxy
76 | ^D
77 | 9d347f841a4e2ce6bc886e1aee74d824
78 | ```
79 |
80 | ## UR
81 |
82 | ### Generate a seed, encode it as UR, transform it to upper case, display it on the console, and encode it to a QR Code in the file "seedqrcode.png"
83 |
84 | ```
85 | $ seedtool --ur | tr [:lower:] [:upper:] | tee /dev/tty | qrencode -o seedqrcode.png -l L
86 | UR:SEED/OEADGDJOCNNEESSPDECECMVLFMLUOSBTDWQZFEAOTPIECFFDJZPYTAIEKK
87 | ```
88 |
89 | 
90 |
91 | ### Generate a 64-byte seed using a deterministic random number generator and encode it as a multi-part UR with a maximum fragment size of 20 bytes
92 |
93 | ```
94 | $ seedtool --deterministic=TEST --count 64 --ur=20
95 | ur:seed/1-4/lpadaacsfycyutrpgrfggyoyadhdfznteelblrcygldwvarflojtcywyhtmtdpeh
96 | ur:seed/2-4/lpaoaacsfycyutrpgrfggyjytpdkfwprylienshnjnpluypmamtkmybswddnkolg
97 | ur:seed/3-4/lpaxaacsfycyutrpgrfggyjkspvseesawmrltdlnlgkplfbkqzzoglfejtgylpfw
98 | ur:seed/4-4/lpaaaacsfycyutrpgrfggyoyaegsnedtrowsdpgtimmwzspfqdjkhshyqzwfssln
99 | ```
100 |
101 | ### Same as above, but generate 5 additional parts using fountain codes
102 |
103 | ```
104 | $ seedtool --deterministic=TEST --count 64 --ur=20 --parts 5
105 | ur:seed/1-4/lpadaacsfycyutrpgrfggyoyadhdfznteelblrcygldwvarflojtcywyhtmtdpeh
106 | ur:seed/2-4/lpaoaacsfycyutrpgrfggyjytpdkfwprylienshnjnpluypmamtkmybswddnkolg
107 | ur:seed/3-4/lpaxaacsfycyutrpgrfggyjkspvseesawmrltdlnlgkplfbkqzzoglfejtgylpfw
108 | ur:seed/4-4/lpaaaacsfycyutrpgrfggyoyaegsnedtrowsdpgtimmwzspfqdjkhshyqzwfssln
109 | ur:seed/5-4/lpahaacsfycyutrpgrfggyoyaegsnedtrowsdpgtimmwzspfqdjkhshytnlburst
110 | ur:seed/6-4/lpamaacsfycyutrpgrfggyoyadhdfznteelblrcygldwvarflojtcywylofxjerl
111 | ur:seed/7-4/lpataacsfycyutrpgrfggytdsopfjyheursphfnssrhkierpfnmdghpywnylisbt
112 | ur:seed/8-4/lpayaacsfycyutrpgrfggyjytpdkfwprylienshnjnpluypmamtkmybsykpamtlp
113 | ur:seed/9-4/lpasaacsfycyutrpgrfggyjytpdkfwprylienshnjnpluypmamtkmybsndfslgss
114 | ```
115 |
116 | ### Recover the seed from UR using a subset of the generated parts
117 |
118 | ```
119 | $ seedtool --in ur
120 | ur:seed/1-4/lpadaacsfycyutrpgrfggyoyadhdfznteelblrcygldwvarflojtcywyhtmtdpeh
121 | ur:seed/3-4/lpaxaacsfycyutrpgrfggyjkspvseesawmrltdlnlgkplfbkqzzoglfejtgylpfw
122 | ur:seed/5-4/lpahaacsfycyutrpgrfggyoyaegsnedtrowsdpgtimmwzspfqdjkhshytnlburst
123 | ur:seed/7-4/lpataacsfycyutrpgrfggytdsopfjyheursphfnssrhkierpfnmdghpywnylisbt
124 | ur:seed/9-4/lpasaacsfycyutrpgrfggyjytpdkfwprylienshnjnpluypmamtkmybsndfslgss
125 | ^D
126 | 9d347f841a4e2ce6bc886e1aee74d82442b2f7649c606daedbad06cf8f0f73c8e834c2ebb7d2868d75820ab4fb4e45a1004c9f29b8ef2d4d6a94fab0b373615e
127 | ```
128 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Unless otherwise noted (either in /README.md or in the file's header comments) the contents of this repository are released under the following license:
2 |
3 | BSD-2-Clause Plus Patent License
4 |
5 | SPDX-License-Identifier: [BSD-2-Clause-Patent](https://spdx.org/licenses/BSD-2-Clause-Patent.html)
6 |
7 | Copyright © 2019 Blockchain Commons, LLC
8 |
9 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
10 |
11 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
13 | Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by:
14 |
15 | (a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of contributors, in source or binary form) alone; or
16 | (b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution.
17 | Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this license, whether expressly, by implication, estoppel or otherwise.
18 |
19 | DISCLAIMER
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 |
--------------------------------------------------------------------------------
/Makefile.in:
--------------------------------------------------------------------------------
1 | # @configure_input@
2 |
3 | #
4 | # Makefile.in
5 | #
6 | # Copyright © 2020 by Blockchain Commons, LLC
7 | # Licensed under the "BSD-2-Clause Plus Patent License"
8 | #
9 |
10 | UNAME := $(shell uname)
11 | ifeq ($(UNAME), Linux)
12 | SHELL := /bin/bash
13 | else ifeq ($(findstring MINGW64, $(UNAME)), MINGW64)
14 | # on windows building with msys2/mingw64
15 | SHELL := /bin/bash
16 | endif
17 |
18 | # Package-specific substitution variables
19 | package = @PACKAGE_NAME@
20 | version = @PACKAGE_VERSION@
21 |
22 | # Prefix-specific substitution variables
23 | prefix = @prefix@
24 | exec_prefix = @exec_prefix@
25 | bindir = @bindir@
26 |
27 | # VPATH-specific substitution variables
28 | srcdir = @srcdir@
29 | VPATH = @srcdir@
30 |
31 | # Terminal colors
32 | RED=`tput setaf 1`
33 | GREEN=`tput setaf 2`
34 | RESET=`tput sgr0`
35 |
36 | .PHONY: all clean seedtool check lint
37 | all clean seedtool check lint:
38 | source set_build_paths.sh && cd src && $(MAKE) $@
39 |
40 | .PHONY: install uninstall
41 | install uninstall:
42 | source set_build_paths.sh && cd src && $(MAKE) $@
43 |
44 | config.status: configure
45 | ./config.status --recheck
46 |
47 | .PHONY: distclean
48 | distclean:
49 | cd src && $(MAKE) $@
50 | rm -f Makefile
51 | rm -rf autom4te.cache
52 | rm -f autoscan.log
53 | rm -f configure.scan configure.status config.log config.status config.h
54 | for d in deps/*; do \
55 | if [[ -d "$d" ]]; then \
56 | pushd $d; \
57 | make clean; \
58 | popd; \
59 | fi; \
60 | done
61 | rm -rf sysroot
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌱 Blockchain Commons seedtool-cli
2 |
3 | 
4 | 
5 | 
6 |
7 | ### _by [Wolf McNally](https://www.github.com/wolfmcnally) and [Christopher Allen](https://www.github.com/ChristopherA)_
8 |
9 | *
***part of the [crypto commons](https://github.com/BlockchainCommons/crypto-commons/blob/master/README.md) technology family***
10 | *
***part of the [gordian](https://github.com/BlockchainCommons/gordian/blob/master/README.md) technology family***
11 |
12 |
13 |
14 |
15 |
16 | ## Deprecation of C++ SeedTool
17 |
18 | This repo contains the original SeedTool written in C++, and is now deprecated. The [new SeedTool is written in Rust](https://github.com/BlockchainCommons/seedtool-cli-rust) and is a complete rewrite. The new SeedTool's inputs and outputs are compatible with the old SeedTool, and most of the same command line options are supported. The new SeedTool is more flexible and extensible, and is designed to support additional functionality.
19 |
20 | ## Introduction
21 |
22 | `seedtool` is a command-line tool for creating and transforming cryptographic seeds of the sort commonly used by blockchain applications.
23 |
24 | It exercises the various cryptographic C libraries created by Blockchain Commons, as described in the Dependencies section.
25 |
26 | ## Status - Feature-Complete Beta
27 |
28 | Seedtool is now considered feature-complete and is entering beta-level testing.
29 |
30 | ## Dependencies
31 |
32 | Seedtool exercises the following Blockchain Commons libraries:
33 |
34 | * [`bc-crypto-base`](https://github.com/blockchaincommons/bc-crypto-base)
35 | * [`bc-shamir`](https://github.com/blockchaincommons/bc-shamir)
36 | * [`bc-sskr`](https://github.com/blockchaincommons/bc-sskr)
37 | * [`bc-bip39`](https://github.com/blockchaincommons/bc-bip39)
38 | * [`bc-ur`](https://github.com/blockchaincommons/bc-ur)
39 |
40 | It also requires the following additional programs:
41 |
42 | * [`GNU argp`](https://www.gnu.org/software/libc/manual/html_node/Argp.html)
43 | * [`CBOR Lite`](https://bitbucket.org/isode/cbor-lite)
44 |
45 | ### Tool Dependencies
46 |
47 | To build `seedtool` you'll need to use the following tools:
48 |
49 | - autotools - Gnu Build System from Free Software Foundation ([intro](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html)).
50 |
51 | ## Recommended Installation instructions
52 |
53 | The dependencies will be automatically installed as submodules when you run the build script. This is the recommended way to install.
54 |
55 | ### Build with Docker
56 |
57 | [Install docker](https://docs.docker.com/get-docker/) and run:
58 |
59 | ```bash
60 | # Build the image
61 | $ docker build -t seedtool-cli .
62 | # Run the container
63 | $ docker run --rm -it seedtool-cli --help
64 | ```
65 |
66 | ### Build on MacOS
67 |
68 | ```bash
69 | $ brew install autoconf automake libtool
70 | ```
71 |
72 | You must then download or clone this repo. Afterward, cd into the repo directory and:
73 |
74 | ```bash
75 | $ ./build.sh
76 | $ sudo make install
77 | ```
78 |
79 | ### Build on Linux
80 |
81 | Make sure you have `llvm`/`clang`, `libc++` and `libc++abi` installed, all with
82 | a minimum recommended version 10.
83 |
84 | #### Build on Ubuntu and Debian
85 |
86 | ```bash
87 | $ sudo apt install build-essential
88 |
89 | $ wget https://apt.llvm.org/llvm.sh
90 | $ chmod +x llvm.sh
91 | $ sudo apt install lsb-release wget software-properties-common
92 | $ sudo ./llvm.sh 10 # version 10
93 |
94 | $ sudo apt-get install libc++-10-dev libc++abi-10-dev
95 | ```
96 |
97 | ```bash
98 | $ sudo apt-get install git
99 | $ git clone https://github.com/BlockchainCommons/seedtool-cli.git
100 | $ cd seedtool-cli/
101 | $ export CC="clang-10" && export CXX="clang++-10" && ./build.sh
102 | $ sudo make install
103 | ```
104 |
105 | ### Build on Windows
106 |
107 | See [instructions here](Docs/Install-Windows.md).
108 |
109 | ## Alternative Installation Instructions
110 |
111 | The following sequence does *not* install the dependencies from submodules; instead they must be installed in the usual places on the build system, otherwise the `./configure` step below will fail.
112 |
113 | ```bash
114 | $ ./configure
115 | $ make
116 | $ sudo make install
117 | ```
118 | *Note:* On Linux the first step is `./configure CC=clang-10 CXX=clang++-10`
119 |
120 | ## Incremental Build Instructions
121 |
122 | If you wish to make changes to the source code and rebuild:
123 |
124 | ```bash
125 | # Make source changes
126 | $ source set_build_paths.sh # sets shell variables used by make
127 | $ make clean # If you want a clean build
128 | $ make
129 | ```
130 |
131 | ## Usage Instructions
132 |
133 | See [usage examples](Docs/Usage.md) for examples of using seedtool.
134 |
135 | ## Full Documentation
136 |
137 | See [`MANUAL.md`](Docs/MANUAL.md) for details, many more examples, and version history.
138 |
139 | ## Notes for Maintainers
140 |
141 | Before accepting a PR that can affect build or unit tests, make sure the following sequence of commands succeeds:
142 |
143 | ```bash
144 | $ ./build.sh
145 | $ make lint
146 | $ make check
147 | $ make distclean
148 | ```
149 |
150 | `make lint` uses [Cppcheck](https://en.wikipedia.org/wiki/Cppcheck) to perform static analysis on the code. All PRs should pass with no warnings.
151 |
152 | ## Related Projects
153 |
154 | * [LetheKit](https://github.com/BlockchainCommons/bc-lethekit) is a parallel project that uses many of the same libraries, but in hardware.
155 | * [URKit](https://github.com/BlockchainCommons/URKit) is another example of our [bc-ur](https://github.com/BlockchainCommons/bc-ur) universal-reference library.
156 |
157 | ## Origin, Authors, Copyright & Licenses
158 |
159 | Unless otherwise noted (either in this [/README.md](./README.md) or in the file's header comments) the contents of this repository are Copyright © 2020 by Blockchain Commons, LLC, and are [licensed](./LICENSE) under the [spdx:BSD-2-Clause Plus Patent License](https://spdx.org/licenses/BSD-2-Clause-Patent.html).
160 |
161 | In most cases, the authors, copyright, and license for each file reside in header comments in the source code. When it does not we have attempted to attribute it accurately in the table below.
162 |
163 | This table below also establishes provenance (repository of origin, permalink, and commit id) for files included from repositories that are outside of this repository. Contributors to these files are listed in the commit history for each repository, first with changes found in the commit history of this repo, then in changes in the commit history of their repo of their origin.
164 |
165 | | File | From | Commit | Authors & Copyright (c) | License |
166 | | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------ | ----------------------------------------------------------- |
167 | | hkdf.c | [rustyrussell/ccan](https://github.com/rustyrussell/ccan/blob/master/ccan/crypto/hkdf_sha256/hkdf_sha256.c) | [d07f742](https://github.com/rustyrussell/ccan/commit/d07f742c5925b97ed558eb07aae285616f5df823) | 2016 [Rusty Russell](https://github.com/rustyrussell)
2020 Wolf McNally | [MIT](https://github.com/rustyrussell/ccan/blob/master/ccan/crypto/hkdf_sha256/LICENSE)
168 | | hkdf.h | [rustyrussell/ccan](https://github.com/rustyrussell/ccan/blob/master/ccan/crypto/hkdf_sha256/hkdf_sha256.h) | [d07f742](https://github.com/rustyrussell/ccan/commit/d07f742c5925b97ed558eb07aae285616f5df823) | 2016 [Rusty Russell](https://github.com/rustyrussell) | [MIT](https://github.com/rustyrussell/ccan/blob/master/ccan/crypto/hkdf_sha256/LICENSE)
169 | | randombytes.c | [dsprenkels/randombytes](https://github.com/dsprenkels/randombytes/blob/master/randombytes.c) | [6db39aa](https://github.com/dsprenkels/randombytes/commit/6db39aaae6bb9ab97beca00d81bcfe935c56c88d) | 2017-2019 [Daan Sprenkels](https://github.com/dsprenkels/) | [MIT](https://github.com/dsprenkels/randombytes/commit/73ae9b4fce2e62babdd6a480b53ad449dd745ed9) |
170 | | randombytes.h | [dsprenkels/randombytes](https://github.com/dsprenkels/randombytes/blob/master/randombytes.h) | [19fd002](https://github.com/dsprenkels/randombytes/commit/19fd002d9b7b001b333a671186a91231b60d821b) | 2017-2019 [Daan Sprenkels](https://github.com/dsprenkels/) | [MIT](https://github.com/dsprenkels/randombytes/commit/73ae9b4fce2e62babdd6a480b53ad449dd745ed9) |
171 |
172 | ### Tool Dependencies
173 |
174 | To build `seedtool` you'll need to use the following tools:
175 |
176 | - autotools - Gnu Build System from Free Software Foundation ([intro](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html)).
177 |
178 | ## Financial Support
179 |
180 | Seedtool is a project of [Blockchain Commons](https://www.blockchaincommons.com/). We are proudly a "not-for-profit" social benefit corporation committed to open source & open development. Our work is funded entirely by donations and collaborative partnerships with people like you. Every contribution will be spent on building open tools, technologies, and techniques that sustain and advance blockchain and internet security infrastructure and promote an open web.
181 |
182 | To financially support further development of Seedtool and other projects, please consider becoming a Patron of Blockchain Commons through ongoing monthly patronage as a [GitHub Sponsor](https://github.com/sponsors/BlockchainCommons). You can also support Blockchain Commons with bitcoins at our [BTCPay Server](https://btcpay.blockchaincommons.com/).
183 |
184 | ## Contributing
185 |
186 | We encourage public contributions through issues and pull-requests! Please review [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our development process. All contributions to this repository require a GPG signed [Contributor License Agreement](./CLA.md).
187 |
188 | ### Discussions
189 |
190 | The best place to talk about Blockchain Commons and its projects is in our GitHub Discussions areas.
191 |
192 | [**Gordian User Community**](https://github.com/BlockchainCommons/Gordian/discussions). For users of the Gordian reference apps, including [Gordian Coordinator](https://github.com/BlockchainCommons/iOS-GordianCoordinator), [Gordian Seed Tool](https://github.com/BlockchainCommons/GordianSeedTool-iOS), [Gordian Server](https://github.com/BlockchainCommons/GordianServer-macOS), [Gordian Wallet](https://github.com/BlockchainCommons/GordianWallet-iOS), and [SpotBit](https://github.com/BlockchainCommons/spotbit) as well as our whole series of [CLI apps](https://github.com/BlockchainCommons/Gordian/blob/master/Docs/Overview-Apps.md#cli-apps). This is a place to talk about bug reports and feature requests as well as to explore how our reference apps embody the [Gordian Principles](https://github.com/BlockchainCommons/Gordian#gordian-principles).
193 |
194 | [**Blockchain Commons Discussions**](https://github.com/BlockchainCommons/Community/discussions). For developers, interns, and patrons of Blockchain Commons, please use the discussions area of the [Community repo](https://github.com/BlockchainCommons/Community) to talk about general Blockchain Commons issues, the intern program, or topics other than those covered by the [Gordian Developer Community](https://github.com/BlockchainCommons/Gordian-Developer-Community/discussions) or the
195 | [Gordian User Community](https://github.com/BlockchainCommons/Gordian/discussions).
196 |
197 | ### Other Questions & Problems
198 |
199 | As an open-source, open-development community, Blockchain Commons does not have the resources to provide direct support of our projects. Please consider the discussions area as a locale where you might get answers to questions. Alternatively, please use this repository's [issues](./issues) feature. Unfortunately, we can not make any promises on response time.
200 |
201 | If your company requires support to use our projects, please feel free to contact us directly about options. We may be able to offer you a contract for support from one of our contributors, or we might be able to point you to another entity who can offer the contractual support that you need.
202 |
203 | ### Credits
204 |
205 | The following people directly contributed to this repository. You can add your name here by getting involved — the first step is to learn how to contribute from our [CONTRIBUTING.md](./CONTRIBUTING.md) documentation.
206 |
207 | | Name | Role | Github | Email | GPG Fingerprint |
208 | | ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- |
209 | | Christopher Allen | Principal Architect | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED |
210 | | Wolf McNally | Project Lead | [@WolfMcNally](https://github.com/wolfmcnally) | \ | 9436 52EE 3844 1760 C3DC 3536 4B6C 2FCF 8947 80AE |
211 |
212 | ## Responsible Disclosure
213 |
214 | We want to keep all our software safe for everyone. If you have discovered a security vulnerability, we appreciate your help in disclosing it to us in a responsible manner. We are unfortunately not able to offer bug bounties at this time.
215 |
216 | We do ask that you offer us good faith and use best efforts not to leak information or harm any user, their data, or our developer community. Please give us a reasonable amount of time to fix the issue before you publish it. Do not defraud our users or us in the process of discovery. We promise not to bring legal action against researchers who point out a problem provided they do their best to follow the these guidelines.
217 |
218 | ## Reporting a Vulnerability
219 |
220 | Please report suspected security vulnerabilities in private via email to ChristopherA@BlockchainCommons.com (do not use this email for support). Please do NOT create publicly viewable issues for suspected security vulnerabilities.
221 |
222 | The following keys may be used to communicate sensitive information to developers:
223 |
224 | | Name | Fingerprint |
225 | | ----------------- | -------------------------------------------------- |
226 | | Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED |
227 |
228 | You can import a key by running the following command with that individual’s fingerprint: `gpg --recv-keys ""` Ensure that you put quotes around fingerprints that contain spaces.
229 |
--------------------------------------------------------------------------------
/bootstrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | autoreconf --install
4 | automake --add-missing --copy >/dev/null 2>&1
5 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | git submodule init
4 | git submodule update
5 |
6 | source set_build_paths.sh
7 |
8 | # Terminal colors
9 | RED=`tput setaf 1`
10 | GREEN=`tput setaf 2`
11 | BLUE=`tput setaf 4`
12 | RESET=`tput sgr0`
13 |
14 | echo "${BLUE}== bc-crypto-base ==${RESET}"
15 |
16 | pushd deps/bc-crypto-base
17 | ./configure --prefix ${SYSROOT}
18 | make check
19 | make install
20 | popd
21 |
22 | echo "${BLUE}== bc-shamir ==${RESET}"
23 |
24 | pushd deps/bc-shamir
25 | ./configure --prefix ${SYSROOT}
26 | make check
27 | make install
28 | popd
29 |
30 | echo "${BLUE}== bc-sskr ==${RESET}"
31 |
32 | pushd deps/bc-sskr
33 | ./configure --prefix ${SYSROOT}
34 | make check
35 | make install
36 | popd
37 |
38 | echo "${BLUE}== bc-bip39 ==${RESET}"
39 |
40 | pushd deps/bc-bip39
41 | ./configure --prefix ${SYSROOT}
42 | make check
43 | make install
44 | popd
45 |
46 | echo "${BLUE}== bc-ur ==${RESET}"
47 |
48 | pushd deps/bc-ur
49 | ./configure --prefix ${SYSROOT}
50 | make check
51 | make install
52 | popd
53 |
54 | echo "${BLUE}== argp-standalone ==${RESET}"
55 |
56 | pushd deps/argp-standalone/argp-standalone
57 | set +e
58 | patch -N <../patch-argp-fmtstream.h
59 | set -e
60 | ./configure --prefix ${SYSROOT}
61 | make install
62 | cp libargp.a ${SYSROOT}/lib/
63 | cp argp.h ${SYSROOT}/include/
64 | popd
65 |
66 | echo "${BLUE}== seedtool ==${RESET}"
67 |
68 | ./configure
69 | make clean
70 | make check
71 | echo "${GREEN}*** Seedtool built.${RESET}"
72 | echo "${GREEN}Next step: sudo make install${RESET}"
73 |
--------------------------------------------------------------------------------
/build/build-tailsOS.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:latest as base
2 | ARG DEBIAN_FRONTEND=noninteractive
3 | WORKDIR /app
4 | COPY . source
5 | COPY .git source/.git
6 |
7 | RUN apt update -y
8 | RUN apt install -y \
9 | build-essential autogen libtool shtool \
10 | clang llvm lld libstdc++6 libc++-dev libc++1 libc++abi1 \
11 | git-buildpackage \
12 | git \
13 | coreutils binutils \
14 | bash
15 | WORKDIR source
16 | FROM base
17 | ARG DEBIAN_FRONTEND=noninteractive
18 | SHELL ["/bin/bash", "-c"]
19 | RUN chmod -x debian/clean
20 | RUN ln -svf /usr/bin/lld /usr/bin/ld
21 | RUN git submodule update
22 | RUN cat debian/patches/series | xargs -I{} patch -f --strip=1 -i "debian/patches/{}" || true
23 | RUN patch -f --strip=1 -i debian/patches/bc-ur-build-tails.diff || true
24 |
25 | # FIXME(nochiel) It would be nice if running this line compiled the packaged the files we care about.
26 | RUN gbp buildpackage --git-upstream-tree=master --git-debian-branch=debian/latest --git-ignore-new --git-force-create --git-submodules
--------------------------------------------------------------------------------
/build/packaging.md:
--------------------------------------------------------------------------------
1 | # Packaging for Debian
2 | - Run `git checkout debian/latest`
3 |
4 | Apply the patches listed in `debian/patches/series`. They should apply cleanly before the repository can be compiled.
5 |
6 | ```sh
7 | cat debian/patches/series | xargs -I{} patch -f --strip=1 -i "debian/patches/{}"
8 | ```
9 |
10 | To build a Debian package run the following command in a checked-out `debian/latest` branch: `gbp buildpackage --git-upstream-tree=master --git-debian-branch=debian/latest --git-ignore-new --git-force-create --git-submodules`
11 |
12 | The relevant build artefacts can be found using `ls ../`.
13 |
14 | # Packaging for TailsOS
15 | - The `tails/latest` branch is always based on the `debian/latest` branch.
16 | - Run `git checkout tails/latest`
17 | - Run `docker build --tag=seedtool-tails --file build-tailsOS.Dockerfile .`
18 | - `/app/source` will contain a copy of the Seedtool source code.
19 | - `app` wiil contain all the `.deb` and source code archive files for distribution.
20 | - Run `docker container run --name seedtool-tails -it build-seedtool-tails bash`
21 | - Run `docker container cp seedtool-tails:/app seedtool-tails-build`
22 | - The directory `seedtool-tails-build/` will now container the output artefacts needed for Tails.
23 |
24 |
25 | ## Possible errors and how to deal with them
26 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Process this file with autoconf to produce a configure script.
3 |
4 | AC_PREREQ([2.69])
5 | AC_INIT([seedtool-cli], [0.11.0])
6 | AC_CONFIG_SRCDIR([src/seedtool.cpp])
7 | AC_CONFIG_HEADERS([src/config.h])
8 | AC_CONFIG_AUX_DIR([build-aux])
9 |
10 | # Checks for programs.
11 | AC_PROG_CXX
12 | AC_PROG_CC
13 | AC_PROG_INSTALL
14 | AC_PROG_MAKE_SET
15 |
16 | # on windows/msys2/mingw64:
17 | AS_CASE([$(uname -s)],
18 | [*MINGW*], [LIBS=-lws2_32],
19 | [LIBS=]
20 | )
21 |
22 | # Checks for libraries.
23 | AC_CHECK_LIB([bc-crypto-base], [sha256_Raw], [], [
24 | echo "### Error! libbc-crypto-base must be installed first."
25 | exit -1
26 | ])
27 | AC_CHECK_LIB([bc-shamir], [split_secret], [], [
28 | echo "### Error! libbc-shamir must be installed first."
29 | exit -1
30 | ])
31 | AC_CHECK_LIB([bc-sskr], [sskr_generate], [], [
32 | echo "### Error! libbc-sskr must be installed first."
33 | exit -1
34 | ])
35 | AC_CHECK_LIB([bc-bip39], [bip39_mnemonic_from_word], [], [
36 | echo "### Error! libbc-bip39 must be installed first."
37 | exit -1
38 | ])
39 | AC_CHECK_LIB([bc-ur], [ur_crc32n], [], [
40 | echo "### Error! libbc-ur must be installed first."
41 | exit -1
42 | ])
43 | AC_CHECK_LIB([argp], [argp_parse], [], [
44 | echo "### Error! argp must be installed first. Try 'brew install argp-standalone'."
45 | exit -1
46 | ])
47 |
48 | # Checks for header files.
49 | AC_CHECK_HEADERS([fcntl.h memory.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h unistd.h stddef.h])
50 |
51 | # Checks for typedefs, structures, and compiler characteristics.
52 | AC_CHECK_HEADER_STDBOOL
53 | AC_C_INLINE
54 | AC_TYPE_SIZE_T
55 | AC_TYPE_SSIZE_T
56 | AC_TYPE_UINT16_T
57 | AC_TYPE_UINT32_T
58 | AC_TYPE_UINT64_T
59 | AC_TYPE_UINT8_T
60 | AC_TYPE_INT16_T
61 | AC_TYPE_INT32_T
62 |
63 | # Checks for library functions.
64 | AC_FUNC_MALLOC
65 | AC_CHECK_FUNCS([memset strerror])
66 |
67 | AC_CONFIG_FILES([Makefile
68 | src/Makefile])
69 | AC_OUTPUT
70 |
--------------------------------------------------------------------------------
/debian/README.Debian:
--------------------------------------------------------------------------------
1 | seedtool-cli for Debian
2 | ----------------------
3 |
4 |
5 |
6 | -- unknown Mon, 06 Feb 2023 14:50:21 +0300
7 |
--------------------------------------------------------------------------------
/debian/README.source:
--------------------------------------------------------------------------------
1 | seedtool-cli for Debian
2 | ----------------------
3 |
4 |
6 |
7 |
8 |
9 | -- unknown Mon, 06 Feb 2023 14:50:21 +0300
10 |
11 |
--------------------------------------------------------------------------------
/debian/changelog:
--------------------------------------------------------------------------------
1 | seedtool-cli (0.9.1-1) UNRELEASED; urgency=medium
2 |
3 | * Initial release for Debian packaging.
4 |
5 | -- Nick Ochiel Mon, 06 Feb 2023 14:50:21 +0300
6 |
--------------------------------------------------------------------------------
/debian/clean:
--------------------------------------------------------------------------------
1 | deps/argp-standalone/argp-standalone/Makefile
2 | deps/argp-standalone/argp-standalone/aclocal.m4
3 | deps/argp-standalone/argp-standalone/compile
4 | deps/argp-standalone/argp-standalone/config.h
5 | deps/argp-standalone/argp-standalone/config.log
6 | deps/argp-standalone/argp-standalone/config.status
7 | deps/argp-standalone/argp-standalone/configure
8 | deps/argp-standalone/argp-standalone/stamp-h1
9 | deps/argp-standalone/argp-standalone/testsuite/Makefile
10 | # deps/argp-standalone/argp-standalone/testsuite/Makefile.in
11 | deps/bc-bip39/Makefile
12 | deps/bc-bip39/config.guess
13 | deps/bc-bip39/config.h
14 | deps/bc-bip39/config.log
15 | deps/bc-bip39/config.status
16 | deps/bc-bip39/config.sub
17 | deps/bc-bip39/configure
18 | deps/bc-bip39/src/Makefile
19 | deps/bc-bip39/test/Makefile
20 | deps/bc-crypto-base/Makefile
21 | deps/bc-crypto-base/config.guess
22 | deps/bc-crypto-base/config.h
23 | deps/bc-crypto-base/config.log
24 | deps/bc-crypto-base/config.status
25 | deps/bc-crypto-base/config.sub
26 | deps/bc-crypto-base/configure
27 | deps/bc-crypto-base/src/Makefile
28 | deps/bc-crypto-base/test/Makefile
29 | deps/bc-shamir/Makefile
30 | deps/bc-shamir/config.guess
31 | deps/bc-shamir/config.h
32 | deps/bc-shamir/config.log
33 | deps/bc-shamir/config.status
34 | deps/bc-shamir/config.sub
35 | deps/bc-shamir/configure
36 | deps/bc-shamir/src/Makefile
37 | deps/bc-shamir/test/Makefile
38 | deps/bc-sskr/Makefile
39 | deps/bc-sskr/config.guess
40 | deps/bc-sskr/config.h
41 | deps/bc-sskr/config.log
42 | deps/bc-sskr/config.status
43 | deps/bc-sskr/config.sub
44 | deps/bc-sskr/configure
45 | deps/bc-sskr/src/Makefile
46 | deps/bc-sskr/test/Makefile
47 | deps/bc-ur/Makefile
48 | deps/bc-ur/config.guess
49 | deps/bc-ur/config.h
50 | deps/bc-ur/config.log
51 | deps/bc-ur/config.status
52 | deps/bc-ur/config.sub
53 | deps/bc-ur/configure
54 | deps/bc-ur/src/Makefile
55 | deps/bc-ur/test/Makefile
56 | config.log
57 | config.status
58 | src/Makefile
59 | src/config.h
60 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: seedtool-cli
2 | Section: unknown
3 | Priority: optional
4 | Maintainer: Wolf McNally
5 | Rules-Requires-Root: no
6 | Build-Depends:
7 | debhelper-compat (= 13),
8 | autotools-dev,
9 | Standards-Version: 4.6.1
10 | Homepage: https://github.com/BlockchainCommons/seedtool-cli
11 | #Vcs-Browser: https://salsa.debian.org/debian/seedtool-cli
12 | Vcs-Git: https://github.com/BlockchainCommons/seedtool-cli.git
13 |
14 | Package: seedtool-cli
15 | Architecture: any
16 | Depends:
17 | ${shlibs:Depends},
18 | ${misc:Depends},
19 | Description: A command-line tool for creating and transforming cryptographic seeds of the sort commonly used by blockchain applications.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/debian/copyright:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Source:
3 | Upstream-Name: seedtool-cli
4 | Upstream-Contact:
5 |
6 | Files:
7 | *
8 | Copyright:
9 |
10 |
11 | License:
12 |
13 |
14 | .
15 |
16 |
17 | # If you want to use GPL v2 or later for the /debian/* files use
18 | # the following clauses, or change it to suit. Delete these two lines
19 | Files:
20 | debian/*
21 | Copyright:
22 | 2023 unknown
23 | License: GPL-2+
24 | This package is free software; you can redistribute it and/or modify
25 | it under the terms of the GNU General Public License as published by
26 | the Free Software Foundation; either version 2 of the License, or
27 | (at your option) any later version.
28 | .
29 | This package is distributed in the hope that it will be useful,
30 | but WITHOUT ANY WARRANTY; without even the implied warranty of
31 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 | GNU General Public License for more details.
33 | .
34 | You should have received a copy of the GNU General Public License
35 | along with this program. If not, see
36 | Comment:
37 | On Debian systems, the complete text of the GNU General
38 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
39 |
40 | # Please also look if there are files or directories which have a
41 | # different copyright/license attached and list them here.
42 | # Please avoid picking licenses with terms that are more restrictive than the
43 | # packaged work, as it may make Debian's contributions unacceptable upstream.
44 | #
45 | # If you need, there are some extra license texts available in two places:
46 | # /usr/share/debhelper/dh_make/licenses/
47 | # /usr/share/common-licenses/
48 |
--------------------------------------------------------------------------------
/debian/manpage.1.ex:
--------------------------------------------------------------------------------
1 | .\" Hey, EMACS: -*- nroff -*-
2 | .\" (C) Copyright 2023 unknown ,
3 | .\"
4 | .\" First parameter, NAME, should be all caps
5 | .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
6 | .\" other parameters are allowed: see man(7), man(1)
7 | .TH Seedtool-cli SECTION "February 6 2023"
8 | .\" Please adjust this date whenever revising the manpage.
9 | .\"
10 | .\" Some roff macros, for reference:
11 | .\" .nh disable hyphenation
12 | .\" .hy enable hyphenation
13 | .\" .ad l left justify
14 | .\" .ad b justify to both left and right margins
15 | .\" .nf disable filling
16 | .\" .fi enable filling
17 | .\" .br insert line break
18 | .\" .sp insert n+1 empty lines
19 | .\" for manpage-specific macros, see man(7)
20 | .SH NAME
21 | seedtool-cli \- program to do something
22 | .SH SYNOPSIS
23 | .B seedtool-cli
24 | .RI [ options ] " files" ...
25 | .br
26 | .B bar
27 | .RI [ options ] " files" ...
28 | .SH DESCRIPTION
29 | This manual page documents briefly the
30 | .B seedtool-cli
31 | and
32 | .B bar
33 | commands.
34 | .PP
35 | .\" TeX users may be more comfortable with the \fB\fP and
36 | .\" \fI\fP escape sequences to invode bold face and italics,
37 | .\" respectively.
38 | \fBseedtool-cli\fP is a program that...
39 | .SH OPTIONS
40 | These programs follow the usual GNU command line syntax, with long
41 | options starting with two dashes ('\-').
42 | A summary of options is included below.
43 | For a complete description, see the Info files.
44 | .TP
45 | .B \-h, \-\-help
46 | Show summary of options.
47 | .TP
48 | .B \-v, \-\-version
49 | Show version of program.
50 | .SH SEE ALSO
51 | .BR bar (1),
52 | .BR baz (1).
53 | .br
54 | The programs are documented fully by
55 | .IR "The Rise and Fall of a Fooish Bar" ,
56 | available via the Info system.
57 |
--------------------------------------------------------------------------------
/debian/manpage.md.ex:
--------------------------------------------------------------------------------
1 | % seedtool-cli(SECTION) | User Commands
2 | %
3 | % "February 6 2023"
4 |
5 | [comment]: # The lines above form a Pandoc metadata block. They must be
6 | [comment]: # the first ones in the file.
7 | [comment]: # See https://pandoc.org/MANUAL.html#metadata-blocks for details.
8 |
9 | [comment]: # pandoc -s -f markdown -t man package.md -o package.1
10 | [comment]: #
11 | [comment]: # A manual page package.1 will be generated. You may view the
12 | [comment]: # manual page with: nroff -man package.1 | less. A typical entry
13 | [comment]: # in a Makefile or Makefile.am is:
14 | [comment]: #
15 | [comment]: # package.1: package.md
16 | [comment]: # pandoc --standalone --from=markdown --to=man $< --output=$@
17 | [comment]: #
18 | [comment]: # The pandoc binary is found in the pandoc package. Please remember
19 | [comment]: # that if you create the nroff version in one of the debian/rules
20 | [comment]: # file targets, such as build, you will need to include pandoc in
21 | [comment]: # your Build-Depends control field.
22 |
23 | [comment]: # Remove the lines starting with '[comment]:' in this file in order
24 | [comment]: # to avoid warning messages from pandoc.
25 |
26 | # NAME
27 |
28 | seedtool-cli - program to do something
29 |
30 | # SYNOPSIS
31 |
32 | **seedtool-cli** **-e** _this_ [**\-\-example=that**] [{**-e** | **\-\-example**} _this_]
33 | [{**-e** | **\-\-example**} {_this_ | _that_}]
34 |
35 | **seedtool-cli** [{**-h** | *\-\-help**} | {**-v** | **\-\-version**}]
36 |
37 | # DESCRIPTION
38 |
39 | This manual page documents briefly the **seedtool-cli** and **bar** commands.
40 |
41 | This manual page was written for the Debian distribution because the
42 | original program does not have a manual page. Instead, it has documentation
43 | in the GNU info(1) format; see below.
44 |
45 | **seedtool-cli** is a program that...
46 |
47 | # OPTIONS
48 |
49 | The program follows the usual GNU command line syntax, with long options
50 | starting with two dashes ('-'). A summary of options is included below. For
51 | a complete description, see the **info**(1) files.
52 |
53 | **-e** _this_, **\-\-example=**_that_
54 | : Does this and that.
55 |
56 | **-h**, **\-\-help**
57 | : Show summary of options.
58 |
59 | **-v**, **\-\-version**
60 | : Show version of program.
61 |
62 | # FILES
63 |
64 | /etc/foo.conf
65 | : The system-wide configuration file to control the behaviour of
66 | seedtool-cli. See **foo.conf**(5) for further details.
67 |
68 | ${HOME}/.foo.conf
69 | : The per-user configuration file to control the behaviour of
70 | seedtool-cli. See **foo.conf**(5) for further details.
71 |
72 | # ENVIRONMENT
73 |
74 | **FOO_CONF**
75 | : If used, the defined file is used as configuration file (see also
76 | the section called “FILES”).
77 |
78 | # DIAGNOSTICS
79 |
80 | The following diagnostics may be issued on stderr:
81 |
82 | Bad configuration file. Exiting.
83 | : The configuration file seems to contain a broken configuration
84 | line. Use the **\-\-verbose** option, to get more info.
85 |
86 | **seedtool-cli** provides some return codes, that can be used in scripts:
87 |
88 | Code Diagnostic
89 | 0 Program exited successfully.
90 | 1 The configuration file seems to be broken.
91 |
92 | # BUGS
93 |
94 | The program is currently limited to only work with the foobar library.
95 |
96 | The upstream BTS can be found at http://bugzilla.foo.tld.
97 |
98 | # SEE ALSO
99 |
100 | **bar**(1), **baz**(1), **foo.conf**(5)
101 |
102 | The programs are documented fully by The Rise and Fall of a Fooish Bar
103 | available via the **info**(1) system.
104 |
105 | # AUTHOR
106 |
107 | unknown
108 | : Wrote this manpage for the Debian system.
109 |
110 | # COPYRIGHT
111 |
112 | Copyright © 2007 unknown
113 |
114 | This manual page was written for the Debian system (and may be used by
115 | others).
116 |
117 | Permission is granted to copy, distribute and/or modify this document under
118 | the terms of the GNU General Public License, Version 2 or (at your option)
119 | any later version published by the Free Software Foundation.
120 |
121 | On Debian systems, the complete text of the GNU General Public License
122 | can be found in /usr/share/common-licenses/GPL.
123 |
124 | [comment]: # Local Variables:
125 | [comment]: # mode: markdown
126 | [comment]: # End:
127 |
--------------------------------------------------------------------------------
/debian/manpage.sgml.ex:
--------------------------------------------------------------------------------
1 | manpage.1'. You may view
5 | the manual page with: 'docbook-to-man manpage.sgml | nroff -man |
6 | less'. A typical entry in a Makefile or Makefile.am is:
7 |
8 | manpage.1: manpage.sgml
9 | docbook-to-man $< > $@
10 |
11 |
12 | The docbook-to-man binary is found in the docbook-to-man package.
13 | Please remember that if you create the nroff version in one of the
14 | debian/rules file targets (such as build), you will need to include
15 | docbook-to-man in your Build-Depends control field.
16 |
17 | -->
18 |
19 |
20 | FIRSTNAME">
21 | SURNAME">
22 |
23 | February 6 2023">
24 |
26 | SECTION">
27 | nik@unknown">
28 |
29 | Seedtool-cli">
30 |
31 |
32 | Debian">
33 | GNU">
34 | GPL">
35 | ]>
36 |
37 |
38 |
39 |
40 | &dhemail;
41 |
42 |
43 | &dhfirstname;
44 | &dhsurname;
45 |
46 |
47 | 2003
48 | &dhusername;
49 |
50 | &dhdate;
51 |
52 |
53 | &dhucpackage;
54 |
55 | &dhsection;
56 |
57 |
58 | &dhpackage;
59 |
60 | program to do something
61 |
62 |
63 |
64 | &dhpackage;
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | DESCRIPTION
73 |
74 | This manual page documents briefly the
75 | &dhpackage; and bar
76 | commands.
77 |
78 | This manual page was written for the &debian; distribution
79 | because the original program does not have a manual page.
80 | Instead, it has documentation in the &gnu;
81 | Info format; see below.
82 |
83 | &dhpackage; is a program that...
84 |
85 |
86 |
87 | OPTIONS
88 |
89 | These programs follow the usual &gnu; command line syntax,
90 | with long options starting with two dashes ('-'). A summary of
91 | options is included below. For a complete description, see the
92 | Info files.
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | Show summary of options.
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | Show version of program.
109 |
110 |
111 |
112 |
113 |
114 | SEE ALSO
115 |
116 | bar (1), baz (1).
117 |
118 | The programs are documented fully by The Rise and
119 | Fall of a Fooish Bar available via the
120 | Info system.
121 |
122 |
123 | AUTHOR
124 |
125 | This manual page was written by &dhusername; &dhemail; for
126 | the &debian; system (and may be used by others). Permission is
127 | granted to copy, distribute and/or modify this document under
128 | the terms of the &gnu; General Public License, Version 2 any
129 | later version published by the Free Software Foundation.
130 |
131 |
132 | On Debian systems, the complete text of the GNU General Public
133 | License can be found in /usr/share/common-licenses/GPL.
134 |
135 |
136 |
137 |
138 |
139 |
155 |
--------------------------------------------------------------------------------
/debian/manpage.xml.ex:
--------------------------------------------------------------------------------
1 |
2 | . will be generated. You may view the
15 | manual page with: nroff -man . | less'. A typical entry
16 | in a Makefile or Makefile.am is:
17 |
18 | DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/docbook-xsl/manpages/docbook.xsl
19 | XP = xsltproc -''-nonet -''-param man.charmap.use.subset "0"
20 |
21 | manpage.1: manpage.xml
22 | $(XP) $(DB2MAN) $<
23 |
24 | The xsltproc binary is found in the xsltproc package. The XSL files are in
25 | docbook-xsl. A description of the parameters you can use can be found in the
26 | docbook-xsl-doc-* packages. Please remember that if you create the nroff
27 | version in one of the debian/rules file targets (such as build), you will need
28 | to include xsltproc and docbook-xsl in your Build-Depends control field.
29 | Alternatively use the xmlto command/package. That will also automatically
30 | pull in xsltproc and docbook-xsl.
31 |
32 | Notes for using docbook2x: docbook2x-man does not automatically create the
33 | AUTHOR(S) and COPYRIGHT sections. In this case, please add them manually as
34 | ... .
35 |
36 | To disable the automatic creation of the AUTHOR(S) and COPYRIGHT sections
37 | read /usr/share/doc/docbook-xsl/doc/manpages/authors.html. This file can be
38 | found in the docbook-xsl-doc-html package.
39 |
40 | Validation can be done using: `xmllint -''-noout -''-valid manpage.xml`
41 |
42 | General documentation about man-pages and man-page-formatting:
43 | man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
44 |
45 | -->
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
56 |
57 |
59 |
60 |
61 |
62 | ]>
63 |
64 |
65 |
66 | &dhtitle;
67 | &dhpackage;
68 |
69 |
70 | &dhfirstname;
71 | &dhsurname;
72 | Wrote this manpage for the Debian system.
73 |
74 | &dhemail;
75 |
76 |
77 |
78 |
79 | 2007
80 | &dhusername;
81 |
82 |
83 | This manual page was written for the Debian system
84 | (and may be used by others).
85 | Permission is granted to copy, distribute and/or modify this
86 | document under the terms of the GNU General Public License,
87 | Version 2 or (at your option) any later version published by
88 | the Free Software Foundation.
89 | On Debian systems, the complete text of the GNU General Public
90 | License can be found in
91 | /usr/share/common-licenses/GPL.
92 |
93 |
94 |
95 | &dhucpackage;
96 | &dhsection;
97 |
98 |
99 | &dhpackage;
100 | program to do something
101 |
102 |
103 |
104 | &dhpackage;
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | this
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | this
122 | that
123 |
124 |
125 |
126 |
127 | &dhpackage;
128 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | DESCRIPTION
148 | This manual page documents briefly the
149 | &dhpackage; and bar
150 | commands.
151 | This manual page was written for the Debian distribution
152 | because the original program does not have a manual page.
153 | Instead, it has documentation in the GNU
154 | info
155 | 1
156 | format; see below.
157 | &dhpackage; is a program that...
158 |
159 |
160 | OPTIONS
161 | The program follows the usual GNU command line syntax,
162 | with long options starting with two dashes ('-'). A summary of
163 | options is included below. For a complete description, see the
164 |
165 | info
166 | 1
167 | files.
168 |
169 |
172 |
173 |
174 |
175 |
176 | Does this and that.
177 |
178 |
179 |
180 |
181 |
182 |
183 | Show summary of options.
184 |
185 |
186 |
187 |
188 |
189 |
190 | Show version of program.
191 |
192 |
193 |
194 |
195 |
196 | FILES
197 |
198 |
199 | /etc/foo.conf
200 |
201 | The system-wide configuration file to control the
202 | behaviour of &dhpackage;. See
203 |
204 | foo.conf
205 | 5
206 | for further details.
207 |
208 |
209 |
210 | ${HOME}/.foo.conf
211 |
212 | The per-user configuration file to control the
213 | behaviour of &dhpackage;. See
214 |
215 | foo.conf
216 | 5
217 | for further details.
218 |
219 |
220 |
221 |
222 |
223 | ENVIRONMENT
224 |
225 |
226 | FOO_CONF
227 |
228 | If used, the defined file is used as configuration
229 | file (see also ).
230 |
231 |
232 |
233 |
234 |
235 | DIAGNOSTICS
236 | The following diagnostics may be issued
237 | on stderr:
238 |
239 |
240 | Bad configuration file. Exiting.
241 |
242 | The configuration file seems to contain a broken configuration
243 | line. Use the option, to get more info.
244 |
245 |
246 |
247 |
248 | &dhpackage; provides some return codes, that can
249 | be used in scripts:
250 |
251 | Code
252 | Diagnostic
253 |
254 | 0
255 | Program exited successfully.
256 |
257 |
258 | 1
259 | The configuration file seems to be broken.
260 |
261 |
262 |
263 |
264 |
265 | BUGS
266 | The program is currently limited to only work
267 | with the foobar library.
268 | The upstreams BTS can be found
269 | at .
270 |
271 |
272 | SEE ALSO
273 |
274 |
275 | bar
276 | 1
277 | ,
278 | baz
279 | 1
280 | ,
281 | foo.conf
282 | 5
283 |
284 | The programs are documented fully by The Rise and
285 | Fall of a Fooish Bar available via the
286 | info
287 | 1
288 | system.
289 |
290 |
291 |
292 |
--------------------------------------------------------------------------------
/debian/patches/series:
--------------------------------------------------------------------------------
1 | fix-build.diff
2 | fix-build.0.diff
3 | Makefile.diff
4 |
--------------------------------------------------------------------------------
/debian/postinst.ex:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # postinst script for seedtool-cli.
3 | #
4 | # See: dh_installdeb(1).
5 |
6 | set -e
7 |
8 | # Summary of how this script can be called:
9 | # * 'configure'
10 | # * 'abort-upgrade'
11 | # * 'abort-remove' 'in-favour'
12 | #
13 | # * 'abort-remove'
14 | # * 'abort-deconfigure' 'in-favour'
15 | # 'removing'
16 | #
17 | # for details, see https://www.debian.org/doc/debian-policy/ or
18 | # the debian-policy package.
19 |
20 |
21 | case "$1" in
22 | configure)
23 | ;;
24 |
25 | abort-upgrade|abort-remove|abort-deconfigure)
26 | ;;
27 |
28 | *)
29 | echo "postinst called with unknown argument '$1'" >&2
30 | exit 1
31 | ;;
32 | esac
33 |
34 | # dh_installdeb will replace this with shell code automatically
35 | # generated by other debhelper scripts.
36 |
37 | #DEBHELPER#
38 |
39 | exit 0
40 |
--------------------------------------------------------------------------------
/debian/postrm.ex:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # postrm script for seedtool-cli.
3 | #
4 | # See: dh_installdeb(1).
5 |
6 | set -e
7 |
8 | # Summary of how this script can be called:
9 | # * 'remove'
10 | # * 'purge'
11 | # * 'upgrade'
12 | # * 'failed-upgrade'
13 | # * 'abort-install'
14 | # * 'abort-install'
15 | # * 'abort-upgrade'
16 | # * 'disappear'
17 | #
18 | # for details, see https://www.debian.org/doc/debian-policy/ or
19 | # the debian-policy package.
20 |
21 |
22 | case "$1" in
23 | purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
24 | ;;
25 |
26 | *)
27 | echo "postrm called with unknown argument '$1'" >&2
28 | exit 1
29 | ;;
30 | esac
31 |
32 | # dh_installdeb will replace this with shell code automatically
33 | # generated by other debhelper scripts.
34 |
35 | #DEBHELPER#
36 |
37 | exit 0
38 |
--------------------------------------------------------------------------------
/debian/preinst.ex:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # preinst script for seedtool-cli.
3 | #
4 | # See: dh_installdeb(1).
5 |
6 | set -e
7 |
8 | # Summary of how this script can be called:
9 | # * 'install'
10 | # * 'install'
11 | # * 'upgrade'
12 | # * 'abort-upgrade'
13 | # for details, see https://www.debian.org/doc/debian-policy/ or
14 | # the debian-policy package.
15 |
16 |
17 | case "$1" in
18 | install|upgrade)
19 | ;;
20 |
21 | abort-upgrade)
22 | ;;
23 |
24 | *)
25 | echo "preinst called with unknown argument '$1'" >&2
26 | exit 1
27 | ;;
28 | esac
29 |
30 | # dh_installdeb will replace this with shell code automatically
31 | # generated by other debhelper scripts.
32 |
33 | #DEBHELPER#
34 |
35 | exit 0
36 |
--------------------------------------------------------------------------------
/debian/prerm.ex:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # prerm script for seedtool-cli.
3 | #
4 | # See: dh_installdeb(1).
5 |
6 | set -e
7 |
8 | # Summary of how this script can be called:
9 | # * 'remove'
10 | # * 'upgrade'
11 | # * 'failed-upgrade'
12 | # * 'remove' 'in-favour'
13 | # * 'deconfigure' 'in-favour'
14 | # 'removing'
15 | #
16 | # for details, see https://www.debian.org/doc/debian-policy/ or
17 | # the debian-policy package.
18 |
19 |
20 | case "$1" in
21 | remove|upgrade|deconfigure)
22 | ;;
23 |
24 | failed-upgrade)
25 | ;;
26 |
27 | *)
28 | echo "prerm called with unknown argument '$1'" >&2
29 | exit 1
30 | ;;
31 | esac
32 |
33 | # dh_installdeb will replace this with shell code automatically
34 | # generated by other debhelper scripts.
35 |
36 | #DEBHELPER#
37 |
38 | exit 0
39 |
--------------------------------------------------------------------------------
/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 |
3 | # See debhelper(7) (uncomment to enable).
4 | # Output every command that modifies files on the build system.
5 | #export DH_VERBOSE = 1
6 |
7 | # See FEATURE AREAS in dpkg-buildflags(1).
8 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all
9 |
10 | # See ENVIRONMENT in dpkg-buildflags(1).
11 | # Package maintainers to append CFLAGS.
12 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
13 | # Package maintainers to append LDFLAGS.
14 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
15 |
16 | export CC=clang
17 | export CXX=clang++
18 | export SYSROOT=/tmp/sysroot
19 | export LIB=${SYSROOT}/lib
20 | export INCLUDE=${SYSROOT}/include
21 |
22 | export CFLAGS += -I${INCLUDE}
23 | export CXXFLAGS += -I${INCLUDE}
24 | export LDFLAGS += -L${LIB}
25 |
26 | %:
27 | cd deps/bc-crypto-base && \
28 | autoreconf --install && \
29 | ./configure --prefix ${SYSROOT} && \
30 | make check && \
31 | make install && make clean || true
32 |
33 | cd deps/bc-shamir && \
34 | autoreconf --install && \
35 | ./configure --prefix ${SYSROOT} && \
36 | make check && \
37 | make install && make clean || true
38 |
39 | cd deps/bc-sskr && \
40 | autoreconf --install && \
41 | ./configure --prefix ${SYSROOT} && \
42 | make check && \
43 | make install && make clean || true
44 |
45 | cd deps/bc-bip39 && \
46 | autoreconf --install && \
47 | ./configure --prefix ${SYSROOT} && \
48 | make check && \
49 | make install && make clean || true
50 |
51 | cd deps/bc-ur && \
52 | autoreconf --install && \
53 | ./configure --prefix ${SYSROOT} && \
54 | make check && \
55 | make install && make clean || true
56 |
57 | cd deps/argp-standalone/argp-standalone && \
58 | autoreconf --install && \
59 | ./configure --prefix ${SYSROOT} && \
60 | make install && \
61 | cp libargp.a ${SYSROOT}/lib/ && \
62 | cp argp.h ${SYSROOT}/include/ && \
63 | make distclean
64 |
65 | dh $@
66 |
67 | override_dh_autoreconf:
68 | autoreconf --install
69 | dh_autoreconf
70 |
71 | # dh_make generated override targets.
72 | # This is an example for Cmake (see ).
73 | # override_dh_auto_configure:
74 | # ./configure
75 |
76 | # override_dh_auto_build:
77 | # dh_auto_build
78 |
79 | # override_dh_auto_test:
80 | # dh_auto_test
81 |
82 | override_dh_auto_clean:
83 | cd deps/bc-crypto-base && make clean || true
84 | cd deps/bc-shamir && make clean || true
85 | cd deps/bc-sskr && make clean || true
86 | cd deps/bc-bip39 && make clean || true
87 | cd deps/bc-ur && make clean || true
88 | cd deps/argp-standalone/argp-standalone && make clean || true
89 | if [ -f ./Makefile ];then make distclean; fi
90 | # TEST that this clears old copies of source/seedtool
91 | # dh_auto_clean
92 |
93 | override_dh_dwz:
94 | true
95 |
--------------------------------------------------------------------------------
/debian/salsa-ci.yml.ex:
--------------------------------------------------------------------------------
1 | # For more information on what jobs are run see:
2 | # https://salsa.debian.org/salsa-ci-team/pipeline
3 | #
4 | # To enable the jobs, go to your repository (at salsa.debian.org)
5 | # and click over Settings > CI/CD > Expand (in General pipelines).
6 | # In "CI/CD configuration file" write debian/salsa-ci.yml and click
7 | # in "Save Changes". The CI tests will run after the next commit.
8 | ---
9 | include:
10 | - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
11 | - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
12 |
--------------------------------------------------------------------------------
/debian/seedtool-cli-docs.docs:
--------------------------------------------------------------------------------
1 | README.source
2 | README.Debian
3 |
--------------------------------------------------------------------------------
/debian/seedtool-cli.cron.d.ex:
--------------------------------------------------------------------------------
1 | #
2 | # Regular cron jobs for the seedtool-cli package.
3 | #
4 | 0 4 * * * root [ -x /usr/bin/seedtool-cli_maintenance ] && /usr/bin/seedtool-cli_maintenance
5 |
--------------------------------------------------------------------------------
/debian/seedtool-cli.doc-base.ex:
--------------------------------------------------------------------------------
1 | Document: seedtool-cli
2 | Title: Debian seedtool-cli Manual
3 | Author:
4 | Abstract: This manual describes what seedtool-cli is
5 | and how it can be used to
6 | manage online manuals on Debian systems.
7 | Section: unknown
8 |
9 | Format: debiandoc-sgml
10 | Files: /usr/share/doc/seedtool-cli/seedtool-cli.sgml.gz
11 |
12 | Format: postscript
13 | Files: /usr/share/doc/seedtool-cli/seedtool-cli.ps.gz
14 |
15 | Format: text
16 | Files: /usr/share/doc/seedtool-cli/seedtool-cli.text.gz
17 |
18 | Format: HTML
19 | Index: /usr/share/doc/seedtool-cli/html/index.html
20 | Files: /usr/share/doc/seedtool-cli/html/*.html
21 |
--------------------------------------------------------------------------------
/debian/source/format:
--------------------------------------------------------------------------------
1 | 3.0 (quilt)
2 |
--------------------------------------------------------------------------------
/debian/source/include-binaries:
--------------------------------------------------------------------------------
1 | src/format-base10.o
2 | src/format-base6.o
3 | src/format-bip39.o
4 | src/format-bits.o
5 | src/format-bytewords-minimal.o
6 | src/format-bytewords-uri.o
7 | src/format-bytewords.o
8 | src/format-cards.o
9 | src/format-dice.o
10 | src/format-hex.o
11 | src/format-ints.o
12 | src/format-random.o
13 | src/format-sskr.o
14 | src/format.o
15 | src/hkdf.o
16 | src/params.o
17 | src/random.o
18 | src/randombytes.o
19 | src/seedtool
20 | src/seedtool.o
21 | src/utils.o
22 |
--------------------------------------------------------------------------------
/debian/source/options:
--------------------------------------------------------------------------------
1 | # This, when put here, doesn't work.
2 | # extend-diff-ignore = "(/deps/.*)|(/src/Makefile.in)|(/debian/)$"
3 | extend-diff-ignore = "packaging.md"
4 | extend-diff-ignore = "build/.*"
5 | # extend-diff-ignore = "deps/.*"
6 | extend-diff-ignore = "src/config.h.in"
7 | extend-diff-ignore = "build-tailsOS.Dockerfile"
8 | extend-diff-ignore = "stamp-h1"
9 | extend-diff-ignore = "configure"
10 | extend-diff-ignore = "test.log"
11 | extend-diff-ignore = "test/Makefile"
12 | extend-diff-ignore = "testsuite/Makefile"
13 | # skip-patches
--------------------------------------------------------------------------------
/debian/upstream/metadata.ex:
--------------------------------------------------------------------------------
1 | # Example file for upstream/metadata.
2 | # See https://wiki.debian.org/UpstreamMetadata for more info/fields.
3 | # Below an example based on a github project.
4 |
5 | # Bug-Database: https://github.com//seedtool-cli/issues
6 | # Bug-Submit: https://github.com//seedtool-cli/issues/new
7 | # Changelog: https://github.com//seedtool-cli/blob/master/CHANGES
8 | # Documentation: https://github.com//seedtool-cli/wiki
9 | # Repository-Browse: https://github.com//seedtool-cli
10 | # Repository: https://github.com//seedtool-cli.git
11 |
--------------------------------------------------------------------------------
/debian/watch.ex:
--------------------------------------------------------------------------------
1 | # Example watch control file for uscan.
2 | # Rename this file to "watch" and then you can run the "uscan" command
3 | # to check for upstream updates and more.
4 | # See uscan(1) for format.
5 |
6 | # Compulsory line, this is a version 4 file.
7 | version=4
8 |
9 | # PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig.
10 | #opts="pgpsigurlmangle=s%$%.sig%"
11 |
12 | # HTTP site (basic).
13 | #http://example.com/downloads.html \
14 | # files/seedtool-cli-([\d\.]+)\.tar\.gz
15 |
16 | # Uncomment to examine an FTP server.
17 | #ftp://ftp.example.com/pub/seedtool-cli-(.*)\.tar\.gz
18 |
19 | # SourceForge hosted projects.
20 | #http://sf.net/seedtool-cli/ seedtool-cli-(.*)\.tar\.gz
21 |
22 | # GitHub hosted projects.
23 | #opts="filenamemangle=s%(?:.*?)?v?(@ANY_VERSION@@ARCHIVE_EXT@)%@PACKAGE@-$1%" \
24 | # https://github.com///tags \
25 | # (?:.*?/)v?@ANY_VERSION@@ARCHIVE_EXT@
26 |
27 | # GitLab hosted projects.
28 | #opts="filenamemangle=s%(?:.*?)?v?(@ANY_VERSION@@ARCHIVE_EXT@)%@PACKAGE@-$1%" \
29 | # https://gitlab.com///-/tags \
30 | # archive/v?@ANY_VERSION@/-v?\d\S*@ARCHIVE_EXT@
31 |
32 | # PyPI.
33 | #https://pypi.debian.net/seedtool-cli/seedtool-cli-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
34 |
35 | # Direct Git.
36 | #opts="mode=git" http://git.example.com/seedtool-cli.git \
37 | # refs/tags/v([\d\.]+)
38 |
--------------------------------------------------------------------------------
/example-scripts/bip39-to-sskr.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # This is an example script that uses Seedtool that converts a BIP39 seed into a set of SSKR shares in one step.
5 | #
6 | #
7 | # Example invocation on single line:
8 | #
9 | # ./bip39-to-sskr.sh "slender horse coil sketch public wink nest point royal believe inform lyrics critic harbor scheme enrich burden glance song chicken grief first panic actor" --group-threshold 1 --group 2-of-3 --group 3-of-5
10 | #
11 | # tuna acid epic hard data tied visa acid acid able hope glow iced meow flew ruby omit fizz need task gear claw door hope meow waxy dark keep barn math beta tent half wasp idea fern peck void limp peck fact half cook game down fish
12 | # tuna acid epic hard data tied visa acid acid acid keno kept oboe data rock skew plus vast free kick horn horn fund foxy tomb gray diet soap roof runs time pose yell able inch fern crux lung into twin pool back user purr fish guru
13 | # tuna acid epic hard data tied visa acid acid also belt fish yurt wave play gear ruby claw fern redo cola wave waxy iron blue luau film bulb kept taco pose drop bias dull jowl fern open echo heat game axis waxy jury list king judo
14 | # tuna acid epic hard data tied visa acid brag able drop mild paid what rich fair jolt urge user exit race saga lion user play cyan crux heat fizz wolf figs chef oval void half numb king gems puma exam away oval scar play vibe cook
15 | # tuna acid epic hard data tied visa acid brag acid cyan axis mild trip fizz unit dice calm memo ramp flew sets toil trip view waxy mild days lung news gush diet yank yank back pool aunt scar roof draw even zest many rust axis memo
16 | # tuna acid epic hard data tied visa acid brag also menu noon flux lamb quiz gift lazy slot twin very axis high hope ruby aqua surf acid very rich each knob fund purr guru oboe mint flux pool fizz gear sets apex deli kiwi tent bald
17 | # tuna acid epic hard data tied visa acid brag apex next also knob hang gift play slot bias miss jowl zone heat barn road game acid quiz next jury holy cash keys very flap zone monk fish curl gift good zaps hawk jade calm fern list
18 | # tuna acid epic hard data tied visa acid brag aqua work cyan cash onyx cook inch fern memo note sets wall need soap puff cusp free eyes crux grim code solo lamb judo veto main idle days cusp solo zest kiwi quad foxy claw play unit
19 | #
20 | #
21 | # Example invocation using STDIN to supply the BIP39 words
22 | #
23 | # ./bip39-to-sskr.sh "" --group-threshold 1 --group 2-of-3 --group 3-of-5
24 | # slender horse coil sketch public wink nest point royal believe inform lyrics critic harbor scheme enrich burden glance song chicken grief first panic actor
25 | # ^D
26 | #
27 | # tuna acid epic hard data skew wand acid acid able jugs noon kiln aunt roof leaf race figs horn exit knob wave next fuel pose taco miss work ruby webs huts film mild wolf zoom free puff wave whiz sets beta wave tent time kiwi vibe
28 | # tuna acid epic hard data skew wand acid acid acid hill oboe lazy stub hard fair diet days task jowl glow jade hope into hope undo game toys view flux vibe navy time judo duty main eyes hope junk what news lazy redo half yank gyro
29 | # tuna acid epic hard data skew wand acid acid also diet visa miss liar jowl warm mint bald data mint code zaps also aunt gush wand even purr belt plus judo join chef waxy kiln soap rich memo warm plus each epic task numb unit kept
30 | # tuna acid epic hard data skew wand acid brag able leaf wall toys trip undo exit ruby navy girl work legs bulb purr luau girl wasp poem quiz able void skew puff yawn gyro kite rich cook each peck belt lazy time void luck zaps maze
31 | # tuna acid epic hard data skew wand acid brag acid yoga jolt gems song mild hard inky when zest keep surf work hard news calm gear poem plus zone cook numb lava leaf work judo ruin zinc oval task next acid gyro oboe road lion runs
32 | # tuna acid epic hard data skew wand acid brag also high runs memo onyx note skew good jury oval peck pose menu toil lung news note iris hard slot kite arch navy heat note tent high item very barn limp zone quad taxi judo fuel eyes
33 | # tuna acid epic hard data skew wand acid brag apex days exit axis ramp tomb oval luau cost bulb down vast junk fish navy sets exit iris fizz eyes limp idea peck drum film unit help loud keno iron buzz knob epic mild frog fair cash
34 | # tuna acid epic hard data skew wand acid brag aqua lung grim visa help echo deli into ruby webs glow data item wand deli iced memo arch door buzz chef into toys ruin numb user wall idle echo half zest work tiny tied pose apex vibe
35 | #
36 |
37 | BIP39=$1
38 | SSKR_OPTIONS=${@:2}
39 | seedtool --in bip39 ${BIP39} | seedtool --in hex --out sskr ${SSKR_OPTIONS}
40 |
--------------------------------------------------------------------------------
/example-scripts/sskr-to-bip39.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # This is an example script that converts a set of SSKR shares to BIP-39 seed in one step. It takes the shares from STDIN and
5 | # write the BIP-39 seed to STDOUT.
6 | #
7 | # Example invocation:
8 | #
9 | # ./sskr-to-bip39.sh
10 | # tuna acid epic hard data tied visa acid acid able hope glow iced meow flew ruby omit fizz need task gear claw door hope meow waxy dark keep barn math beta tent half wasp idea fern peck void limp peck fact half cook game down fish
11 | # tuna acid epic hard data tied visa acid acid acid keno kept oboe data rock skew plus vast free kick horn horn fund foxy tomb gray diet soap roof runs time pose yell able inch fern crux lung into twin pool back user purr fish guru
12 | # ^D
13 | #
14 | # slender horse coil sketch public wink nest point royal believe inform lyrics critic harbor scheme enrich burden glance song chicken grief first panic actor
15 |
16 | seedtool --in sskr | seedtool --in hex --out bip39
17 |
--------------------------------------------------------------------------------
/images/logos/README.md:
--------------------------------------------------------------------------------
1 | Logos for social media.
2 |
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-black.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-black.jpg
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-black.png
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-black.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-black.psd
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-shapes.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-shapes.ai
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-white.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-white.jpg
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-white.png
--------------------------------------------------------------------------------
/images/logos/seedtool-logo-white.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-logo-white.psd
--------------------------------------------------------------------------------
/images/logos/seedtool-screen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-screen.jpg
--------------------------------------------------------------------------------
/images/logos/seedtool-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-screen.png
--------------------------------------------------------------------------------
/images/logos/seedtool-screen.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/images/logos/seedtool-screen.psd
--------------------------------------------------------------------------------
/manual-images/seedqrcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlockchainCommons/seedtool-cli/b79d02fb6d936921dd36c08c3994bfd155ee7288/manual-images/seedqrcode.png
--------------------------------------------------------------------------------
/set_build_paths.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SYSROOT=${PWD}/sysroot
4 | LIB=${SYSROOT}/lib
5 | INCLUDE=${SYSROOT}/include
6 |
7 | export CFLAGS="${CFLAGS} -I${INCLUDE}"
8 | export CXXFLAGS="${CXXFLAGS} -I${INCLUDE}"
9 | export LDFLAGS="${LDFLAGS} -L${LIB}"
10 |
--------------------------------------------------------------------------------
/src/.gitignore:
--------------------------------------------------------------------------------
1 | seedtool
2 |
--------------------------------------------------------------------------------
/src/Makefile.in:
--------------------------------------------------------------------------------
1 | # @configure_input@
2 |
3 | #
4 | # Makefile.in
5 | #
6 | # Copyright © 2020 by Blockchain Commons, LLC
7 | # Licensed under the "BSD-2-Clause Plus Patent License"
8 | #
9 |
10 | # Package-specific substitution variables
11 | package = @PACKAGE_NAME@
12 | version = @PACKAGE_VERSION@
13 | tarname = @PACKAGE_TARNAME@
14 |
15 | # Prefix-specific substitution variables
16 | prefix = @prefix@
17 | exec_prefix = @exec_prefix@
18 | bindir = @bindir@
19 |
20 | # VPATH-specific substitution variables
21 | srcdir = @srcdir@
22 | VPATH = @srcdir@
23 |
24 | # Terminal colors
25 | RED=`tput setaf 1`
26 | GREEN=`tput setaf 2`
27 | RESET=`tput sgr0`
28 |
29 | CBOR_DIR = ../deps/cbor-lite
30 |
31 | COMPILER = g++
32 | CFLAGS += --debug -O0
33 | CXXFLAGS += -std=c++17 --debug -O0 -I"$(CBOR_DIR)/include"
34 |
35 | toolname = seedtool
36 |
37 | .PHONY: all
38 | all: $(toolname)
39 |
40 | OBJS = \
41 | seedtool.o \
42 | utils.o \
43 | params.o \
44 | random.o \
45 | format.o \
46 | format-base6.o \
47 | format-base10.o \
48 | format-bip39.o \
49 | format-bits.o \
50 | format-cards.o \
51 | format-dice.o \
52 | format-hex.o \
53 | format-ints.o \
54 | format-random.o \
55 | format-sskr.o \
56 | format-bytewords.o \
57 | format-bytewords-uri.o \
58 | format-bytewords-minimal.o \
59 | randombytes.o \
60 | hkdf.o
61 |
62 | LDLIBS += -lbc-sskr -lbc-shamir -lbc-crypto-base -lbc-bip39 -lbc-ur -largp
63 |
64 | UNAME := $(shell uname)
65 | ifeq ($(UNAME), Linux)
66 | LDLIBS += -lm -lgcc_s -lgcc -lstdc++
67 | else ifeq ($(findstring MINGW64, $(UNAME)), MINGW64)
68 | # on windows building with msys2/mingw64
69 | LDLIBS += -lm -lc++ -lws2_32
70 | else
71 | LDLIBS += -lstdc++
72 | endif
73 |
74 | $(toolname): $(OBJS)
75 |
76 | seedtool.o: params.hpp format.hpp
77 | utils.o: utils.hpp
78 | params.o: params.hpp utils.hpp random.hpp formats-all.hpp config.h
79 | random.o: random.hpp randombytes.h hkdf.h utils.hpp
80 | randombytes.o: randombytes.h
81 | hkdf.o: hkdf.h
82 | format.o: format.hpp utils.hpp
83 | formats-all.hpp: format-base6.hpp format-base10.hpp format-bip39.hpp format-bits.hpp format-cards.hpp format-dice.hpp format-hex.hpp format-ints.hpp format-random.hpp format-sskr.hpp format-bytewords.hpp format-bytewords-uri.hpp format-bytewords-minimal.hpp
84 | format-base6.o: format-base6.hpp format.hpp params.hpp random.hpp
85 | format-base10.o: format-base10.hpp format.hpp params.hpp random.hpp
86 | format-bip39.o: format-bip39.hpp format.hpp params.hpp random.hpp utils.hpp cbor-utils.hpp
87 | format-bits.o: format-bits.hpp format.hpp params.hpp random.hpp
88 | format-cards.o: format-cards.hpp format.hpp params.hpp random.hpp
89 | format-dice.o: format-dice.hpp format.hpp params.hpp random.hpp
90 | format-hex.o: format-hex.hpp format.hpp params.hpp random.hpp utils.hpp cbor-utils.hpp
91 | format-ints.o: format-ints.hpp format.hpp params.hpp random.hpp
92 | format-random.o: format-random.hpp format.hpp params.hpp random.hpp
93 | format-sskr.o: format-sskr.hpp format.hpp params.hpp random.hpp utils.hpp cbor-utils.hpp
94 | format-bytewords.o: format-bytewords.hpp format.hpp params.hpp random.hpp
95 | format-bytewords-uri.o: format-bytewords-uri.hpp format.hpp params.hpp random.hpp
96 | format-bytewords-minimal.o: format-bytewords-minimal.hpp format.hpp params.hpp random.hpp
97 |
98 | bindir = $(DESTDIR)$(prefix)/bin
99 |
100 | .PHONY: install
101 | install: $(toolname)
102 | install -d $(bindir)
103 | install $(toolname) $(bindir)
104 |
105 | .PHONY: uninstall
106 | uninstall:
107 | rm -f $(bindir)/$(toolname)
108 | -rmdir $(bindir) >/dev/null 2>&1
109 |
110 | .PHONY: check
111 | check: $(toolname)
112 | ./test.sh ./$(toolname)
113 |
114 | .PHONY: clean
115 | clean:
116 | rm -f $(toolname) *.o
117 | rm -rf *.dSYM
118 |
119 | .PHONY: distclean
120 | distclean: clean
121 | rm -f Makefile
122 | rm -f config.h
123 |
124 | .PHONY: lint
125 | lint:
126 | cppcheck --enable=all --error-exitcode=1 --inline-suppr --suppress=missingInclude --suppress=ConfigurationNotChecked .
127 |
--------------------------------------------------------------------------------
/src/cbor-utils.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // cbor.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #ifndef CBOR_UTILS_HPP
9 | #define CBOR_UTILS_HPP
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "utils.hpp"
17 |
18 | const auto cborDecodingFlags = ur::CborLite::Flag::requireMinimalEncoding;
19 |
20 | template
21 | void encode_byte_string(Buffer& cbor, const ByteVector& bytes) {
22 | ur::CborLite::encodeBytes(cbor, bytes);
23 | }
24 |
25 | template
26 | void decode_byte_string(Iter& pos, Iter end, ByteVector& bytes) {
27 | ur::CborLite::decodeBytes(pos, end, bytes, cborDecodingFlags);
28 | }
29 |
30 | template
31 | void encode_string_array(Buffer& cbor, const StringVector& strings) {
32 | ur::CborLite::encodeArraySize(cbor, strings.size());
33 | for(auto string: strings) {
34 | ur::CborLite::encodeText(cbor, string);
35 | }
36 | }
37 |
38 | template
39 | void decode_string_array(Iter& pos, Iter end, StringVector& strings) {
40 | size_t size;
41 | ur::CborLite::decodeArraySize(pos, end, size, cborDecodingFlags);
42 | for(auto i = 0; i < size; i++) {
43 | std::string s;
44 | ur::CborLite::decodeText(pos, end, s, cborDecodingFlags);
45 | strings.push_back(s);
46 | }
47 | }
48 |
49 | template
50 | void encode_array_of_string_arrays(Buffer& cbor, const std::vector& array_of_string_arrays) {
51 | ur::CborLite::encodeArraySize(cbor, array_of_string_arrays.size());
52 | for(auto string_array: array_of_string_arrays) {
53 | encode_string_array(cbor, string_array);
54 | }
55 | }
56 |
57 | template
58 | void decode_array_of_string_arrays(Iter& pos, Iter end, std::vector& array_of_string_arrays) {
59 | size_t size;
60 | ur::CborLite::decodeArraySize(pos, end, size, cborDecodingFlags);
61 | for(auto i = 0; i < size; i++) {
62 | StringVector strings;
63 | decode_string_array(pos, end, strings);
64 | array_of_string_arrays.push_back(strings);
65 | }
66 | }
67 |
68 | template
69 | void encode_dict_with_birthdate(Buffer& cbor, const ByteVector& embedded_cbor, bool include_birthdate) {
70 | size_t map_size = include_birthdate ? 2 : 1;
71 | ur::CborLite::encodeMapSize(cbor, size_t(map_size));
72 | ur::CborLite::encodeInteger(cbor, 1);
73 | append(cbor, embedded_cbor);
74 | if(include_birthdate) {
75 | ur::CborLite::encodeInteger(cbor, 2);
76 | ur::CborLite::encodeTagAndValue(cbor, ur::CborLite::Major::semantic, size_t(100));
77 | ur::CborLite::encodeInteger(cbor, days_since_epoch());
78 | }
79 | }
80 |
81 | template
82 | void decode_dict_with_birthdate(Iter& pos, Iter end, Func f) {
83 | size_t map_len;
84 | auto len = ur::CborLite::decodeMapSize(pos, end, map_len, cborDecodingFlags);
85 | std::set labels;
86 | for(auto i = 0; i < map_len; i++) {
87 | int label;
88 | ur::CborLite::decodeInteger(pos, end, label, cborDecodingFlags);
89 | if(labels.find(label) != labels.end()) {
90 | throw std::runtime_error("Duplicate label.");
91 | }
92 | labels.insert(label);
93 | switch (label) {
94 | case 1:
95 | f(pos, end);
96 | break;
97 | case 2: {
98 | // Birthday field ignored
99 | ur::CborLite::Tag tag;
100 | size_t value;
101 | ur::CborLite::decodeTagAndValue(pos, end, tag, value, cborDecodingFlags);
102 | if(tag != ur::CborLite::Major::semantic) {
103 | throw std::runtime_error("Invalid date.");
104 | }
105 | switch(value) {
106 | case 0: {
107 | std::string date;
108 | ur::CborLite::decodeText(pos, end, date, cborDecodingFlags);
109 | }
110 | break;
111 | case 1: {
112 | double date;
113 | ur::CborLite::decodeDoubleFloat(pos, end, date, cborDecodingFlags);
114 | }
115 | break;
116 | case 100: {
117 | int date;
118 | ur::CborLite::decodeInteger(pos, end, date, cborDecodingFlags);
119 | }
120 | break;
121 | default:
122 | throw std::runtime_error("Invalid date.");
123 | }
124 | }
125 | break;
126 | case 3: {
127 | // Name field ignored
128 | std::string name;
129 | ur::CborLite::decodeText(pos, end, name, cborDecodingFlags);
130 | }
131 | break;
132 | case 4: {
133 | // Note field ignored
134 | std::string note;
135 | ur::CborLite::decodeText(pos, end, note, cborDecodingFlags);
136 | }
137 | break;
138 | default:
139 | throw std::runtime_error("Unknown label.");
140 | break;
141 | }
142 | }
143 | if(pos != end) {
144 | throw std::runtime_error("Additional unknown bytes at end.");
145 | }
146 | }
147 |
148 | #endif // CBOR_UTILS_HPP
149 |
--------------------------------------------------------------------------------
/src/config.h.in:
--------------------------------------------------------------------------------
1 | /* src/config.h.in. Generated from configure.ac by autoheader. */
2 |
3 | /* Define to 1 if you have the header file. */
4 | #undef HAVE_FCNTL_H
5 |
6 | /* Define to 1 if you have the header file. */
7 | #undef HAVE_INTTYPES_H
8 |
9 | /* Define to 1 if you have the `argp' library (-largp). */
10 | #undef HAVE_LIBARGP
11 |
12 | /* Define to 1 if you have the `bc-bip39' library (-lbc-bip39). */
13 | #undef HAVE_LIBBC_BIP39
14 |
15 | /* Define to 1 if you have the `bc-crypto-base' library (-lbc-crypto-base). */
16 | #undef HAVE_LIBBC_CRYPTO_BASE
17 |
18 | /* Define to 1 if you have the `bc-shamir' library (-lbc-shamir). */
19 | #undef HAVE_LIBBC_SHAMIR
20 |
21 | /* Define to 1 if you have the `bc-sskr' library (-lbc-sskr). */
22 | #undef HAVE_LIBBC_SSKR
23 |
24 | /* Define to 1 if you have the `bc-ur' library (-lbc-ur). */
25 | #undef HAVE_LIBBC_UR
26 |
27 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
28 | to 0 otherwise. */
29 | #undef HAVE_MALLOC
30 |
31 | /* Define to 1 if you have the header file. */
32 | #undef HAVE_MEMORY_H
33 |
34 | /* Define to 1 if you have the `memset' function. */
35 | #undef HAVE_MEMSET
36 |
37 | /* Define to 1 if you have the header file. */
38 | #undef HAVE_STDDEF_H
39 |
40 | /* Define to 1 if you have the header file. */
41 | #undef HAVE_STDINT_H
42 |
43 | /* Define to 1 if you have the header file. */
44 | #undef HAVE_STDIO_H
45 |
46 | /* Define to 1 if you have the header file. */
47 | #undef HAVE_STDLIB_H
48 |
49 | /* Define to 1 if you have the `strerror' function. */
50 | #undef HAVE_STRERROR
51 |
52 | /* Define to 1 if you have the header file. */
53 | #undef HAVE_STRINGS_H
54 |
55 | /* Define to 1 if you have the header file. */
56 | #undef HAVE_STRING_H
57 |
58 | /* Define to 1 if you have the header file. */
59 | #undef HAVE_SYS_IOCTL_H
60 |
61 | /* Define to 1 if you have the header file. */
62 | #undef HAVE_SYS_PARAM_H
63 |
64 | /* Define to 1 if you have the header file. */
65 | #undef HAVE_SYS_STAT_H
66 |
67 | /* Define to 1 if you have the header file. */
68 | #undef HAVE_SYS_TYPES_H
69 |
70 | /* Define to 1 if you have the header file. */
71 | #undef HAVE_UNISTD_H
72 |
73 | /* Define to 1 if the system has the type `_Bool'. */
74 | #undef HAVE__BOOL
75 |
76 | /* Define to the address where bug reports for this package should be sent. */
77 | #undef PACKAGE_BUGREPORT
78 |
79 | /* Define to the full name of this package. */
80 | #undef PACKAGE_NAME
81 |
82 | /* Define to the full name and version of this package. */
83 | #undef PACKAGE_STRING
84 |
85 | /* Define to the one symbol short name of this package. */
86 | #undef PACKAGE_TARNAME
87 |
88 | /* Define to the home page for this package. */
89 | #undef PACKAGE_URL
90 |
91 | /* Define to the version of this package. */
92 | #undef PACKAGE_VERSION
93 |
94 | /* Define to 1 if all of the C90 standard headers exist (not just the ones
95 | required in a freestanding environment). This macro is provided for
96 | backward compatibility; new code need not use it. */
97 | #undef STDC_HEADERS
98 |
99 | /* Define for Solaris 2.5.1 so the uint32_t typedef from ,
100 | , or is not used. If the typedef were allowed, the
101 | #define below would cause a syntax error. */
102 | #undef _UINT32_T
103 |
104 | /* Define for Solaris 2.5.1 so the uint64_t typedef from ,
105 | , or is not used. If the typedef were allowed, the
106 | #define below would cause a syntax error. */
107 | #undef _UINT64_T
108 |
109 | /* Define for Solaris 2.5.1 so the uint8_t typedef from ,
110 | , or is not used. If the typedef were allowed, the
111 | #define below would cause a syntax error. */
112 | #undef _UINT8_T
113 |
114 | /* Define to `__inline__' or `__inline' if that's what the C compiler
115 | calls it, or to nothing if 'inline' is not supported under any name. */
116 | #ifndef __cplusplus
117 | #undef inline
118 | #endif
119 |
120 | /* Define to the type of a signed integer type of width exactly 16 bits if
121 | such a type exists and the standard includes do not define it. */
122 | #undef int16_t
123 |
124 | /* Define to the type of a signed integer type of width exactly 32 bits if
125 | such a type exists and the standard includes do not define it. */
126 | #undef int32_t
127 |
128 | /* Define to rpl_malloc if the replacement function should be used. */
129 | #undef malloc
130 |
131 | /* Define to `unsigned int' if does not define. */
132 | #undef size_t
133 |
134 | /* Define to `int' if does not define. */
135 | #undef ssize_t
136 |
137 | /* Define to the type of an unsigned integer type of width exactly 16 bits if
138 | such a type exists and the standard includes do not define it. */
139 | #undef uint16_t
140 |
141 | /* Define to the type of an unsigned integer type of width exactly 32 bits if
142 | such a type exists and the standard includes do not define it. */
143 | #undef uint32_t
144 |
145 | /* Define to the type of an unsigned integer type of width exactly 64 bits if
146 | such a type exists and the standard includes do not define it. */
147 | #undef uint64_t
148 |
149 | /* Define to the type of an unsigned integer type of width exactly 8 bits if
150 | such a type exists and the standard includes do not define it. */
151 | #undef uint8_t
152 |
--------------------------------------------------------------------------------
/src/format-base10.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-base10.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-base10.hpp"
9 |
10 | #include
11 |
12 | #include "params.hpp"
13 | #include "utils.hpp"
14 | #include "random.hpp"
15 |
16 | void FormatBase10::process_input(Params* p) {
17 | auto input = p->get_one_argument();
18 |
19 | #if 0
20 | auto entropy = digits_to_data(input, 0, 9);
21 | p->seed = deterministic_random(entropy, p->count);
22 | #else
23 | // Compatibility with https://iancoleman.io/bip39/
24 | digits_to_data(input, 0, 9); // syntax check only
25 | p->seed = sha256_deterministic_random(input, p->count);
26 | #endif
27 | }
28 |
29 | void FormatBase10::process_output(Params* p) {
30 | p->output = data_to_ints(p->seed, 0, 9, "");
31 | }
32 |
--------------------------------------------------------------------------------
/src/format-base10.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-base10.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBase10 : public Format {
13 | public:
14 | FormatBase10() : Format(Format::Key::base10, "base10") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-base6.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-base6.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-base6.hpp"
9 |
10 | #include
11 |
12 | #include "params.hpp"
13 | #include "utils.hpp"
14 | #include "random.hpp"
15 |
16 | void FormatBase6::process_input(Params* p) {
17 | auto input = p->get_one_argument();
18 |
19 | #if 0
20 | auto entropy = digits_to_data(input, 0, 5);
21 | p->seed = deterministic_random(entropy, p->count);
22 | #else
23 | // Compatibility with https://iancoleman.io/bip39/
24 | digits_to_data(input, 0, 5); // syntax check only
25 | p->seed = sha256_deterministic_random(input, p->count);
26 | #endif
27 | }
28 |
29 | void FormatBase6::process_output(Params* p) {
30 | p->output = data_to_ints(p->seed, 0, 5, "");
31 | }
32 |
--------------------------------------------------------------------------------
/src/format-base6.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-base6.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBase6 : public Format {
13 | public:
14 | FormatBase6() : Format(Format::Key::base6, "base6") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-bip39.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bip39.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-bip39.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 |
16 | #include "params.hpp"
17 | #include "utils.hpp"
18 | #include "cbor-utils.hpp"
19 |
20 | using namespace std;
21 |
22 | bool FormatBIP39::is_seed_length_valid(size_t seed_len) {
23 | if(!(12 <= seed_len && seed_len <= 32)) { return false; }
24 | if(seed_len % 4 != 0) { return false; }
25 | return true;
26 | }
27 |
28 | void FormatBIP39::process_input(Params* p) {
29 | string input;
30 |
31 | if(p->is_ur_in) {
32 | auto& ur = p->ur_shares.front();
33 | auto pos = ur.cbor().begin();
34 | const auto end = ur.cbor().end();
35 |
36 | StringVector strings;
37 | typedef ur::ByteVector::const_iterator Iter;
38 | auto f = [&strings](Iter& pos, Iter end) {
39 | decode_string_array(pos, end, strings);
40 | };
41 | decode_dict_with_birthdate(pos, end, f);
42 | input = join(strings, " ");
43 | } else {
44 | input = p->get_combined_arguments();
45 | }
46 |
47 | ByteVector buf;
48 | buf.resize(300);
49 | auto len = bip39_secret_from_mnemonics(input.c_str(), buf.data(), buf.size());
50 | if(len == 0) {
51 | throw runtime_error("Invalid BIP39 word sequence.");
52 | }
53 | buf.resize(len);
54 | p->seed = buf;
55 | }
56 |
57 | void FormatBIP39::process_output(Params* p) {
58 | if(!is_seed_length_valid(p->seed.size())) {
59 | throw runtime_error("Invalid seed length for BIP39. Must be in [12-32] and divisible by 4.");
60 | }
61 |
62 | size_t max_mnemonics_len = 300;
63 | char mnemonics[max_mnemonics_len];
64 | bip39_mnemonics_from_secret(p->seed.data(), p->seed.size(), mnemonics, max_mnemonics_len);
65 | string s = mnemonics;
66 |
67 | if(p->is_ur_out) {
68 | auto words = split(s, ' ');
69 | ByteVector encoded_words;
70 | encode_string_array(encoded_words, words);
71 | ByteVector dict;
72 | encode_dict_with_birthdate(dict, encoded_words, false);
73 | p->set_ur_output(dict, "crypto-bip39");
74 | } else {
75 | p->output = s;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/format-bip39.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bip39.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBIP39 : public Format {
13 | public:
14 | FormatBIP39() : Format(Format::Key::bip39, "bip39") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 |
19 | static bool is_seed_length_valid(size_t seed_len);
20 | };
21 |
--------------------------------------------------------------------------------
/src/format-bits.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bits.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-bits.hpp"
9 |
10 | #include
11 |
12 | #include "params.hpp"
13 | #include "utils.hpp"
14 | #include "random.hpp"
15 |
16 | void FormatBits::process_input(Params* p) {
17 | auto input = p->get_one_argument();
18 |
19 | #if 0
20 | auto entropy = digits_to_data(input, 0, 1);
21 | p->seed = deterministic_random(entropy, p->count);
22 | #else
23 | // Compatibility with https://iancoleman.io/bip39/
24 | digits_to_data(input, 0, 1); // syntax check only
25 | p->seed = sha256_deterministic_random(input, p->count);
26 | #endif
27 | }
28 |
29 | void FormatBits::process_output(Params* p) {
30 | p->output = data_to_ints(p->seed, 0, 1, "");
31 | }
32 |
--------------------------------------------------------------------------------
/src/format-bits.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bits.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBits : public Format {
13 | public:
14 | FormatBits() : Format(Format::Key::bits, "bits") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-bytewords-minimal.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bytewords.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-bytewords-minimal.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include "params.hpp"
14 | #include "utils.hpp"
15 |
16 | using namespace std;
17 |
18 | bool FormatBytewordsMinimal::is_seed_length_valid(size_t seed_len) {
19 | if(!(1 <= seed_len && seed_len <= 64)) { return false; }
20 | return true;
21 | }
22 |
23 | void FormatBytewordsMinimal::process_input(Params* p) {
24 | auto input = p->get_one_argument();
25 | p->seed = ur::Bytewords::decode(ur::Bytewords::style::minimal, input);
26 | }
27 |
28 | void FormatBytewordsMinimal::process_output(Params* p) {
29 | p->output = ur::Bytewords::encode(ur::Bytewords::style::minimal, p->seed);
30 | }
31 |
--------------------------------------------------------------------------------
/src/format-bytewords-minimal.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bch32.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBytewordsMinimal : public Format {
13 | public:
14 | FormatBytewordsMinimal() : Format(Format::Key::bytewords, "bytewords") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 |
19 | static bool is_seed_length_valid(size_t seed_len);
20 | };
21 |
--------------------------------------------------------------------------------
/src/format-bytewords-uri.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bytewords.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-bytewords-uri.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include "params.hpp"
14 | #include "utils.hpp"
15 |
16 | using namespace std;
17 |
18 | bool FormatBytewordsURI::is_seed_length_valid(size_t seed_len) {
19 | if(!(1 <= seed_len && seed_len <= 64)) { return false; }
20 | return true;
21 | }
22 |
23 | void FormatBytewordsURI::process_input(Params* p) {
24 | auto input = p->get_one_argument();
25 | p->seed = ur::Bytewords::decode(ur::Bytewords::style::uri, input);
26 | }
27 |
28 | void FormatBytewordsURI::process_output(Params* p) {
29 | p->output = ur::Bytewords::encode(ur::Bytewords::style::uri, p->seed);
30 | }
31 |
--------------------------------------------------------------------------------
/src/format-bytewords-uri.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bch32.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBytewordsURI : public Format {
13 | public:
14 | FormatBytewordsURI() : Format(Format::Key::bytewords, "bytewords") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 |
19 | static bool is_seed_length_valid(size_t seed_len);
20 | };
21 |
--------------------------------------------------------------------------------
/src/format-bytewords.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bytewords.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-bytewords.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include "params.hpp"
14 | #include "utils.hpp"
15 |
16 | using namespace std;
17 |
18 | bool FormatBytewords::is_seed_length_valid(size_t seed_len) {
19 | if(!(1 <= seed_len && seed_len <= 64)) { return false; }
20 | return true;
21 | }
22 |
23 | void FormatBytewords::process_input(Params* p) {
24 | auto input = p->get_one_argument();
25 | p->seed = ur::Bytewords::decode(ur::Bytewords::style::standard, input);
26 | }
27 |
28 | void FormatBytewords::process_output(Params* p) {
29 | p->output = ur::Bytewords::encode(ur::Bytewords::style::standard, p->seed);
30 | }
31 |
--------------------------------------------------------------------------------
/src/format-bytewords.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-bch32.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatBytewords : public Format {
13 | public:
14 | FormatBytewords() : Format(Format::Key::bytewords, "bytewords") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 |
19 | static bool is_seed_length_valid(size_t seed_len);
20 | };
21 |
--------------------------------------------------------------------------------
/src/format-cards.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-cards.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-cards.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include "params.hpp"
14 | #include "utils.hpp"
15 | #include "random.hpp"
16 |
17 | using namespace std;
18 |
19 | // Arrangement of cards per:
20 | // https://github.com/iancoleman/bip39/blob/master/src/js/entropy.js
21 | static const string card_suits = "cdhs";
22 | static const string card_ranks = "a23456789tjqk";
23 |
24 | static size_t parse_rank(char c) {
25 | c = tolower(c);
26 | for(size_t i = 0; i < card_ranks.size(); i++) {
27 | if(c == card_ranks[i]) {
28 | return i;
29 | }
30 | }
31 | throw runtime_error("Invalid card rank. Allowed: [A,2-9,T,J,Q,K]");
32 | }
33 |
34 | static size_t parse_suit(char c) {
35 | c = tolower(c);
36 | for(size_t i = 0; i < card_suits.size(); i++) {
37 | if(c == card_suits[i]) {
38 | return i;
39 | }
40 | }
41 | throw runtime_error("Invalid card rank. Allowed: [D,C,H,S]");
42 | }
43 |
44 | ByteVector cards_to_data(const string& cards) {
45 | ByteVector result;
46 |
47 | auto len = cards.length();
48 | if(len % 2 != 0) {
49 | throw runtime_error("Cards string must have even number of characters.");
50 | }
51 | auto count = len / 2;
52 | result.reserve(count);
53 | for(auto i = 0; i < count; i++) {
54 | auto rank = parse_rank(cards[i * 2]);
55 | auto suit = parse_suit(cards[i * 2 + 1]);
56 | auto n = suit * 13 + rank;
57 | result.push_back(n);
58 | }
59 |
60 | return result;
61 | }
62 |
63 | void FormatCards::process_input(Params* p) {
64 | auto input = p->get_one_argument();
65 |
66 | // NOT currently compatible with with https://iancoleman.io/bip39/
67 | // https://github.com/iancoleman/bip39/blob/54600393af3293dc9e0f222b24ebd07b63824330/src/js/entropy.js#L245
68 |
69 | auto entropy = cards_to_data(input);
70 | p->seed = deterministic_random(entropy, p->count);
71 | }
72 |
73 | static string to_card(size_t n) {
74 | if(n > 51) { return NULL; }
75 | string buf;
76 | size_t rank = n % 13;
77 | size_t suit = n / 13;
78 | buf += card_ranks[rank];
79 | buf += card_suits[suit];
80 |
81 | // test value round trip
82 | auto v = cards_to_data(buf);
83 | assert(v.size() == 1);
84 | assert(v[0] == n);
85 |
86 | return buf;
87 | }
88 |
89 | void FormatCards::process_output(Params* p) {
90 | p->output = data_to_alphabet(p->seed, 52, to_card);
91 | }
92 |
--------------------------------------------------------------------------------
/src/format-cards.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-cards.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatCards : public Format {
13 | public:
14 | FormatCards() : Format(Format::Key::cards, "cards") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-dice.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-dice.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-dice.hpp"
9 | #include "params.hpp"
10 | #include "utils.hpp"
11 | #include "random.hpp"
12 |
13 | void FormatDice::process_input(Params* p) {
14 | auto input = p->get_one_argument();
15 |
16 | #if 0
17 | auto entropy = digits_to_data(input, 1, 6);
18 | p->seed = deterministic_random(entropy, p->count);
19 | #else
20 | // Compatibility with https://iancoleman.io/bip39/
21 | digits_to_data(input, 1, 6); // syntax check only
22 | p->seed = sha256_deterministic_random(input, p->count);
23 | #endif
24 | }
25 |
26 | void FormatDice::process_output(Params* p) {
27 | p->output = data_to_ints(p->seed, 1, 6, "");
28 | }
29 |
--------------------------------------------------------------------------------
/src/format-dice.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-dice.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatDice : public Format {
13 | public:
14 | FormatDice() : Format(Format::Key::dice, "dice") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-hex.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-hex.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-hex.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 |
16 | #include "params.hpp"
17 | #include "utils.hpp"
18 | #include "cbor-utils.hpp"
19 |
20 | using namespace std;
21 |
22 | void FormatHex::process_input(Params* p) {
23 |
24 | // Currently compatible with with https://iancoleman.io/bip39/
25 | // ONLY in "raw entropy" mode.
26 |
27 | if(p->is_ur_in) {
28 | auto& ur = p->ur_shares.front();
29 | auto pos = ur.cbor().begin();
30 | const auto end = ur.cbor().end();
31 |
32 | ByteVector bytes;
33 | typedef ur::ByteVector::const_iterator Iter;
34 | auto f = [&bytes](Iter& pos, Iter end) {
35 | decode_byte_string(pos, end, bytes);
36 | };
37 | decode_dict_with_birthdate(pos, end, f);
38 |
39 | p->seed = bytes;
40 | } else {
41 | auto input = p->get_one_argument();
42 | p->seed = hex_to_data(input);
43 | }
44 | }
45 |
46 | void FormatHex::process_output(Params* p) {
47 | if(p->is_ur_out) {
48 | ByteVector byte_string;
49 | encode_byte_string(byte_string, p->seed);
50 | ByteVector dict;
51 | encode_dict_with_birthdate(dict, byte_string, false);
52 | p->set_ur_output(dict, "seed");
53 | } else {
54 | p->output = data_to_hex(p->seed);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/format-hex.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-hex.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatHex : public Format {
13 | public:
14 | FormatHex() : Format(Format::Key::hex, "hex") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-ints.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-ints.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-ints.hpp"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "params.hpp"
16 | #include "utils.hpp"
17 | #include "random.hpp"
18 |
19 | using namespace std;
20 |
21 | FormatInts::FormatInts() : Format(Format::Key::ints, "ints") {
22 | low = 0;
23 | high = 9;
24 | }
25 |
26 | static ByteVector parse_ints(const string& input) {
27 | ByteVector result;
28 |
29 | istringstream iss(input);
30 |
31 | while(!iss.eof()) {
32 | string s;
33 | iss >> s;
34 | int i;
35 | if(!(stringstream(s) >> i)) {
36 | throw runtime_error("Invalid integer. Allowed: [0-255]");
37 | }
38 | if(!(0 <= i && i <= 255)) {
39 | throw runtime_error("Integer out of range. Allowed: [0-255]");
40 | }
41 | result.push_back(i);
42 | }
43 |
44 | return result;
45 | }
46 |
47 | void FormatInts::process_input(Params* p) {
48 | auto input = p->get_combined_arguments();
49 | auto entropy = parse_ints(input);
50 | p->seed = deterministic_random(entropy, p->count);
51 | }
52 |
53 | void FormatInts::process_output(Params* p) {
54 | p->output = data_to_ints(p->seed, low, high, " ");
55 | }
56 |
--------------------------------------------------------------------------------
/src/format-ints.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-ints.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatInts : public Format {
13 | public:
14 | FormatInts();
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 |
19 | size_t low;
20 | size_t high;
21 | };
22 |
--------------------------------------------------------------------------------
/src/format-random.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-random.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-random.hpp"
9 | #include "params.hpp"
10 |
11 | void FormatRandom::process_input(Params* p) {
12 | p->seed.resize(p->count);
13 | p->rng(p->seed.data(), p->count, NULL);
14 | }
15 |
16 | void FormatRandom::process_output(Params* p) {
17 | assert(false); // never happens
18 | }
19 |
--------------------------------------------------------------------------------
/src/format-random.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-random.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format.hpp"
11 |
12 | class FormatRandom : public Format {
13 | public:
14 | FormatRandom() : Format(Format::Key::random, "random") {}
15 |
16 | virtual void process_input(Params* p) override;
17 | virtual void process_output(Params* p) override;
18 | };
19 |
--------------------------------------------------------------------------------
/src/format-sskr.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-sskr.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format-sskr.hpp"
9 |
10 | #include
11 | #include
12 |
13 | #include "params.hpp"
14 | #include "cbor-utils.hpp"
15 | #include
16 |
17 | using namespace std;
18 |
19 | bool FormatSSKR::is_seed_length_valid(size_t seed_len) {
20 | if(!(16 <= seed_len && seed_len <= 32)) { return false; }
21 | if(seed_len % 2 != 0) { return false; }
22 | return true;
23 | }
24 |
25 | static ByteVector combine(StringVector shares) {
26 | vector shares_bytes;
27 | size_t bytes_in_each_share = 0;
28 | for(auto share: shares) {
29 | auto cbor_buf = ur::Bytewords::decode(ur::Bytewords::standard, share);
30 | auto pos = cbor_buf.begin();
31 | auto end = cbor_buf.end();
32 |
33 | ur::CborLite::Tag tag;
34 | size_t value;
35 | ur::CborLite::decodeTagAndValue(pos, end, tag, value, ur::CborLite::Flag::requireMinimalEncoding);
36 | if(tag != ur::CborLite::Major::semantic || value != 309) {
37 | throw runtime_error("Not a valid SSKR share.");
38 | }
39 | ByteVector* bytes_buf = new ByteVector;
40 | ur::CborLite::decodeBytes(pos, end, *bytes_buf, ur::CborLite::Flag::requireMinimalEncoding);
41 | auto bytes_in_share = bytes_buf->size();
42 | if(bytes_in_each_share == 0) {
43 | bytes_in_each_share = bytes_in_share;
44 | } else if(bytes_in_share != bytes_in_each_share) {
45 | throw runtime_error("SSKR shares do not all have equal numbers of words.");
46 | }
47 | shares_bytes.push_back(bytes_buf);
48 | }
49 |
50 | vector shares_bytes_pointers;
51 | for(const auto v: shares_bytes) {
52 | auto p = v->data();
53 | shares_bytes_pointers.push_back(p);
54 | }
55 |
56 | size_t result_len = bytes_in_each_share - METADATA_LENGTH_BYTES;
57 | ByteVector result(result_len) ;
58 |
59 | auto recovered_secret_len = sskr_combine(
60 | shares_bytes_pointers.data(), bytes_in_each_share, shares_bytes_pointers.size(),
61 | result.data(), result.size()
62 | );
63 |
64 | if(recovered_secret_len != result_len) {
65 | throw runtime_error("Invalid SSKR shares.");
66 | }
67 |
68 | for(auto p: shares_bytes) {
69 | delete p;
70 | }
71 |
72 | return result;
73 | }
74 |
75 | void FormatSSKR::process_input(Params* p) {
76 | if(p->is_ur_in) {
77 | for(auto& ur: p->ur_shares) {
78 | auto bw = ur::Bytewords::encode(ur::Bytewords::standard, ur.cbor());
79 | p->shares.push_back(bw);
80 | }
81 | } else {
82 | p->shares = p->get_multiple_arguments();
83 | }
84 | p->seed = combine(p->shares);
85 | }
86 |
87 | void FormatSSKR::process_output(Params* p) {
88 | // If we received a UR in and the input method was also SSKR, the actual
89 | // contained shares have been extracted in process_input() above, so we simply
90 | // output them.
91 | if(p->is_ur_in && !p->shares.empty()) {
92 | p->output = join(p->shares, "\n");
93 | return;
94 | }
95 |
96 | auto seed_len = p->seed.size();
97 | auto share_len = seed_len + METADATA_LENGTH_BYTES;
98 | auto share_count = sskr_count_shards(groups_threshold, groups.data(), groups.size());
99 | auto shares_buffer_len = share_len * share_count;
100 |
101 | if(!is_seed_length_valid(seed_len)) {
102 | throw runtime_error("Invalid seed length for SSKR. Must be in [16-32] and even.");
103 | }
104 |
105 | size_t bytes_in_each_share = 0;
106 | uint8_t shares_buffer[shares_buffer_len];
107 |
108 | int gen_share_count = sskr_generate(
109 | groups_threshold, groups.data(), groups.size(),
110 | p->seed.data(), seed_len,
111 | &bytes_in_each_share, shares_buffer, shares_buffer_len,
112 | NULL,
113 | p->rng
114 | );
115 |
116 | assert(gen_share_count == share_count);
117 | assert(bytes_in_each_share == share_len);
118 |
119 | if(p->is_ur_out) {
120 | StringVector strings;
121 | for (int i = 0; i < share_count; i++) {
122 | uint8_t* bytes = shares_buffer + (i * bytes_in_each_share);
123 | auto v = ByteVector(bytes, bytes + bytes_in_each_share);
124 | ByteVector cbor;
125 | ur::CborLite::encodeTagAndValue(cbor, ur::CborLite::Major::semantic, size_t(309));
126 | ur::CborLite::encodeBytes(cbor, v);
127 | ur::UR ur("crypto-sskr", cbor);
128 | auto s = ur::UREncoder::encode(ur);
129 | strings.push_back(s);
130 | }
131 | auto all_strings = join(strings, "\n");
132 | p->output = all_strings;
133 | } else {
134 | StringVector strings;
135 | for (int i = 0; i < share_count; i++) {
136 | uint8_t* bytes = shares_buffer + (i * bytes_in_each_share);
137 | auto v = ByteVector(bytes, bytes + bytes_in_each_share);
138 | ByteVector cbor;
139 | ur::CborLite::encodeTagAndValue(cbor, ur::CborLite::Major::semantic, size_t(309));
140 | ur::CborLite::encodeBytes(cbor, v);
141 | auto s = ur::Bytewords::encode(ur::Bytewords::standard, cbor);
142 | strings.push_back(s);
143 | }
144 | auto all_strings = join(strings, "\n");
145 | p->output = all_strings;
146 | }
147 | }
148 |
149 | FormatSSKR::FormatSSKR()
150 | : Format(Format::Key::sskr, "sskr"),
151 | groups({{1, 1}}) {
152 | groups_threshold = 1;
153 | }
154 |
--------------------------------------------------------------------------------
/src/format-sskr.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format-sskr.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 | #include
12 |
13 | #include "format.hpp"
14 | #include "utils.hpp"
15 |
16 | class FormatSSKR : public Format {
17 | public:
18 | FormatSSKR();
19 |
20 | virtual void process_input(Params* p) override;
21 | virtual void process_output(Params* p) override;
22 |
23 | static bool is_seed_length_valid(size_t seed_len);
24 |
25 | size_t groups_threshold;
26 | std::vector groups;
27 | };
28 |
--------------------------------------------------------------------------------
/src/format.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // format.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "format.hpp"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | #include "utils.hpp"
15 |
16 | static const std::vector format_key_names = {
17 | "random",
18 | "hex",
19 | "bits",
20 | "cards",
21 | "dice",
22 | "base6",
23 | "base10",
24 | "ints",
25 | "bip39",
26 | "sskr",
27 | "btw",
28 | "btwu",
29 | "btwm"
30 | };
31 |
32 | Format::Key Format::key_for_string(const std::string &arg) {
33 | for(auto i = 0; i < format_key_names.size(); i++) {
34 | if(arg == format_key_names[i]) {
35 | return (Format::Key)i;
36 | }
37 | }
38 |
39 | return Format::Key::unknown;
40 | }
41 |
--------------------------------------------------------------------------------
/src/format.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // format.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 |
12 | class Params;
13 |
14 | class Format {
15 | public:
16 | enum class Key {
17 | unknown = -1,
18 | random,
19 | hex,
20 | bits,
21 | cards,
22 | dice,
23 | base6,
24 | base10,
25 | ints,
26 | bip39,
27 | sskr,
28 | bytewords,
29 | bytewords_uri,
30 | bytewords_minimal
31 | };
32 |
33 | Format(Key key, const std::string &name) : key(key), name(name) {}
34 | virtual ~Format() {}
35 |
36 | Key key;
37 | std::string name;
38 |
39 | virtual void process_input(Params *) = 0;
40 | virtual void process_output(Params *) = 0;
41 |
42 | static Key key_for_string(const std::string &arg);
43 | };
44 |
--------------------------------------------------------------------------------
/src/formats-all.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // formats-all.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include "format-base6.hpp"
11 | #include "format-base10.hpp"
12 | #include "format-bip39.hpp"
13 | #include "format-bits.hpp"
14 | #include "format-cards.hpp"
15 | #include "format-dice.hpp"
16 | #include "format-hex.hpp"
17 | #include "format-ints.hpp"
18 | #include "format-random.hpp"
19 | #include "format-sskr.hpp"
20 | #include "format-bytewords.hpp"
21 | #include "format-bytewords-uri.hpp"
22 | #include "format-bytewords-minimal.hpp"
23 |
24 | bool is_random(const Format* f) { return dynamic_cast(f) != NULL; }
25 | bool is_hex(const Format* f) { return dynamic_cast(f) != NULL; }
26 | bool is_bits(const Format* f) { return dynamic_cast(f) != NULL; }
27 | bool is_cards(const Format* f) { return dynamic_cast(f) != NULL; }
28 | bool is_dice(const Format* f) { return dynamic_cast(f) != NULL; }
29 | bool is_base6(const Format* f) { return dynamic_cast(f) != NULL; }
30 | bool is_base10(const Format* f) { return dynamic_cast(f) != NULL; }
31 | bool is_ints(const Format* f) { return dynamic_cast(f) != NULL; }
32 | bool is_bip39(const Format* f) { return dynamic_cast(f) != NULL; }
33 | bool is_sskr(const Format* f) { return dynamic_cast(f) != NULL; }
34 | bool is_bytewords(const Format* f) { return dynamic_cast(f) != NULL; }
35 | bool is_bytewords_uri(const Format* f) { return dynamic_cast(f) != NULL; }
36 | bool is_bytewords_minimal(const Format* f) { return dynamic_cast(f) != NULL; }
37 | bool is_bytewords_any(const Format* f) { return is_bytewords(f) || is_bytewords_uri(f) || is_bytewords_minimal(f); }
38 |
--------------------------------------------------------------------------------
/src/hkdf.c:
--------------------------------------------------------------------------------
1 | // Permission is hereby granted, free of charge, to any person obtaining a copy
2 | // of this software and associated documentation files (the "Software"), to deal
3 | // in the Software without restriction, including without limitation the rights
4 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5 | // copies of the Software, and to permit persons to whom the Software is
6 | // furnished to do so, subject to the following conditions:
7 |
8 | // The above copyright notice and this permission notice shall be included in
9 | // all copies or substantial portions of the Software.
10 |
11 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17 | // THE SOFTWARE.
18 |
19 | #include "hkdf.h"
20 |
21 | #include
22 |
23 | #include
24 | #include
25 |
26 | void hkdf_sha256(uint8_t *okm, size_t okm_size,
27 | const uint8_t *s, size_t ssize,
28 | const uint8_t *k, size_t ksize,
29 | const uint8_t *info, size_t isize)
30 | {
31 | uint8_t prk[SHA256_DIGEST_LENGTH];
32 | uint8_t t[SHA256_DIGEST_LENGTH];
33 | HMAC_SHA256_CTX ctx;
34 | unsigned char c;
35 |
36 | assert(okm_size < 255 * sizeof(t));
37 |
38 | /* RFC 5869:
39 | *
40 | * 2.2. Step 1: Extract
41 | *
42 | * HKDF-Extract(salt, IKM) -> PRK
43 | *
44 | * Options:
45 | * Hash a hash function; HashLen denotes the length of the
46 | * hash function output in octets
47 | *
48 | * Inputs:
49 | * salt optional salt value (a non-secret random value);
50 | * if not provided, it is set to a string of HashLen zeros.
51 | * IKM input keying material
52 | *
53 | * Output:
54 | * PRK a pseudorandom key (of HashLen octets)
55 | *
56 | * The output PRK is calculated as follows:
57 | *
58 | * PRK = HMAC-Hash(salt, IKM)
59 | */
60 | if(s == NULL || ssize == 0) {
61 | uint8_t a[SHA256_DIGEST_LENGTH];
62 | memset(a, 0, SHA256_DIGEST_LENGTH);
63 | hmac_sha256(a, SHA256_DIGEST_LENGTH, k, ksize, prk);
64 | } else {
65 | hmac_sha256(s, ssize, k, ksize, prk);
66 | }
67 |
68 | /*
69 | * 2.3. Step 2: Expand
70 | *
71 | * HKDF-Expand(PRK, info, L) -> OKM
72 | *
73 | * Options:
74 | * Hash a hash function; HashLen denotes the length of the
75 | * hash function output in octets
76 | *
77 | * Inputs:
78 | * PRK a pseudorandom key of at least HashLen octets
79 | * (usually, the output from the extract step)
80 | * info optional context and application specific information
81 | * (can be a zero-length string)
82 | * L length of output keying material in octets
83 | * (<= 255*HashLen)
84 | *
85 | * Output:
86 | * OKM output keying material (of L octets)
87 | *
88 | * The output OKM is calculated as follows:
89 | *
90 | * N = ceil(L/HashLen)
91 | * T = T(1) | T(2) | T(3) | ... | T(N)
92 | * OKM = first L octets of T
93 | *
94 | * where:
95 | * T(0) = empty string (zero length)
96 | * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
97 | * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
98 | * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
99 | * ...
100 | *
101 | * (where the constant concatenated to the end of each T(n) is a
102 | * single octet.)
103 | */
104 | c = 1;
105 | hmac_sha256_Init(&ctx, prk, sizeof(prk));
106 | hmac_sha256_Update(&ctx, info, isize);
107 | hmac_sha256_Update(&ctx, &c, 1);
108 | hmac_sha256_Final(&ctx, t);
109 |
110 | while (okm_size > sizeof(t)) {
111 | memcpy(okm, &t, sizeof(t));
112 | okm = okm + sizeof(t);
113 | okm_size -= sizeof(t);
114 |
115 | c++;
116 | hmac_sha256_Init(&ctx, prk, sizeof(prk));
117 | hmac_sha256_Update(&ctx, t, sizeof(t));
118 | hmac_sha256_Update(&ctx, info, isize);
119 | hmac_sha256_Update(&ctx, &c, 1);
120 | hmac_sha256_Final(&ctx, t);
121 | }
122 | memcpy(okm, &t, okm_size);
123 | }
--------------------------------------------------------------------------------
/src/hkdf.h:
--------------------------------------------------------------------------------
1 | #ifndef CCAN_CRYPTO_HKDF_SHA256_H
2 | #define CCAN_CRYPTO_HKDF_SHA256_H
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 |
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 |
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | #include
27 | #include
28 |
29 | /**
30 | * hkdf_sha256 - generate a derived key
31 | * @okm: where to output the key
32 | * @okm_size: the number of bytes pointed to by @okm (must be less than 255*32)
33 | * @s: salt
34 | * @ssize: the number of bytes pointed to by @s
35 | * @k: pointer to input key
36 | * @ksize: the number of bytes pointed to by @k
37 | * @info: pointer to info
38 | * @isize: the number of bytes pointed to by @info
39 | */
40 | void hkdf_sha256(uint8_t *okm, size_t okm_size,
41 | const uint8_t *s, size_t ssize,
42 | const uint8_t *k, size_t ksize,
43 | const uint8_t *info, size_t isize);
44 |
45 | #ifdef __cplusplus
46 | }
47 | #endif
48 |
49 | #endif /* CCAN_CRYPTO_HKDF_SHA256_H */
50 |
--------------------------------------------------------------------------------
/src/params.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // params.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "random.hpp"
19 | #include "utils.hpp"
20 |
21 | #define MAX_GROUPS 16
22 | #define MAX_RAW_GROUPS (MAX_GROUPS + 1)
23 |
24 | #define MAX_ARGS 256
25 |
26 | class RawParams {
27 | public:
28 | RawParams() { }
29 |
30 | std::string input_format;
31 | std::string output_format;
32 | std::string count;
33 |
34 | std::string ints_low;
35 | std::string ints_high;
36 |
37 | std::string random_deterministic;
38 | bool is_ur = false;
39 | std::string max_fragment_length;
40 | std::string fountain_parts;
41 |
42 | std::string sskr_groups_threshold;
43 | StringVector sskr_groups;
44 |
45 | StringVector args;
46 | };
47 |
48 | class Format;
49 |
50 | class Params {
51 | public:
52 | Params() { }
53 | ~Params();
54 |
55 | Format* input_format = NULL;
56 | Format* output_format = NULL;
57 |
58 | bool is_ur_out = false;
59 | bool is_ur_in = false;
60 | std::vector ur_shares;
61 | size_t max_fragment_length = 0;
62 | std::optional fountain_parts;
63 |
64 | StringVector shares;
65 |
66 | StringVector input;
67 | std::string output;
68 |
69 | ByteVector seed;
70 |
71 | size_t count = 0;
72 |
73 | char* deterministic_seed = NULL;
74 | random_generator rng = NULL;
75 |
76 | void validate();
77 |
78 | RawParams raw;
79 |
80 | struct argp_state* state = nullptr;
81 |
82 | static Params* parse( int argc, char *argv[] );
83 | void read_args_from_stdin();
84 |
85 | std::string get_one_argument();
86 | std::string get_combined_arguments();
87 | StringVector get_multiple_arguments();
88 |
89 | void set_ur_output(const ByteVector& cbor, const std::string& type);
90 |
91 | private:
92 | sskr_group_descriptor parse_group_spec(const std::string &string);
93 |
94 | void validate_count();
95 | void validate_deterministic();
96 | void validate_input_format();
97 | void validate_count_for_input_format();
98 | void validate_output_format();
99 | void validate_output_for_input();
100 | void validate_ints_specific();
101 | void validate_bip39_specific();
102 | void validate_sskr_specific();
103 | void validate_input();
104 | void validate_ur();
105 | };
106 |
--------------------------------------------------------------------------------
/src/random.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // random.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 |
15 | #include "random.hpp"
16 | #include "randombytes.h"
17 | #include "hkdf.h"
18 |
19 | using namespace std;
20 |
21 | void crypto_random(uint8_t* buf, size_t n, void* ctx) {
22 | assert(randombytes(buf, n) == 0);
23 | }
24 |
25 | static uint8_t deterministic_seed[SHA256_DIGEST_LENGTH];
26 | static uint64_t deterministic_salt = 0;
27 |
28 | void seed_deterministic_string(const string &string) {
29 | sha256_Raw((uint8_t*)string.c_str(), string.length(), deterministic_seed);
30 | deterministic_salt = 0;
31 | }
32 |
33 | void deterministic_random(uint8_t* buf, size_t n, void* ctx) {
34 | deterministic_salt += 1;
35 |
36 | hkdf_sha256(buf, n,
37 | (uint8_t*)&deterministic_salt, sizeof(deterministic_salt),
38 | deterministic_seed, SHA256_DIGEST_LENGTH,
39 | NULL, 0);
40 | }
41 |
42 | ByteVector deterministic_random(const ByteVector &entropy, size_t n) {
43 | ByteVector result;
44 | result.resize(n);
45 |
46 | auto seed = sha256(entropy);
47 |
48 | hkdf_sha256(result.data(), n,
49 | NULL, 0, // no salt
50 | seed.data(), SHA256_DIGEST_LENGTH,
51 | NULL, 0); // no info
52 |
53 | return result;
54 | }
55 |
56 | ByteVector sha256_deterministic_random(const ByteVector &entropy, size_t n) {
57 | auto seed = sha256(entropy);
58 | if(n <= seed.size()) {
59 | return take(seed, n);
60 | } else {
61 | throw runtime_error("Random number generator limits reached.");
62 | }
63 | }
64 |
65 | ByteVector sha256_deterministic_random(const string &string, size_t n) {
66 | ByteVector entropy;
67 | std::copy(string.begin(), string.end(), back_inserter(entropy));
68 | return sha256_deterministic_random(entropy, n);
69 | }
70 |
--------------------------------------------------------------------------------
/src/random.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // random.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include "utils.hpp"
15 |
16 | typedef void (*random_generator)(uint8_t*, size_t, void*);
17 |
18 | // Generates a buffer of random bytes using the OS's cryptographically strong random number generator.
19 | void crypto_random(uint8_t* buf, size_t n, void* ctx);
20 |
21 | // Seeds the cryptographically strong deterministic random number generator with the SHA256 digest of the string.
22 | void seed_deterministic_string(const std::string &string);
23 |
24 | // Generates a buffer of random bytes using the cryptographically strong deterministic random number generator.
25 | void deterministic_random(uint8_t* buf, size_t n, void* ctx);
26 |
27 | ByteVector deterministic_random(const ByteVector &entropy, size_t n);
28 |
29 | ByteVector sha256_deterministic_random(const ByteVector &entropy, size_t n);
30 | ByteVector sha256_deterministic_random(const std::string &string, size_t n);
31 |
--------------------------------------------------------------------------------
/src/randombytes.c:
--------------------------------------------------------------------------------
1 | // The MIT License
2 | //
3 | // Copyright (c) 2017 Daan Sprenkels
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | // In the case that are compiling on linux, we need to define _GNU_SOURCE
24 | // *before* randombytes.h is included. Otherwise SYS_getrandom will not be
25 | // declared.
26 | #if defined(__linux__)
27 | # define _GNU_SOURCE
28 | #endif /* defined(__linux__) */
29 |
30 | #include "randombytes.h"
31 |
32 | #if defined(_WIN32)
33 | /* Windows */
34 | # include
35 | # include /* CryptAcquireContext, CryptGenRandom */
36 | #endif /* defined(_WIN32) */
37 |
38 |
39 | #if defined(__linux__)
40 | /* Linux */
41 | // We would need to include , but not every target has access
42 | // to the linux headers. We only need RNDGETENTCNT, so we instead inline it.
43 | // RNDGETENTCNT is originally defined in `include/uapi/linux/random.h` in the
44 | // linux repo.
45 | # define RNDGETENTCNT 0x80045200
46 |
47 | # include
48 | # include
49 | # include
50 | # include
51 | # include
52 | # include
53 | # include
54 | # include
55 | # include
56 | # include
57 | # include
58 |
59 | // We need SSIZE_MAX as the maximum read len from /dev/urandom
60 | # if !defined(SSIZE_MAX)
61 | # define SSIZE_MAX (SIZE_MAX / 2 - 1)
62 | # endif /* defined(SSIZE_MAX) */
63 |
64 | #endif /* defined(__linux__) */
65 |
66 |
67 | #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
68 | /* Dragonfly, FreeBSD, NetBSD, OpenBSD (has arc4random) */
69 | # include
70 | # if defined(BSD)
71 | # include
72 | # endif
73 | #endif
74 |
75 | #if defined(__EMSCRIPTEN__)
76 | # include
77 | # include
78 | # include
79 | # include
80 | #endif /* defined(__EMSCRIPTEN__) */
81 |
82 |
83 | #if defined(_WIN32)
84 | static int randombytes_win32_randombytes(void* buf, const size_t n)
85 | {
86 | HCRYPTPROV ctx;
87 | BOOL tmp;
88 |
89 | tmp = CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL,
90 | CRYPT_VERIFYCONTEXT);
91 | if (tmp == FALSE) return -1;
92 |
93 | tmp = CryptGenRandom(ctx, n, (BYTE*) buf);
94 | if (tmp == FALSE) return -1;
95 |
96 | tmp = CryptReleaseContext(ctx, 0);
97 | if (tmp == FALSE) return -1;
98 |
99 | return 0;
100 | }
101 | #endif /* defined(_WIN32) */
102 |
103 |
104 | #if defined(__linux__) && defined(SYS_getrandom)
105 | static int randombytes_linux_randombytes_getrandom(void *buf, size_t n)
106 | {
107 | /* I have thought about using a separate PRF, seeded by getrandom, but
108 | * it turns out that the performance of getrandom is good enough
109 | * (250 MB/s on my laptop).
110 | */
111 | size_t offset = 0, chunk;
112 | int ret;
113 | while (n > 0) {
114 | /* getrandom does not allow chunks larger than 33554431 */
115 | chunk = n <= 33554431 ? n : 33554431;
116 | do {
117 | ret = syscall(SYS_getrandom, (char *)buf + offset, chunk, 0);
118 | } while (ret == -1 && errno == EINTR);
119 | if (ret < 0) return ret;
120 | offset += ret;
121 | n -= ret;
122 | }
123 | assert(n == 0);
124 | return 0;
125 | }
126 | #endif /* defined(__linux__) && defined(SYS_getrandom) */
127 |
128 |
129 | #if defined(__linux__) && !defined(SYS_getrandom)
130 | static int randombytes_linux_read_entropy_ioctl(int device, int *entropy)
131 | {
132 | return ioctl(device, RNDGETENTCNT, entropy);
133 | }
134 |
135 | static int randombytes_linux_read_entropy_proc(FILE *stream, int *entropy)
136 | {
137 | int retcode;
138 | do {
139 | rewind(stream);
140 | retcode = fscanf(stream, "%d", entropy);
141 | } while (retcode != 1 && errno == EINTR);
142 | if (retcode != 1) {
143 | return -1;
144 | }
145 | return 0;
146 | }
147 |
148 | static int randombytes_linux_wait_for_entropy(int device)
149 | {
150 | /* We will block on /dev/random, because any increase in the OS' entropy
151 | * level will unblock the request. I use poll here (as does libsodium),
152 | * because we don't *actually* want to read from the device. */
153 | enum { IOCTL, PROC } strategy = IOCTL;
154 | const int bits = 128;
155 | struct pollfd pfd;
156 | int fd;
157 | FILE *proc_file;
158 | int retcode, retcode_error = 0; // Used as return codes throughout this function
159 | int entropy = 0;
160 |
161 | /* If the device has enough entropy already, we will want to return early */
162 | retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
163 | // printf("errno: %d (%s)\n", errno, strerror(errno));
164 | if (retcode != 0 && (errno == ENOTTY || errno == ENOSYS)) {
165 | // The ioctl call on /dev/urandom has failed due to a
166 | // - ENOTTY (unsupported action), or
167 | // - ENOSYS (invalid ioctl; this happens on MIPS, see #22).
168 | //
169 | // We will fall back to reading from
170 | // `/proc/sys/kernel/random/entropy_avail`. This less ideal,
171 | // because it allocates a file descriptor, and it may not work
172 | // in a chroot. But at this point it seems we have no better
173 | // options left.
174 | strategy = PROC;
175 | // Open the entropy count file
176 | proc_file = fopen("/proc/sys/kernel/random/entropy_avail", "r");
177 | } else if (retcode != 0) {
178 | // Unrecoverable ioctl error
179 | return -1;
180 | }
181 | if (entropy >= bits) {
182 | return 0;
183 | }
184 |
185 | do {
186 | fd = open("/dev/random", O_RDONLY);
187 | } while (fd == -1 && errno == EINTR); /* EAGAIN will not occur */
188 | if (fd == -1) {
189 | /* Unrecoverable IO error */
190 | return -1;
191 | }
192 |
193 | pfd.fd = fd;
194 | pfd.events = POLLIN;
195 | for (;;) {
196 | retcode = poll(&pfd, 1, -1);
197 | if (retcode == -1 && (errno == EINTR || errno == EAGAIN)) {
198 | continue;
199 | } else if (retcode == 1) {
200 | if (strategy == IOCTL) {
201 | retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
202 | } else if (strategy == PROC) {
203 | retcode = randombytes_linux_read_entropy_proc(proc_file, &entropy);
204 | } else {
205 | return -1; // Unreachable
206 | }
207 |
208 | if (retcode != 0) {
209 | // Unrecoverable I/O error
210 | retcode_error = retcode;
211 | break;
212 | }
213 | if (entropy >= bits) {
214 | break;
215 | }
216 | } else {
217 | // Unreachable: poll() should only return -1 or 1
218 | retcode_error = -1;
219 | break;
220 | }
221 | }
222 | do {
223 | retcode = close(fd);
224 | } while (retcode == -1 && errno == EINTR);
225 | if (strategy == PROC) {
226 | do {
227 | retcode = fclose(proc_file);
228 | } while (retcode == -1 && errno == EINTR);
229 | }
230 | if (retcode_error != 0) {
231 | return retcode_error;
232 | }
233 | return retcode;
234 | }
235 |
236 |
237 | static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
238 | {
239 | int fd;
240 | size_t offset = 0;
241 | do {
242 | fd = open("/dev/urandom", O_RDONLY);
243 | } while (fd == -1 && errno == EINTR);
244 | if (fd == -1) return -1;
245 | if (randombytes_linux_wait_for_entropy(fd) == -1) return -1;
246 |
247 | while (n > 0) {
248 | size_t count = n <= SSIZE_MAX ? n : SSIZE_MAX;
249 | ssize_t tmp = read(fd, (char *)buf + offset, count);
250 | if (tmp == -1 && (errno == EAGAIN || errno == EINTR)) {
251 | continue;
252 | }
253 | if (tmp == -1) return -1; /* Unrecoverable IO error */
254 | offset += tmp;
255 | n -= tmp;
256 | }
257 | assert(n == 0);
258 | return 0;
259 | }
260 | #endif /* defined(__linux__) && !defined(SYS_getrandom) */
261 |
262 |
263 | #if defined(BSD)
264 | static int randombytes_bsd_randombytes(void *buf, size_t n)
265 | {
266 | arc4random_buf(buf, n);
267 | return 0;
268 | }
269 | #endif /* defined(BSD) */
270 |
271 |
272 | #if defined(__EMSCRIPTEN__)
273 | static int randombytes_js_randombytes_nodejs(void *buf, size_t n) {
274 | const int ret = EM_ASM_INT({
275 | var crypto;
276 | try {
277 | crypto = require('crypto');
278 | } catch (error) {
279 | return -2;
280 | }
281 | try {
282 | writeArrayToMemory(crypto.randomBytes($1), $0);
283 | return 0;
284 | } catch (error) {
285 | return -1;
286 | }
287 | }, buf, n);
288 | switch (ret) {
289 | case 0:
290 | return 0;
291 | case -1:
292 | errno = EINVAL;
293 | return -1;
294 | case -2:
295 | errno = ENOSYS;
296 | return -1;
297 | }
298 | assert(false); // Unreachable
299 | }
300 | #endif /* defined(__EMSCRIPTEN__) */
301 |
302 |
303 | int randombytes(void *buf, size_t n)
304 | {
305 | #if defined(__EMSCRIPTEN__)
306 | //# pragma message("Using crypto api from NodeJS")
307 | return randombytes_js_randombytes_nodejs(buf, n);
308 | #elif defined(__linux__)
309 | # if defined(SYS_getrandom)
310 | //# pragma message("Using getrandom system call")
311 | /* Use getrandom system call */
312 | return randombytes_linux_randombytes_getrandom(buf, n);
313 | # else
314 | //# pragma message("Using /dev/urandom device")
315 | /* When we have enough entropy, we can read from /dev/urandom */
316 | return randombytes_linux_randombytes_urandom(buf, n);
317 | # endif
318 | #elif defined(BSD)
319 | //# pragma message("Using arc4random system call")
320 | /* Use arc4random system call */
321 | return randombytes_bsd_randombytes(buf, n);
322 | #elif defined(_WIN32)
323 | //# pragma message("Using Windows cryptographic API")
324 | /* Use windows API */
325 | return randombytes_win32_randombytes(buf, n);
326 | #else
327 | # error "randombytes(...) is not supported on this platform"
328 | #endif
329 | }
330 |
--------------------------------------------------------------------------------
/src/randombytes.h:
--------------------------------------------------------------------------------
1 | // The MIT License
2 | //
3 | // Copyright (c) 2017 Daan Sprenkels
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef sss_RANDOMBYTES_H
24 | #define sss_RANDOMBYTES_H
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 | #ifdef _WIN32
31 | /* Load size_t on windows */
32 | #include
33 | #else
34 | #include
35 | #endif /* _WIN32 */
36 |
37 |
38 | /*
39 | * Write `n` bytes of high quality random bytes to `buf`
40 | */
41 | int randombytes(void *buf, size_t n);
42 |
43 | #ifdef __cplusplus
44 | }
45 | #endif
46 |
47 | #endif /* sss_RANDOMBYTES_H */
48 |
--------------------------------------------------------------------------------
/src/seedtool.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // seedtool.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include
9 | #include
10 |
11 | #include "params.hpp"
12 | #include "format.hpp"
13 |
14 | using namespace std;
15 |
16 | int main( int argc, char *argv[] ) {
17 | auto p = Params::parse(argc, argv);
18 |
19 | try {
20 | p->input_format->process_input(p);
21 | p->output_format->process_output(p);
22 |
23 | if(p->output.empty()) {
24 | throw runtime_error("An internal error occurred.");
25 | }
26 |
27 | cout << p->output << endl;
28 |
29 | } catch(exception &e) {
30 | cerr << argv[0] << ": " << e.what() << endl;
31 | exit(1);
32 | }
33 |
34 | delete p;
35 | return 0;
36 | }
37 |
--------------------------------------------------------------------------------
/src/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Echo any provided arguments.
4 | # [ $# -gt 0 ] && echo "#:$# 1:$1 2:$2 3:$3"
5 |
6 | SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
7 | SEEDTOOL="${1:-${SCRIPT_DIR}/seedtool} --deterministic TEST"
8 | SHUNIT2="${SCRIPT_DIR}/../deps/shunit2/shunit2"
9 |
10 | testDefault()
11 | {
12 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d824' \
13 | "$(${SEEDTOOL})"
14 | }
15 |
16 | testRedundantDefault()
17 | {
18 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d824' \
19 | "$(${SEEDTOOL} --in random --out hex)"
20 | }
21 |
22 | testOutBTW()
23 | {
24 | assertEquals $'next edge lamb liar city girl draw visa roof logo jolt city waxy jury trip dark loud duty obey monk' \
25 | "$(${SEEDTOOL} --out btw)"
26 | }
27 |
28 | testInBTW()
29 | {
30 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d824' \
31 | "$(${SEEDTOOL} --in btw 'next edge lamb liar city girl draw visa roof logo jolt city waxy jury trip dark loud duty obey monk')"
32 | }
33 |
34 | testOutBTWU()
35 | {
36 | assertEquals $'deli-need-cats-taxi-dice-door-webs-vows-free-zero-legs-wall-half-waxy-trip-oval-memo-sets-rock-hill' \
37 | "$(${SEEDTOOL} --in hex --out btwu 279b18d0282aefe845fb83e956eed8a6)"
38 | }
39 |
40 | testOutBTWM()
41 | {
42 | assertEquals $'dindcstidedrwsvsfezolswlhfwytpolmossrkhl' \
43 | "$(${SEEDTOOL} --in hex --out btwm 279b18d0282aefe845fb83e956eed8a6)"
44 | }
45 |
46 | testOutBits()
47 | {
48 | assertEquals $'1001000111001010' \
49 | "$(${SEEDTOOL} --out bits)"
50 | }
51 |
52 | testOutCards()
53 | {
54 | assertEquals $'6hjckdah6c4dtc8skh2htd6ctsjd5s8c' \
55 | "$(${SEEDTOOL} --out cards)"
56 | }
57 |
58 | testOutDice()
59 | {
60 | assertEquals $'4234232654326352' \
61 | "$(${SEEDTOOL} --out dice)"
62 | }
63 |
64 | testOutBase6()
65 | {
66 | assertEquals $'3123121543215241' \
67 | "$(${SEEDTOOL} --out base6)"
68 | }
69 |
70 | testOutBase10()
71 | {
72 | assertEquals $'6245132875418481' \
73 | "$(${SEEDTOOL} --out base10)"
74 | }
75 |
76 | testOut5Cards()
77 | {
78 | assertEquals $'6hjckdah6c' \
79 | "$(${SEEDTOOL} --out cards --count 5)"
80 | }
81 |
82 | testOutInts()
83 | {
84 | assertEquals $'6 2 4 5 1 3 2 8 7 5 4 1 8 4 8 1' \
85 | "$(${SEEDTOOL} --out ints)"
86 | }
87 |
88 | testOutIntsRange()
89 | {
90 | assertEquals $'62 21 50 52 11 31 18 90' \
91 | "$(${SEEDTOOL} --out ints --count 8 --low 1 --high 100)"
92 | }
93 |
94 | testOutBIP39()
95 | {
96 | assertEquals $'outdoor physical three cruel tissue infant vendor assist brain inhale current emotion' \
97 | "$(${SEEDTOOL} --out bip39)"
98 | }
99 |
100 | testOutBIP39Count32()
101 | {
102 | assertEquals $'outdoor physical three cruel tissue infant vendor assist brain inhale current embrace clinic knife mystery metal horror item twice assault wedding marble song buyer' \
103 | "$(${SEEDTOOL} --out bip39 --count 32)"
104 | }
105 |
106 | testOutSSKR()
107 | {
108 | assertEquals $'tuna acid epic gyro many meow able able able next edge lamb liar city girl draw visa roof logo jolt city waxy jury trip dark safe arch flew what' \
109 | "$(${SEEDTOOL} --out sskr)"
110 | }
111 |
112 | testOutSSKRCount32()
113 | {
114 | assertEquals $'tuna acid epic hard data many meow able able able next edge lamb liar city girl draw visa roof logo jolt city waxy jury trip dark flew purr yell idle news horn join pool ugly poem atom task many bias junk soap yoga idea yell work' \
115 | "$(${SEEDTOOL} --out sskr --count 32)"
116 | }
117 |
118 | testOutSSKRGroup2Of3()
119 | {
120 | assertEquals $'tuna acid epic gyro many meow able acid able mild fern pool door purr calm trip cyan flew zest cats tuna omit figs bias acid aunt keys play frog
121 | tuna acid epic gyro many meow able acid acid keep undo peck poem kiwi jazz cola luck hope rock into film jolt lava flux rust gala sets ruin toil
122 | tuna acid epic gyro many meow able acid also girl void oval fish exam veto gala inky keys jump visa barn cusp high miss monk jazz numb dice foxy' \
123 | "$(${SEEDTOOL} --out sskr --group 2-of-3)"
124 | }
125 |
126 | testOutSSKR3Groups()
127 | {
128 | assertEquals $'tuna acid epic gyro many meow brag acid able noon diet race hope glow junk kept oval jump hope heat keys high barn hang into next miss logo oval
129 | tuna acid epic gyro many meow brag acid acid heat noon peck aqua keno wolf wasp fund aqua gush cyan gear hill inky drop scar buzz city toys mild
130 | tuna acid epic gyro many meow brag acid also belt high luau wall figs iris heat huts noon gala paid cook holy trip omit edge miss cats keep runs
131 | tuna acid epic gyro many meow brag brag able kiwi pool yell user math girl figs gift free part when liar kiln view iced buzz keep eyes taxi wolf
132 | tuna acid epic gyro many meow brag brag acid surf miss barn kick surf miss lamb calm miss dark song kite fuel real hill mint apex dull runs unit
133 | tuna acid epic gyro many meow brag brag also skew love quad dull iced join each curl numb data aqua wand vows owls idea cash keep echo keys math
134 | tuna acid epic gyro many meow brag brag apex kept quad fund loud film quiz junk kiln jump paid fish brag toil yank high meow apex data cash ruin
135 | tuna acid epic gyro many meow brag brag aqua epic open wave main high calm echo taxi void paid fact kiln soap tiny list join kiln rust blue flap
136 | tuna acid epic gyro many meow brag cusp able legs acid keep menu film yell very lava undo flew curl wolf soap chef idle fuel king runs trip urge
137 | tuna acid epic gyro many meow brag cusp acid puff kiwi crux soap rock toys bulb hill jade beta jade zinc loud void junk kiln soap draw edge pose
138 | tuna acid epic gyro many meow brag cusp also heat apex plus mild glow saga lava yoga user game diet mild gyro limp puma down echo quiz user oboe
139 | tuna acid epic gyro many meow brag cusp apex iron lamb yurt taco song veto keep data iris atom idea need bulb king oval calm lava deli echo time
140 | tuna acid epic gyro many meow brag cusp aqua vast rust bald iron fuel grim gyro eyes chef dark kept surf mild swan bulb slot draw kick zero onyx' \
141 | "$(${SEEDTOOL} --out sskr --group-threshold 2 --group 2-of-3 --group 3-of-5 --group 3-of-5)"
142 | }
143 |
144 | testInBits()
145 | {
146 | assertEquals $'8d933e43b1bc8f2e3fc27adc98ad4534' \
147 | "$(${SEEDTOOL} --in bits 1110110001110111)"
148 | }
149 |
150 | testInCards()
151 | {
152 | assertEquals $'7df301924511326d7350be14c9e7176d' \
153 | "$(${SEEDTOOL} --in cards 6c9s8c7c9c4cah6c2sjs7d5c2s4c4dqs)"
154 | }
155 |
156 | testInCardsCount32()
157 | {
158 | assertEquals $'7df301924511326d7350be14c9e7176d98e945f9ad0ed034726ad4ee0de59c25' \
159 | "$(${SEEDTOOL} --count 32 --in cards 6c9s8c7c9c4cah6c2sjs7d5c2s4c4dqs)"
160 | }
161 |
162 | testInDice()
163 | {
164 | assertEquals $'77ae0de807d60367311eb040c70690d2' \
165 | "$(${SEEDTOOL} --in dice 3343462611234633)"
166 | }
167 |
168 | testInBase6()
169 | {
170 | assertEquals $'51621269b3a91fe6482ceb7779f0d1d1' \
171 | "$(${SEEDTOOL} --in base6 3242235101442242)"
172 | }
173 |
174 | testInBase10()
175 | {
176 | assertEquals $'a0ca21e20db54b4df7479737c145f6db' \
177 | "$(${SEEDTOOL} --in base10 3190125)"
178 | }
179 |
180 | testInInts()
181 | {
182 | assertEquals $'a38385ba7a67b7f5882b37f75b43c2df' \
183 | "$(${SEEDTOOL} --in ints 71 22 95 6 23 65 27 10 67 16)"
184 | }
185 |
186 | testDicePipe()
187 | {
188 | assertEquals $'eefa19b88c5846e71fcb52d007066ae4a2bd0be166e12c8de95c8e71a712c581' \
189 | "$(${SEEDTOOL} --out dice | ${SEEDTOOL} --in dice --count 32)"
190 | }
191 |
192 | testInBIP39OutBTW()
193 | {
194 | assertEquals $'love exam mint dark bias item mint atom open kept soap list whiz view soap fact jugs obey idle jugs' \
195 | "$(${SEEDTOOL} --in bip39 --out btw mechanic royal math burst practice addict noise weekend margin now improve invest)"
196 | }
197 |
198 | testInSSKR()
199 | {
200 | assertEquals $'82f188b091c38fced97bb45732bddf7e' \
201 | "$(${SEEDTOOL} --in sskr 'tuna acid epic gyro edge next able able able leaf when logo puff maze scar many taco tuna king quiz hang easy ruby user knob omit time chef slot')"
202 | }
203 |
204 | testInSSKR2Of3()
205 | {
206 | assertEquals $'2c4b163bfe9b791dbc0e755b911d01f6' \
207 | "$(${SEEDTOOL} --in sskr \
208 | 'tuna acid epic gyro edge next able acid able flux down eyes pool task cyan gyro kept exit paid wave high news bias zone zaps calm note poem aqua' \
209 | 'tuna acid epic gyro edge next able acid also wolf vows bald sets claw bald dull cost slot inky liar work note tied zest safe crux kiln work exit')"
210 | }
211 |
212 | testOutUR()
213 | {
214 | # seedtool --deterministic TEST --ur
215 | assertEquals $'ur:seed/oyadgdnteelblrcygldwvarflojtcywyjytpdkjspafltb' \
216 | "$(${SEEDTOOL} --ur)"
217 | }
218 |
219 | testInUR()
220 | {
221 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d824' \
222 | "$(${SEEDTOOL} --in ur ur:seed/oyadgdnteelblrcygldwvarflojtcywyjytpdkjspafltb)"
223 | }
224 |
225 | testOutMultipartUR()
226 | {
227 | assertEquals $'ur:seed/1-5/lpadahcfadmdcyknoxqdgohdgyoyadhkadmhnteelblrcygldwvarflojtcywyjytpdkfwprylienshnjnpluypmamtkmybsjkspvseesawmrltdlnlgkplfbkqzzoglfeoyaegsnedtrowsdpgtimmwzspfqdjkhshyfrylenpdnnnswmbeheclaszoyknbvavs
228 | ur:seed/2-5/lpaoahcfadmdcyknoxqdgohdgygmdstpoennbtflwykbtpktgwcxdkhtskwkkgmdmdlubblstnoxpkpysotntbcmotbdwfetqzwsckmscadwssgarysfeomohdytfhlbmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnsdeesecrd
229 | ur:seed/3-5/lpaxahcfadmdcyknoxqdgohdgypscsutkkiyfzeyvtyajlvlsewnhkjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatkspriymotofgcemhguskgeflfyfspliorntefgdkykpswzwyrydwlamdft
230 | ur:seed/4-5/lpaaahcfadmdcyknoxqdgohdgywtpfvwdeecahtdhhvalrnynbtiwnbdctuesabtmnecvapratdwlbvltpgsglmdbnmknebkkscymofpkteyvoatjlqdaovesffhylgdimamcyadctgstymddlynpefppfemlkntknghveglrypslaahtblyvdspolptcpaxrpgs
231 | ur:seed/5-5/lpahahcfadmdcyknoxqdgohdgypkflsfmdfxjydpioihltbnwppfhtielguthtwdpdihaykgoyclentldykkmnvedsbwuyeojejennbkrtkevotacppyjsvdgohtvewenyneylfekihgcplpgljoisgwverkmokgldyavseojehncfvakgehcmrojlwezmdnkkwe' \
232 | "$(${SEEDTOOL} --count 400 --ur=100)"
233 | }
234 |
235 | testInMultipartUR()
236 | {
237 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d82442b2f7649c606daedbad06cf8f0f73c8e834c2ebb7d2868d75820ab4fb4e45a1004c9f29b8ef2d4d6a94fab0b373615e3bf736a89e9ceb105f2109fb5226d8a29e0d47ee7ed8774f20245ac5f47b95958b1483daa4aaabc9dad616a30bf338b4ef1e971d2cc449bdcc339258f93f7f91a3d067522b085ca6b2f7c72732ce5aed7ae0ef273f13c8d92ffa89b69cac18dd79664032e0f86fe3c1f1596fd2dc582c690f17407d0852932d23798056a424cacae3bfd4e30fe8030f943645fcdf4d86de1b45570778b26692ce461c9053c54a47443dae67bed34624f5acf2eebdf0b0e5283505d25ce6849aa0d0f10b1fdec20d8e35e6b2072c7fe3d84c4e950c989f0a781a92417732e2076fb302e4cc3ff7506a061a011f4cd4952ff6af41b0378c9d7a54e44ebdac8005d681e7c8a6a9aa47cc9543742d6765870cecb05a648ddd5aeaa865087ba12136d530798ee42613db336b6b9e0ac07ce2d922ab71e7555ae4ed9a9ff7457d5722854e70684fe4bb927b89f8e8336b6019e67b3116b86fed' \
238 | "$(${SEEDTOOL} --in ur 'ur:seed/1-5/lpadahcfadmdcyknoxqdgohdgyoyadhkadmhnteelblrcygldwvarflojtcywyjytpdkfwprylienshnjnpluypmamtkmybsjkspvseesawmrltdlnlgkplfbkqzzoglfeoyaegsnedtrowsdpgtimmwzspfqdjkhshyfrylenpdnnnswmbeheclaszoyknbvavs' \
239 | 'ur:seed/2-5/lpaoahcfadmdcyknoxqdgohdgygmdstpoennbtflwykbtpktgwcxdkhtskwkkgmdmdlubblstnoxpkpysotntbcmotbdwfetqzwsckmscadwssgarysfeomohdytfhlbmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnsdeesecrd' \
240 | 'ur:seed/3-5/lpaxahcfadmdcyknoxqdgohdgypscsutkkiyfzeyvtyajlvlsewnhkjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatkspriymotofgcemhguskgeflfyfspliorntefgdkykpswzwyrydwlamdft' \
241 | 'ur:seed/4-5/lpaaahcfadmdcyknoxqdgohdgywtpfvwdeecahtdhhvalrnynbtiwnbdctuesabtmnecvapratdwlbvltpgsglmdbnmknebkkscymofpkteyvoatjlqdaovesffhylgdimamcyadctgstymddlynpefppfemlkntknghveglrypslaahtblyvdspolptcpaxrpgs' \
242 | 'ur:seed/5-5/lpahahcfadmdcyknoxqdgohdgypkflsfmdfxjydpioihltbnwppfhtielguthtwdpdihaykgoyclentldykkmnvedsbwuyeojejennbkrtkevotacppyjsvdgohtvewenyneylfekihgcplpgljoisgwverkmokgldyavseojehncfvakgehcmrojlwezmdnkkwe')"
243 | }
244 |
245 | testOutFountainUR()
246 | {
247 | assertEquals $'ur:seed/1-7/lpadatcfadehcyetoyioluhddwoyadhkaddwnteelblrcygldwvarflojtcywyjytpdkfwprylienshnjnpluypmamtkmybsjkspvseesawmrltdlnbkaatllr
248 | ur:seed/2-7/lpaoatcfadehcyetoyioluhddwlgkplfbkqzzoglfeoyaegsnedtrowsdpgtimmwzspfqdjkhshyfrylenpdnnnswmbeheclaszogmdstpoennbtfljpyaihsn
249 | ur:seed/3-7/lpaxatcfadehcyetoyioluhddwwykbtpktgwcxdkhtskwkkgmdmdlubblstnoxpkpysotntbcmotbdwfetqzwsckmscadwssgarysfeomohdytfhlblerhdest
250 | ur:seed/4-7/lpaaatcfadehcyetoyioluhddwmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnspscsutkkiyfzeyvtyajlvlsewnhksscaimzt
251 | ur:seed/5-7/lpahatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatksprpytiinki
252 | ur:seed/6-7/lpamatcfadehcyetoyioluhddwiymotofgcemhguskgeflfyfspliorntefgdkykpswzwyrywtpfvwdeecahtdhhvalrnynbtiwnbdctuesabtmneceegwrkkn
253 | ur:seed/7-7/lpatatcfadehcyetoyioluhddwvapratdwlbvltpgsglmdbnmknebkkscymofpkteyvoatjlqdaovesffhylgdimamcyadctgstymddlynpeaeaeaerosssfjl
254 | ur:seed/8-7/lpayatcfadehcyetoyioluhddwtotelphkaewkfrisssiofgkbkpmepychnyrotiztwylogyfdpflbjllppmtyesdylejktifmglendlltrfpfpkeeglchdakp
255 | ur:seed/9-7/lpasatcfadehcyetoyioluhddwmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnspscsutkkiyfzeyvtyajlvlsewnhkfxjypdtk
256 | ur:seed/10-7/lpbkatcfadehcyetoyioluhddwdwjyuybdmkiyknftdacyaoqdtkaaiofxhglrvtcpmwwnsemtftosmshpamfeehweurtidmkneordbgcygadturseztzekpgl
257 | ur:seed/11-7/lpbdatcfadehcyetoyioluhddwehdmfycnkblknsvdotwflfldynferlatkkaxcsdsbelrfgtlkshtlffmhldaryhetyrysnpyvelrtygmimlpwddivdytgsti
258 | ur:seed/12-7/lpbnatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatksprhtwevebg
259 | ur:seed/13-7/lpbtatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatksprflksylsk
260 | ur:seed/14-7/lpbaatcfadehcyetoyioluhddwylehckclglrkhpnlwpykqdzsldgojoldpyhybzfxtlttpletinsgtdrfqdglwtzehkvlswmhsrwmvdpaclsflbjzctmefdbk
261 | ur:seed/15-7/lpbsatcfadehcyetoyioluhddwknfynsdnzsfzbzuogtykzmihnbweneoxvaeelyrhihiduthkemwndalecwtijzbzgarfvdnletrhseinlsgmjpdnfmwlgytb
262 | ur:seed/16-7/lpbeatcfadehcyetoyioluhddwntknhffwlpnljnghlffrspneaydwcmlgzsvoknnymwnsgoaewtztwnjlptvordgmmdynhhgtwznbynhngloyrktevtmufstd
263 | ur:seed/17-7/lpbyatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatkspruroxcabe' \
264 | "$(${SEEDTOOL} --count 300 --ur=50 --parts 10)"
265 | }
266 |
267 | testInFountainUR()
268 | {
269 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d82442b2f7649c606daedbad06cf8f0f73c8e834c2ebb7d2868d75820ab4fb4e45a1004c9f29b8ef2d4d6a94fab0b373615e3bf736a89e9ceb105f2109fb5226d8a29e0d47ee7ed8774f20245ac5f47b95958b1483daa4aaabc9dad616a30bf338b4ef1e971d2cc449bdcc339258f93f7f91a3d067522b085ca6b2f7c72732ce5aed7ae0ef273f13c8d92ffa89b69cac18dd79664032e0f86fe3c1f1596fd2dc582c690f17407d0852932d23798056a424cacae3bfd4e30fe8030f943645fcdf4d86de1b45570778b26692ce461c9053c54a47443dae67bed34624f5acf2eebdf0b0e5283505d25ce6849aa0d0f10b1fdec20d8e35e6b2072c7fe3d84c4e950c989f0a781a92417732e2076fb302e4cc3ff7506a061a011f4cd4952ff6af' \
270 | "$(${SEEDTOOL} --in ur \
271 | 'ur:seed/2-7/lpaoatcfadehcyetoyioluhddwlgkplfbkqzzoglfeoyaegsnedtrowsdpgtimmwzspfqdjkhshyfrylenpdnnnswmbeheclaszogmdstpoennbtfljpyaihsn' \
272 | 'ur:seed/4-7/lpaaatcfadehcyetoyioluhddwmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnspscsutkkiyfzeyvtyajlvlsewnhksscaimzt' \
273 | 'ur:seed/5-7/lpahatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatksprpytiinki' \
274 | 'ur:seed/7-7/lpatatcfadehcyetoyioluhddwvapratdwlbvltpgsglmdbnmknebkkscymofpkteyvoatjlqdaovesffhylgdimamcyadctgstymddlynpeaeaeaerosssfjl' \
275 | 'ur:seed/8-7/lpayatcfadehcyetoyioluhddwtotelphkaewkfrisssiofgkbkpmepychnyrotiztwylogyfdpflbjllppmtyesdylejktifmglendlltrfpfpkeeglchdakp' \
276 | 'ur:seed/9-7/lpasatcfadehcyetoyioluhddwmeottiiogmdnayhholprylstdieytohtweknvtwsdifhbwsptadlzsldrpnspscsutkkiyfzeyvtyajlvlsewnhkfxjypdtk' \
277 | 'ur:seed/10-7/lpbkatcfadehcyetoyioluhddwdwjyuybdmkiyknftdacyaoqdtkaaiofxhglrvtcpmwwnsemtftosmshpamfeehweurtidmkneordbgcygadturseztzekpgl' \
278 | 'ur:seed/14-7/lpbaatcfadehcyetoyioluhddwylehckclglrkhpnlwpykqdzsldgojoldpyhybzfxtlttpletinsgtdrfqdglwtzehkvlswmhsrwmvdpaclsflbjzctmefdbk' \
279 | 'ur:seed/16-7/lpbeatcfadehcyetoyioluhddwntknhffwlpnljnghlffrspneaydwcmlgzsvoknnymwnsgoaewtztwnjlptvordgmmdynhhgtwznbynhngloyrktevtmufstd' \
280 | 'ur:seed/17-7/lpbyatcfadehcyetoyioluhddwjltduohddwinbschfzkiaygmmudpcnkklahfoxdksgsgvlrstyvlbsvsaxbsmwenfezturgtlnuecwfehgatkspruroxcabe')"
281 | }
282 |
283 | testOutSSKRUR()
284 | {
285 | assertEquals $'ur:crypto-sskr/taadecgomymwaeadaemdfnpldrprcmtpcnfwztcstaotfsbsadatkspyfg
286 | ur:crypto-sskr/taadecgomymwaeadadkpuopkpmkijzcalkherkiofmjtlafxrtgassrntl
287 | ur:crypto-sskr/taadecgomymwaeadaoglvdolfhemvogaiyksjpvabncphhmsmkjznbdefy' \
288 | "$(${SEEDTOOL} --out sskr --group 2-of-3 --ur)"
289 | }
290 |
291 | testInSSKRUR()
292 | {
293 | assertEquals $'9d347f841a4e2ce6bc886e1aee74d824' \
294 | "$(${SEEDTOOL} --in ur ur:crypto-sskr/taadecgomymwaeadaemdfnpldrprcmtpcnfwztcstaotfsbsadatkspyfg ur:crypto-sskr/taadecgomymwaeadaoglvdolfhemvogaiyksjpvabncphhmsmkjznbdefy)"
295 | }
296 |
297 | # Eat all command-line arguments before calling shunit2.
298 | shift $#
299 | # TODO no shunit2 on windows/msys2/mingw64 platform
300 | if [ "$(uname)" == "Darwin" ] || [ "$(uname)" == "Linux" ]; then
301 | . "${SHUNIT2}"
302 | fi
303 |
--------------------------------------------------------------------------------
/src/utils.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // utils.cpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #include "utils.hpp"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include
17 |
18 | using namespace std;
19 |
20 | const string data_to_hex(const ByteVector& in) {
21 | auto hex = "0123456789abcdef";
22 | string result;
23 | for(auto c: in) {
24 | result.append(1, hex[(c >> 4) & 0xF]);
25 | result.append(1, hex[c & 0xF]);
26 | }
27 | return result;
28 | }
29 |
30 | uint8_t hex_digit_to_bin(char hex) {
31 | if (hex >= '0' && hex <= '9') {
32 | return hex - '0';
33 | } else if (hex >= 'A' && hex <= 'F') {
34 | return hex - 'A' + 10;
35 | } else if (hex >= 'a' && hex <= 'f') {
36 | return hex - 'a' + 10;
37 | } else {
38 | throw runtime_error("Invalid hex digit");
39 | }
40 | }
41 |
42 | const ByteVector hex_to_data(const string& hex) {
43 | ByteVector result;
44 |
45 | auto len = hex.length();
46 | if(len % 2 != 0) {
47 | throw runtime_error("Hex string must have even number of characters.");
48 | }
49 | auto count = len / 2;
50 | result.reserve(count);
51 | for(auto i = 0; i < count; i++) {
52 | auto b1 = hex_digit_to_bin(hex[i * 2]);
53 | auto b2 = hex_digit_to_bin(hex[i * 2 + 1]);
54 | result.push_back((b1 << 4) | b2);
55 | }
56 |
57 | return result;
58 | }
59 |
60 | const ByteVector data_to_base(const ByteVector& buf, size_t base) {
61 | ByteVector result;
62 | result.reserve(buf.size());
63 | transform(buf.begin(), buf.end(), back_inserter(result), [&](auto b) { return roundf(b / 255.0 * (base - 1)); });
64 | return result;
65 | }
66 |
67 | const string data_to_alphabet(const ByteVector &in,
68 | size_t base,
69 | string (to_alphabet)(size_t))
70 | {
71 | string result;
72 |
73 | auto data = data_to_base(in, base);
74 | for(auto b: data) {
75 | auto s = to_alphabet(b);
76 | result.append(s);
77 | }
78 |
79 | return result;
80 | }
81 |
82 | const string data_to_ints(const ByteVector &in,
83 | size_t low, size_t high, const string &separator)
84 | {
85 | if (!(low < high && high <= 255)) {
86 | throw runtime_error("Int conversion range must be in 0 <= low < high <= 255.");
87 | }
88 | size_t base = high - low + 1;
89 | auto data = data_to_base(in, base);
90 | auto count = in.size();
91 | string result;
92 | for(auto i = 0; i < count; i++) {
93 | if (i > 0) {
94 | result += separator;
95 | }
96 |
97 | result += to_string(data[i] + low);
98 | }
99 |
100 | return result;
101 | }
102 |
103 | const ByteVector digits_to_data(const string& in, size_t low, size_t high) {
104 | ByteVector result;
105 | for(auto c: in) {
106 | int n = c - '0';
107 | if(n < low || n > high) {
108 | throw runtime_error("Invalid digit.");
109 | }
110 | result.push_back(n);
111 | }
112 | return result;
113 | }
114 |
115 | const string join(const StringVector &strings, const string &separator) {
116 | ostringstream result;
117 | bool first = true;
118 | for(auto s: strings) {
119 | if(!first) {
120 | result << separator;
121 | }
122 | result << s;
123 | first = false;
124 | }
125 | return result.str();
126 | }
127 |
128 | const StringVector split(const string& s, const char& separator) {
129 | StringVector result;
130 | string buf;
131 |
132 | for(auto c: s) {
133 | if(c != separator) {
134 | buf += c;
135 | } else if(buf.length() > 0) {
136 | result.push_back(buf);
137 | buf = "";
138 | }
139 | }
140 |
141 | if(buf != "") {
142 | result.push_back(buf);
143 | }
144 |
145 | return result;
146 | }
147 |
148 | const ByteVector sha256(const ByteVector &buf) {
149 | uint8_t digest[SHA256_DIGEST_LENGTH];
150 | sha256_Raw(buf.data(), buf.size(), digest);
151 | return ByteVector(digest, digest + SHA256_DIGEST_LENGTH);
152 | }
153 |
154 | const string take(const string &s, size_t count) {
155 | auto first = s.begin();
156 | auto c = min(s.size(), count);
157 | auto last = first + c;
158 | return string(first, last);
159 | }
160 |
161 | int days_since_epoch() {
162 | using namespace std::chrono;
163 | auto today = system_clock::now();
164 | auto time_since = today.time_since_epoch();
165 | typedef duration> days;
166 | return duration_cast(time_since).count();
167 | }
168 |
--------------------------------------------------------------------------------
/src/utils.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // utils.hpp
3 | //
4 | // Copyright © 2020 by Blockchain Commons, LLC
5 | // Licensed under the "BSD-2-Clause Plus Patent License"
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | typedef std::vector ByteVector;
17 | typedef std::vector StringVector;
18 |
19 | const std::string data_to_hex(const ByteVector& in);
20 | uint8_t hex_digit_to_bin(char hex);
21 |
22 | const ByteVector hex_to_data(const std::string& hex);
23 |
24 | const ByteVector data_to_base(const ByteVector& buf, size_t base);
25 |
26 | const std::string data_to_alphabet(const ByteVector &in,
27 | size_t base,
28 | std::string (to_alphabet)(size_t));
29 |
30 | const std::string data_to_ints(const ByteVector &in,
31 | size_t low, size_t high, const std::string &separator);
32 |
33 | const ByteVector digits_to_data(const std::string& in, size_t low, size_t high);
34 |
35 | const std::string join(const StringVector &strings, const std::string &separator);
36 | const StringVector split(const std::string& s, const char& separator);
37 |
38 | const ByteVector sha256(const ByteVector &buf);
39 |
40 | template
41 | const std::vector take(const std::vector &buf, size_t count) {
42 | auto first = buf.begin();
43 | auto c = std::min(buf.size(), count);
44 | auto last = first + c;
45 | return std::vector(first, last);
46 | }
47 |
48 | const std::string take(const std::string &s, size_t count);
49 |
50 | template
51 | void append(std::vector& target, const std::vector& source) {
52 | target.insert(target.end(), source.begin(), source.end());
53 | }
54 |
55 | int days_since_epoch();
56 |
57 | template
58 | const std::vector flatten(const std::vector>& source) {
59 | std::vector result;
60 | for(auto item: source) {
61 | append(result, item);
62 | }
63 | return result;
64 | }
65 |
--------------------------------------------------------------------------------