Uniform Resources (URs) allow for the encoding of a variety of information, including a variety of crypto-data. This document describes how they are used to encode SSKRs, or Sharded Secret Key Reconstruction shares.
As usual, this will typically be done for you automatically using Blockchain Commons’ libraries but what follows is an explanation of how everything works.
Why Use URs for SSKRs?
URs are generally a boon because they both improve interoperability and type their contents. As a result, whenever you look at a UR you can see exactly what it contains, and you can easily use that data on a variety of systems.
URs can be particularly useful for SSKRs because of their tight integration with QR Codes. URs were built to work with QRs, and many applications that read in SSKR URs are likely to allow the option of using a camera to capture a QR. This means that instead of solely storing an SSKR share as words, you can also preserve them as a QR. This can be a gamechanger for the reliability and resilience of private keys because friends and family can easily store a variety of SSKR shares for a variety of different people and instanteously and reliably retrieve them as needed.
SSKRs: crypto-sskr
The example uses Blockchain Commons’ default 128-bit seed, YINMN BLUE.
HEX: 59f2293a5bce7d4de59e71b4207ac5d2
BIP-39 WORDS: fly mule excess resource treat plunge nose soda reflect adult ramp planet
BYTEWORDS: hawk whiz diet fact help taco kiwi gift view noon jugs quiz crux kiln silk tied omit keno lung jade
GORDIAN ENVELOPE: See QR code, above
SEGWIT UR OUTPUT DESCRIPTOR: ur:output-descriptor/oeadisktjojeisdefzdydtaolytantjloxaxhdclaxvlcprfttldjobkredtlnhsidwybaeyjtswyandlgjnehtkdsidbkqzsrkphyfhsaaahdcxhnfgnepefxgdytryckticelyotsstoknfntavevaskiddmolsarntykbrybtjpksamtantjooeadlncsghykaeykaeykaocyhngrmuwzaycyzssajpsndifmkohy
SEGWIT TEXT OUTPUT DESCRIPTOR: wpkh([604b93f2/84'/0'/0']xpub6DVfq9VduocgjGeR69Nyr8CCi9w5gywnU7wXMYGswpHjffjcbLYNzz6G6555VDcSZLDwZPzJHJQabVWWgkpvYntpunL3UjHGrkCJ6VndbQf)#ncwysjuk
Do not use this seed to hold real monies; they could disappear immediately!
Translating from Seed to SSKRs
When running SSKR on a seed, it shards to secret to generates a number of shares. This creation of shares will be fully taken care of by your library of choice and is beyond the scope of this document.
For example the following seed:
59f2293a5bce7d4de59e71b4207ac5d2
Can produce the following shares, which constitute a single group of three members with a threshold of two: any two shares can reconstruct the seed.
754b000100a8be4da2e6cf65a05424887888ae855c
754b000101016fd11b9ed35e42bc08c12b47c6c476
754b000102e1076ecb16f7137f9f7c1ade0d7e0708
Understanding an SSKR Share
As described in the crypto-sskr CDDL, the first five bytes of an SSKR share contain an identifier and information about the groups, members, and thresholds that define the SSKR.
The general format is:
- identifier (16 bits)
- group-threshold - 1 (4 bits)
- How many groups are required to retrieve the secret?
- group-count - 1 (4 bits)
- How many groups are there total?
- group-index (4 bits)
- What group is this share from?
- member-threshold - 1 (4 bits)
- How many members are required to retrieve the secret in this group?
- RESERVED (4 bits)
- Currently must be zero.
- member-index (4 bits)
- What member in this group is this share from?
- secret-share (same number of bits as secret)
The above shares can thus be read as follows:
ID | group | member | secret share |
---|---|---|---|
754b | 000 | 100 | a8be4da2e6cf65a05424887888ae855c |
754b | 000 | 101 | 016fd11b9ed35e42bc08c12b47c6c476 |
754b | 000 | 102 | e1076ecb16f7137f9f7c1ade0d7e0708 |
The first share thus reveals:
-
identifier:
754b
- Group Threshold: 0 (+ 1 = 1), just one group needed
- Group Count: 0 (+ 1 = 1), just one group total
- Group Index: 0, the 0th group
- Member Threshold: 1 (+ 1 = 2), two members needed
- RESERVED: 0
- Member Index: 0, the 0th member
-
Secret Share:
a8be4da2e6cf65a05424887888ae855c
Translating an SSKR Share to UR
Translating an SSKR to a crypto-sskr
UR is trivial. All it requires
is encoding the hex of the share as CBOR, then translating it to
minimal bytewords and prefixing it with crypto-sskr
as described in
the UR Overview.
To start with, shares are represented as hex:
h'754b000100a8be4da2e6cf65a05424887888ae855c'
h'754b000101016fd11b9ed35e42bc08c12b47c6c476'
h'754b000102e1076ecb16f7137f9f7c1ade0d7e0708'
Using the CBOR playground, they translate as follows:
55 # bytes(21)
754B000100A8BE4DA2E6CF65A05424887888AE855C
55 # bytes(21)
754b000101016fd11b9ed35e42bc08c12b47c6c476
55 # bytes(21)
754b000102e1076ecb16f7137f9f7c1ade0d7e0708
Or more concisely:
55754b000100a8be4da2e6cf65a05424887888ae855c
55754b000101016fd11b9ed35e42bc08c12b47c6c476
55754b000102e1076ecb16f7137f9f7c1ade0d7e0708
Which is to say: the CBOR encoding is just the share with a length and type prefixing it, here 55
.
This translates to the following URs:
ur:crypto-sskr/gokpgraeadaepdrngtoevatkihnbghdklokslopllphhhgspeybg
ur:crypto-sskr/gokpgraeadadadjlttcwnntehyfwrfaysednflswsskoltambsin
ur:crypto-sskr/gokpgraeadaovyatjtsbcmylbwlbnekecyuebtkbataywtmymuwl
The Difference between SSKR Bytewords and SSKR URs
SSKR Bytewords are one way to represent an SSKR share, so that the share can be written down, etched in steel, or otherwise stored. After encoding as CBOR, with tagging, the share is then translated into normal bytewords.
SSKR
URs
are another way to represent an SSKR share, so that it can be
transmitted between interoperable devices or even stored as a
QR. After encoding as CBOR, without tagging, the share is then
translated to minimal bytewords (and prepended with a ur:crypto-sskr
prefix).
Because these two storage methods both use bytewords, they can look very similar, but there are subtle differences between the two.
-
Typing.
- SSKR bytewords is typed by tagging the hex of the share with
309
. - SSKR UR is typed by prefixing the minimal bytewords with
ur:crypto-sskr
. - This results in the bytewords having three extra words at the start:
tuna acid epic
, which represents the309
tag in CBOR. - Either way you know what you’re getting because of the typing:
309
in CBOR for SSKR bytewords andur:crypto-sskr
in a prefix for UR Bytewords.
- SSKR bytewords is typed by tagging the hex of the share with
-
Encoding.
- SSKR bytewords typically uses regular bytewords encoding for clarity.
- SSKR UR uses minimal bytewords encoding for efficiency.
-
Checksum.
- Because SSKR bytewords have an extra tag at the start, their checksum will be different from UR bytewords, which means that the last four words are different.
As an example the first UR encoding was:
ur:crypto-sskr/gokpgraeadaepdrngtoevatkihnbghdklokslopllphhhgspeybg
Expanding those words would give you a ur:crypto-sskr
with:
ur:crypto-sskr/
gyro keep gear able acid able paid ruin gift oboe visa
task inch numb gush dark logo keys logo pool limp high
hang soap easy brag
(This isn’t how a UR is typically displayed, but it’s shown here without minimal bytewords here solely for easy comparison.)
To encode that same SSKR share as plain bytewords would require the following:
309(
h'754b000100a8be4da2e6cf65a05424887888ae855c'
)
Which encodes as:
D9 0135 # tag(309)
55 # bytes(21)
754B000100A8BE4DA2E6CF65A05424887888AE855C
Or:
D9013555754B000100A8BE4DA2E6CF65A05424887888AE855C
This would produce the Bytewords:
tuna acid epic
gyro keep gear able acid able paid ruin gift oboe visa
task inch numb gush dark logo keys logo pool limp high
soap cyan owls gush
Comparing the two verifies that the share (gyro keep gear able acid
able paid ruin gift oboe visa task inch numb gush dark logo keys logo
pool limp high
or gokpgraeadaepdrngtoevatkihnbghdklokslopllphh
) is
identical in both cases, by the plain bytewords has three additional
opening words (tuna acid epic
or tag 309
) and the four checksum
words at the end vary. This is all exactly as expected.
Testing SSKR URs with Blockchain Commons’ Reference Tools
Gordian SeedTool will export seeds as either SSKR URs or SSKR Bytewords, allowing easy checking among all the formats.
The Blockchain Commons [Seedtool] and [Bytewords] CLIs may also be used, in conjunction with [cbor2diag].
A seed can be input into seedtool:
$ seed=59f2293a5bce7d4de59e71b4207ac5d2
$ seedtool -i hex $seed
59f2293a5bce7d4de59e71b4207ac5d2
That seed can in turn be used to generate SSKR Bytewords:
$ seedtool -i hex $seed -o sskr --group=2-of-3
tuna acid epic gyro cola dark able acid able math blue belt blue glow item gush yank vial hope view fish soap play brew unit idle puff jump rock
tuna acid epic gyro cola dark able acid acid pose frog taxi inch vibe epic arch very play lava surf kick frog pose flux iron wave unit void help
tuna acid epic gyro cola dark able acid also waxy roof plus zaps also tiny yawn unit junk zaps real quad task omit quad pool fuel exit lamb tuna
bytewords
can convert SSKR Bytewords to SSKR Minimal Bytewords:
$ bytewords -i standard -o minimal
tuna acid epic gyro cola dark able acid able math blue belt blue glow item gush yank vial hope view fish soap play brew unit idle puff jump rock
taadecgocadkaeadaemhbebtbegwimghykvlhevwfhsppybwutiepfjprk
Note that this is not the same thing as an SSKR UR, because it contains that 309
tag (tuna acid epic
or taadec
) and a different checksum (idle puff jump rock
or iepfjprk
).
In fact, none of the command-line tools currently output SSKR URs, but if you import one from somewhere else, such Gordian SeedTool, you can convert it to CBOR using bytewords
and then examine it using cbor2diag
.
For:
ur:crypto-sskr/gokpgraeadaepdrngtoevatkihnbghdklokslopllphhhgspeybg
You can:
$ bytewords -i minimal gokpgraeadaepdrngtoevatkihnbghdklokslopllphhhgspeybg -o hex
55754b000100a8be4da2e6cf65a05424887888ae855c
$ cbor2diag -x 55754b000100a8be4da2e6cf65a05424887888ae855c
h'754b000100a8be4da2e6cf65a05424887888ae855c'
Integrating SSKR URs Into Your Code
Blockchain Commons provides an SSKR library in C that translates SSKRs into either Bytewords or URs. It builds on bc-crypto-base, bc-shamir, and bc-bytewords. Translations are also available to other languages.
SSKR Libraries
Language | Repo | Contributor | Status |
---|---|---|---|
C | bc-sskr | Blockchain Commons | Security Reviewed |
Java | bc-libs-java | Bitmark | |
JavaCard | jc-sskr | Proxy | |
Rust | bc-sskr-rust | Blockchain Commons | |
Swift | BCLibsSwift | Blockchain Commons |
Shamir’s Secret Sharing Libraries
Language | Repo | Contributor | Status |
---|---|---|---|
C | bc-shamir | Blockchain Commons | Security Reviewed |
Java | bc-libs-java | Bitmark | |
Rust | bc-shamir-rust | Blockchain Commons | |
Swift | BCLibsSwift | Blockchain Commons |
UR Libraries
Language | Repo | Contributor | Status |
---|---|---|---|
C++ | bc-ur | Blockchain Commons | |
Java | bc-ur-java | Bitmark | |
Java | Hummingbird | Craig Raw | |
Python | foundation-ur-py | Foundation | |
Rust | bc-ur-rust | Blockchain Commons | |
Rust | ur-rust | Dominik Spicher | |
Swift | URKit + URUI | Blockchain Commons | |
TypeScript | bc-ur for TS | xardass |
Conclusion
SSKRs provide a means to shard a secret and then distribute those shares to multiple people. Encoding an SSKR as a UR is entirely trivial, just requiring a simple CBOR encoding followed by the typical minimal Bytewords conversion. The results can be ground-breaking, especially in the ability to reliably and interoperably store your shares as QR codes.