go-shamirsplit

module
v0.1.2-0...-8dfc45d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2019 License: MIT

README

shamirsplit

This is a commandline program to split secrets into a number of shares where a certain threshold amount is necessary to reconstruct the original secret.

Idea

After watching Daan Sprenkels' 34C3 talk "We should share our secrets" I was fascinated how simple yet powerful Shamir secret sharing is. (If you need technical details on Shamir secret sharing, go watch that talk and read the documentation to the accompanying projects on GitHub).

However, I soon realized that using hexadeciaml encoding and appending the entire ciphertext to every keyshare was wasteful and wanted to use erasure coding with the same threshold values to minimize the space used by shares.

Sometime in the future this tool may also support binary protobuf-serialized files to further minimize memory usage.

Description

Informally speaking, the input data is encrypted with an authenticated encryption construction using a random key. The key is then split using Shamir secret sharing and the ciphertext is split and encoded using Reed-Solomon erasure coding. The resulting shares are then signed using a signature algorithm on an elliptic curve with a key derived from the same initial random key.

The combination of keyshare, data share and signature is then encoded in a PEM formatted file, which also includes a unique UUID for easier identification of shards that go together. (I call the combination of key- and data shares a 'shard'.)

When creating shards there are two main arguments, threshold and shares. The latter is the total number of shards created and threshold is the minimum number of shards needed to reconstruct the original data.

For an attempted visualization of the process and data flows see specification.txt.

In the spirit of "don't roll your own crypto", I didn't implement any of the primitives used within. I merely plugged them together and hope that I didn't make any grave mistakes in doing so. Some of the pieces used within:

Installation

  • use go get github.com/ansemjo/go-shamirsplit/cmd/shamirsplit
  • or clone the repository and run make && sudo make install

Usage

Most up-to-date usage information should always be available with shamirsplit --help. Generally there are two subcommands, create and combine and usage data for these subcommands is available with shamirsplit <subcommand> --help.

Creation

In its simplest form, data is piped into the command and the shards are output on the console:

$ echo 'Hello, World!' | shamirsplit create -t 2 -s 3
-----BEGIN SHARDED MESSAGE-----
Threshold: 2
UUID: d6204844-90ef-4f5c-8e52-f3d9f071c89f

ChYKENYgSESQ709cjlLz2fBxyJ8QAhgDGiEBBCYpTker/wuy0QKYvSB9KZRtwWxu
A9W5bEIohzFVoXoiINmBXEWdOJdQ3OjZGuujkWS8mRAtxXbIL+s1ZJ0YO3/xKkBj
Gr9hIztF665uKdnlGiFUGJm1ithjp9agwPhALcEy4MXhSxaXwxZwBtK319j6XGOm
A3EQNjF/yNLbN8fyItsOMhBNeB6VxuaX5AhX2V4hiXSZ
-----END SHARDED MESSAGE-----
-----BEGIN SHARDED MESSAGE-----
Threshold: 2
UUID: d6204844-90ef-4f5c-8e52-f3d9f071c89f

ChYKENYgSESQ709cjlLz2fBxyJ8QAhgDEAEaIQJ2hiK0vaAHvZqv9Oe31BfWh/3V
ptSYd/sEUS7reHXLiiIg2YFcRZ04l1Dc6Nka66ORZLyZEC3Fdsgv6zVknRg7f/Eq
QLLaIpMWENe6U4OyamI+3ywJ4pAZ5fIVxVF2Dn1KI4Hd+dj45Rvg0JkuQyn5w+19
1XhlX7aVY/xP82/AGZMxeAIyEMl49vZR53jMP8Vu4z+RAgI=
-----END SHARDED MESSAGE-----
-----BEGIN SHARDED MESSAGE-----
Threshold: 2
UUID: d6204844-90ef-4f5c-8e52-f3d9f071c89f

ChYKENYgSESQ709cjlLz2fBxyJ8QAhgDEAIaIQNY5tLi61CmJoKFpjuxcTGDf43Z
4EsY4MXVqSzPtpzt2iIg2YFcRZ04l1Dc6Nka66ORZLyZEC3Fdsgv6zVknRg7f/Eq
QOG1AV6ie5rfTFEXtIgIAtizHslpdVJSNyBE7QqQXXnXHOyhaRfrYJQXk0bF5Q8Y
I8FXtOtno8Jf7XBAqxjhgw4yEFh401P15FS0Zm6qOR25mLI=
-----END SHARDED MESSAGE-----

To make splitting easier, a null-byte can be appended after each PEM block with -0/--null. While-read loops or GNU split can then delimit on that null-byte:

$ echo 'Hello, World!' | shamirsplit create -t 2 -s 3 -0 |\
 while read -d $'\0' shard; do echo "$shard" > shard.$((i++)); done
$ echo 'Hello, World!' | shamirsplit create -t 2 -s 3 -0 | split -l1 -t'\0' -d - "shard."

Note however that you need to remove the null-bytes from the output files manually in case you use split. Otherwise shamirsplit combine will only read the first shard and then complain about missing shards.

Alternatively use the -d/--directory and -n/--name arguments to write the shards to files in a directory directly:

$ echo 'Hello, World!' | shamirsplit create -t 2 -s 3 -d /tmp -n testingshard
/tmp/testingshard_000.pem
/tmp/testingshard_001.pem
/tmp/testingshard_002.pem
Combination

To combine shards at a later point in time, concatenate and pipe all the shards that you have in any order. If you have more valid shards than the threshold, the original data will be reconstructed.

Note: upon verification the first shard given is assumed to be "your" shard and its embedded public key will be used to verify the signatures on all shards. Since this provides integrity you should take care to always pipe your own shard first.

$ rm /tmp/testingshard_001.pem 
rm: remove regular file '/tmp/testingshard_001.pem'? y
$ cat /tmp/testingshard_00{2,0}.pem | shamirsplit combine
Hello, World!

Directories

Path Synopsis
cmd
Package sharding is a generated protocol buffer package.
Package sharding is a generated protocol buffer package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL