|
6 | 6 |
|
7 | 7 | --- |
8 | 8 |
|
| 9 | +## Contents |
| 10 | + |
| 11 | +* [Introduction](#introduction) |
| 12 | +* [General Functionality](#general-functionality) |
| 13 | +* [Generate Random Seeds](#generate-random-seeds) |
| 14 | +* [Generating Seeds from Provided Entropy](#generating-seeds-from-provided-entropy) |
| 15 | +* [Deterministic Randomness](#deterministic-randomness) |
| 16 | +* [Compatibility](#compatibility) |
| 17 | +* [Uniform Resources (URs)](#uniform-resources-urs) |
| 18 | +* [Version History](#version-history) |
| 19 | + |
9 | 20 | ## Introduction |
10 | 21 |
|
11 | 22 | `seedtool` is a command-line tool for creating and transforming cryptographic seeds of the sort commonly used by blockchain applications. |
@@ -676,8 +687,190 @@ $ seedtool --in base10 123456 | seedtool --in hex --out bip39 |
676 | 687 | mirror reject rookie talk pudding throw happy era myth already payment owner |
677 | 688 | ``` |
678 | 689 |
|
| 690 | +## Uniform Resources (URs) |
| 691 | + |
| 692 | +Seedtool can encode and decode binary (hex) seeds, BIP39-encoded seeds, or SLIP39-encoded shares in the Uniform Resource (UR) format. This format is defined in [BCR-0005: Uniform Resources (UR): Encoding Structured Binary Data for Transport in URIs and QR Codes](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-0005-ur.md). The UR types supported for encoding and decoding are `crypto-seed`, `crypto-bip39` and `crypto-slip39`. These types are defined in [BCR-0006: Registry of Uniform Resource (UR) Types](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-0006-urtypes.md). |
| 693 | + |
| 694 | +To encode the result of `seedtool` as a UR, supply the `--ur[=MAX_PART_LENGTH]` command line option. `MAX_PART_LENGTH` is a positive integer that sets the maximum number of characters allowed in a UR part. If a UR cannot be completely encoded in `MAX_PART_LENGTH` or fewer characters, it will be split into a number of roughly equal parts small enough to fall below the `MAX_PART_LENGTH` limit. The default for `MAX_PART_LENGTH` is 2500, and can be set higher or lower. Since `MAX_PART_LENGTH` is optional, it *must* be supplied after an equal sign: |
| 695 | + |
| 696 | +``` |
| 697 | +# OK: |
| 698 | +
|
| 699 | +$ seedtool --ur |
| 700 | +ur:crypto-seed/5gq4pjvz0lzqme7r36sfm44v43jhu3gzmpjpj3lp2k483n |
| 701 | +
|
| 702 | +# OK, UR is still small enough to be encoded in one part |
| 703 | +
|
| 704 | +$ seedtool --ur=500 |
| 705 | +ur:crypto-seed/5gq4qzq6lnxmndvqvmzs79en6clth2qzmpjpj3lpax8n30 |
| 706 | +
|
| 707 | +# Illegal: Optional values must be defined using equal sign. |
| 708 | +
|
| 709 | +$ seedtool --ur 500 |
| 710 | +seedtool: Do not provide arguments when using the random (default) input format. |
| 711 | +
|
| 712 | +# Invalid: MAX_PART_LENGTH too small: |
| 713 | +
|
| 714 | +$ seedtool --ur=50 |
| 715 | +seedtool: Maximum part length too small. |
| 716 | +``` |
| 717 | + |
| 718 | +To decode a UR in one of the supported formats, use the UR input method `--in ur`. |
| 719 | + |
| 720 | +``` |
| 721 | +$ seedtool --in ur ur:crypto-seed/5gq4qzq6lnxmndvqvmzs79en6clth2qzmpjpj3lpax8n30 |
| 722 | +081afccdb9b58066c50f1733d63ebba8 |
| 723 | +``` |
| 724 | + |
| 725 | +As in other cases, input may be supplied on separate lines and terminated by `^D`. |
| 726 | + |
| 727 | +``` |
| 728 | +$ seedtool --in ur |
| 729 | +ur:crypto-seed/5gq4qzq6lnxmndvqvmzs79en6clth2qzmpjpj3lpax8n30 |
| 730 | +^D |
| 731 | +081afccdb9b58066c50f1733d63ebba8 |
| 732 | +``` |
| 733 | + |
| 734 | +As with other input and output methods, seedtool operates in either encoding mode or decoding mode. Thus it is illegal to combine the `--ur` option with the `--in ur` input method. |
| 735 | + |
| 736 | +``` |
| 737 | +$ seedtool --ur --in ur ur:crypto-seed/5gq4qzq6lnxmndvqvmzs79en6clth2qzmpjpj3lpax8n30 |
| 738 | +seedtool: The --ur option may not be combined with the --in ur input method. |
| 739 | +``` |
| 740 | + |
| 741 | +The following example pipes the output of one invocation of seedtool to another, first decoding a binary seed UR to hex, and then re-encoding that hex seed as BIP39. |
| 742 | + |
| 743 | +``` |
| 744 | +$ seedtool --in ur ur:crypto-seed/5gq4qzq6lnxmndvqvmzs79en6clth2qzmpjpj3lpax8n30 | seedtool --out bip39 --ur |
| 745 | +ur:crypto-bip39/5gqccemvda38xar9wfjxxmr4vf5xvetnw35hvctvv3jkzumev3kk2ctwvashgarjv93hgetnd9nksar9v4shyargv4cxj7n6v9jxymmy09nkket5vd582urxwfjkvatnv5pdseqeglssz4y9pq |
| 746 | +
|
| 747 | +# |
| 748 | +# Decode the previous result |
| 749 | +# |
| 750 | +
|
| 751 | +$ seedtool --in ur |
| 752 | +ur:crypto-bip39/5gqccemvda38xar9wfjxxmr4vf5xvetnw35hvctvv3jkzumev3kk2ctwvashgarjv93hgetnd9nksar9v4shyargv4cxj7n6v9jxymmy09nkket5vd582urxwfjkvatnv5pdseqeglssz4y9pq |
| 753 | +^D |
| 754 | +83258554a2e89c1db20a2ba5a31de7da |
| 755 | +
|
| 756 | +# |
| 757 | +# Re-encode the previous result to BIP39 words |
| 758 | +# |
| 759 | +
|
| 760 | +$ seedtool --out bip39 --in hex 83258554a2e89c1db20a2ba5a31de7da |
| 761 | +lobster club festival easy mean attract sight earth pizza body ketchup refuse |
| 762 | +``` |
| 763 | + |
| 764 | +The UR format is designed to be efficiently transmitted in QR codes, because it uses only characters in the QR Code "alphanumeric" character set. This set uses only upper case letters. The Unix `tr` tool can be used to transform the QR to upper case: |
| 765 | + |
| 766 | +``` |
| 767 | +$ seedtool --ur | tr [:lower:] [:upper:] |
| 768 | +UR:CRYPTO-SEED/5GQ4QELHNPJYLFAE07APH603YHVLSVSZMPJPJ3LP5VE66K |
| 769 | +``` |
| 770 | + |
| 771 | +``` |
| 772 | +# |
| 773 | +# Generate a seed, encode it as UR, transform it to upper case, |
| 774 | +# display it on the console, and encode it to a QR Code in |
| 775 | +# the file "seedqrcode.png". |
| 776 | +# |
| 777 | +
|
| 778 | +$ seedtool --ur | tr [:lower:] [:upper:] | tee /dev/tty | qrencode -o seedqrcode.png -l L |
| 779 | +UR:CRYPTO-SEED/5GQ4QZQZ0Z7CT2QWEULWT50LXF8YPXGZMPJPJ3LP3RLQFT |
| 780 | +``` |
| 781 | + |
| 782 | +`seedqrcode.png`: |
| 783 | + |
| 784 | + |
| 785 | + |
| 786 | +The payload of a UR is [CBOR](https://tools.ietf.org/html/rfc7049) encoded as [BC32](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-0004-bc32.md). If you wish to examine the CBOR encoding, you can use seedtool to decode the BC32 payload of a UR. In this example we use the seed above, but only decode the part after the slash as BC32. |
| 787 | + |
| 788 | +``` |
| 789 | +$ seedtool --in bc32 5GQ4QZQZ0Z7CT2QWEULWT50LXF8YPXGZMPJPJ3LP3RLQFT |
| 790 | +a20150080278bd85a80ecf3ee5d1ff324e409902d8641947e1 |
| 791 | +``` |
| 792 | + |
| 793 | +Inputting this byte sequence into the [CBOR Playground](http://cbor.me/), we see the CBOR diagnostic notation output: |
| 794 | + |
| 795 | +``` |
| 796 | +{1: h'080278BD85A80ECF3EE5D1FF324E4099', 2: 100(18401)} |
| 797 | +``` |
| 798 | + |
| 799 | +This is a map with two fields, labeled `1` (the seed itself) and `2` (the date the seed was encoded as number of days since the Unix epoch, tagged with `100` as per the [IETF specification for such dates](https://datatracker.ietf.org/doc/draft-ietf-cbor-date-tag/?include_text=1). The map labels and their meanings are defined in the [Registry of Uniform Resource (UR) Types](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-0006-urtypes.md). |
| 800 | + |
| 801 | +**✳️ NOTE:** Currently seedtool encodes the current date as the seed birthdate when encoding output in UR format. Currently seedtool ignores this field when decoding UR format. |
| 802 | + |
| 803 | +When a UR encoding must be broken up into parts, seedtool prints each part on a separate line. |
| 804 | + |
| 805 | +``` |
| 806 | +$ seedtool --ur=150 --out slip39 --group 2-of-3 |
| 807 | +ur:crypto-slip39/1of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/5gqc89r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxerpvd5kgetrv9exgumxv |
| 808 | +ur:crypto-slip39/2of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/f5hx6r0wpjxkmnfw3j8qctfv35xsatdd9jxjarevah82cmvv4shyetrw43xjcmxdf |
| 809 | +ur:crypto-slip39/3of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/6ku6t0wf5xvmmjv43kzum5v4jk6ur509nkc6trv4h8xetxv9ehqetrw3jkjmtpvaj |
| 810 | +ur:crypto-slip39/4of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ksempwdhkc6twv45x2ut4v96xjmmwvach2ctjw3jh99r8wajkzmr5dpukvum9de5k |
| 811 | +ur:crypto-slip39/5of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/7ungv93kzer9d45kxenpvajkucmev4j8yetpd4jxcctdwpnxxmrfde5kxetkv4ux2 |
| 812 | +ur:crypto-slip39/6of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ergv4kx2anpw3hhy6rnw4hxc6t8dp6xvctnwpjkxar8wdhkx6t9w3uk27tfv4kxge |
| 813 | +ur:crypto-slip39/7of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/n8v4hxjatnvejkjargv4exgurpwpsksmmjvasku6t6v4jxvcttv45xvmr90p5kymr |
| 814 | +ur:crypto-slip39/8of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/9va6x2ctrdpjh99r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxenpd3mkz7tn |
| 815 | +ur:crypto-slip39/9of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ve3kzmt9wfsk2un0w4hxgetnd35kxet9vek82enxv4c82mtswdnxxctdwp6hxergd |
| 816 | +ur:crypto-slip39/10of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/a3x7endv9h82ctvvekh2umrd3jkvctjw35hxar8dphhymt0dejkwanpd4cxjun9dp |
| 817 | +ur:crypto-slip39/11of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/jxzuntdejhxum8wpex2urpwfjkvun9vaex2ar9wpe82mn9qtvxgx28uyxkd09j |
| 818 | +``` |
| 819 | + |
| 820 | +The original seed can be recovered from the above: |
| 821 | + |
| 822 | +``` |
| 823 | +$ seedtool --in ur |
| 824 | +ur:crypto-slip39/1of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/5gqc89r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxerpvd5kgetrv9exgumxv |
| 825 | +ur:crypto-slip39/2of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/f5hx6r0wpjxkmnfw3j8qctfv35xsatdd9jxjarevah82cmvv4shyetrw43xjcmxdf |
| 826 | +ur:crypto-slip39/3of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/6ku6t0wf5xvmmjv43kzum5v4jk6ur509nkc6trv4h8xetxv9ehqetrw3jkjmtpvaj |
| 827 | +ur:crypto-slip39/4of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ksempwdhkc6twv45x2ut4v96xjmmwvach2ctjw3jh99r8wajkzmr5dpukvum9de5k |
| 828 | +ur:crypto-slip39/5of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/7ungv93kzer9d45kxenpvajkucmev4j8yetpd4jxcctdwpnxxmrfde5kxetkv4ux2 |
| 829 | +ur:crypto-slip39/6of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ergv4kx2anpw3hhy6rnw4hxc6t8dp6xvctnwpjkxar8wdhkx6t9w3uk27tfv4kxge |
| 830 | +ur:crypto-slip39/7of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/n8v4hxjatnvejkjargv4exgurpwpsksmmjvasku6t6v4jxvcttv45xvmr90p5kymr |
| 831 | +ur:crypto-slip39/8of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/9va6x2ctrdpjh99r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxenpd3mkz7tn |
| 832 | +ur:crypto-slip39/9of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ve3kzmt9wfsk2un0w4hxgetnd35kxet9vek82enxv4c82mtswdnxxctdwp6hxergd |
| 833 | +ur:crypto-slip39/10of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/a3x7endv9h82ctvvekh2umrd3jkvctjw35hxar8dphhymt0dejkwanpd4cxjun9dp |
| 834 | +ur:crypto-slip39/11of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/jxzuntdejhxum8wpex2urpwfjkvun9vaex2ar9wpe82mn9qtvxgx28uyxkd09j |
| 835 | +^D |
| 836 | +edf2ffaf0e38678306c22d860d4db87a |
| 837 | +``` |
| 838 | + |
| 839 | +The encoded SLIP-39 shares can also be recovered: |
| 840 | + |
| 841 | +``` |
| 842 | +$ seedtool --in ur --out slip39 |
| 843 | +ur:crypto-slip39/1of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/5gqc89r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxerpvd5kgetrv9exgumxv |
| 844 | +ur:crypto-slip39/2of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/f5hx6r0wpjxkmnfw3j8qctfv35xsatdd9jxjarevah82cmvv4shyetrw43xjcmxdf |
| 845 | +ur:crypto-slip39/3of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/6ku6t0wf5xvmmjv43kzum5v4jk6ur509nkc6trv4h8xetxv9ehqetrw3jkjmtpvaj |
| 846 | +ur:crypto-slip39/4of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ksempwdhkc6twv45x2ut4v96xjmmwvach2ctjw3jh99r8wajkzmr5dpukvum9de5k |
| 847 | +ur:crypto-slip39/5of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/7ungv93kzer9d45kxenpvajkucmev4j8yetpd4jxcctdwpnxxmrfde5kxetkv4ux2 |
| 848 | +ur:crypto-slip39/6of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ergv4kx2anpw3hhy6rnw4hxc6t8dp6xvctnwpjkxar8wdhkx6t9w3uk27tfv4kxge |
| 849 | +ur:crypto-slip39/7of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/n8v4hxjatnvejkjargv4exgurpwpsksmmjvasku6t6v4jxvcttv45xvmr90p5kymr |
| 850 | +ur:crypto-slip39/8of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/9va6x2ctrdpjh99r8wajkzmr5dpukvum9de5k7ungv93kzer9d45kxenpd3mkz7tn |
| 851 | +ur:crypto-slip39/9of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/ve3kzmt9wfsk2un0w4hxgetnd35kxet9vek82enxv4c82mtswdnxxctdwp6hxergd |
| 852 | +ur:crypto-slip39/10of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/a3x7endv9h82ctvvekh2umrd3jkvctjw35hxar8dphhymt0dejkwanpd4cxjun9dp |
| 853 | +ur:crypto-slip39/11of11/drs6fzfe3cgsa6sa06la338wxvjcz7amyua8z3rxjyv90qa7zg5qa39yll/jxzuntdejhxum8wpex2urpwfjkvun9vaex2ar9wpe82mn9qtvxgx28uyxkd09j |
| 854 | +^D |
| 855 | +wealthy senior academic acid cards bishop knit paid humidity nuclear cubic junior forecast empty license aspect image gasoline equation quarter |
| 856 | +wealthy senior academic agency dream lamp clinic vexed elevator sunlight aspect society yield genius either papa organize fake flexible teacher |
| 857 | +wealthy senior academic always camera round slice fluff pumps campus hobo manual muscle artist hormone vampire darkness prepare regret prune |
| 858 | +``` |
| 859 | + |
| 860 | +``` |
| 861 | +$ seedtool --in slip39 |
| 862 | +wealthy senior academic acid cards bishop knit paid humidity nuclear cubic junior forecast empty license aspect image gasoline equation quarter |
| 863 | +wealthy senior academic always camera round slice fluff pumps campus hobo manual muscle artist hormone vampire darkness prepare regret prune |
| 864 | +^d |
| 865 | +edf2ffaf0e38678306c22d860d4db87a |
| 866 | +``` |
| 867 | + |
679 | 868 | ## Version History |
680 | 869 |
|
| 870 | +### 0.4.0, 5/19/2020 |
| 871 | + |
| 872 | +* Added support for encoding to and decoding from UR format. |
| 873 | + |
681 | 874 | ### 0.3.0, 5/1/2020 |
682 | 875 |
|
683 | 876 | * Modified "Bech32" format to be "BC32", including dropping "seed" HRP and '1' divider. |
|
0 commit comments