Noah Vesely e767f28d4c Initial barycentric Langrange interpolation
Implements barycentric Lagrange interpolation. Uses algorithm (3.1) from the
paper "Polynomial Interpolation: Langrange vs Newton" by Wilhelm Werner to find
the barycentric weights, and then evaluates at `Gf256::zero()` using the second
or "true" form of the barycentric interpolation formula.

I also earlier implemented a variant of this algorithm, Algorithm 2, from "A new
efficient algorithm for polynomial interpolation," which uses less total
operations than Werner's version, however, because it uses a lot more
multiplications or divisions (depending on how you choose to write it), it runs
slower given the running time of subtraction/ addition (equal) vs
multiplication, and especially division in the Gf256 module.

The new algorithm takes n^2 / 2 divisions and n^2 subtractions to calculate the
barycentric weights, and another n divisions, n multiplications, and 2n
additions to evaluate the polynomial*. The old algorithm runs in n^2 - n
divisions, n^2 multiplications, and n^2 subtractions. Without knowing the exact
running time of each of these operations, we can't say for sure, but I think a
good guess would be the new algorithm trends toward about 1/3 running time as n
-> infinity. It's also easy to see theoretically that for small n the original
lagrange algorithm is faster. This is backed up by benchmarks, which showed for
n >= 5, the new algorithm is faster. We can see that this is more or less what
we should expect given the running times in n of these algorithms.

To ensure we always run the faster algorithm, I've kept both versions and only
use the new one when 5 or more points are given.

Previously the tests in the lagrange module were allowed to pass nodes to the
interpolation algorithms with x = 0. Genuine shares will not be evaluated at x =
0, since then they would just be the secret, so:

1. Now nodes in tests start at x = 1 like `scheme::secret_share` deals them out.
2. I have added assert statements to reinforce this fact and guard against
   division by 0 panics.

This meant getting rid of the `evaluate_at_works` test, but
`interpolate_evaluate_at_0_eq_evaluate_at` provides a similar test.

Further work will include the use of barycentric weights in the `interpolate`
function.

A couple more interesting things to note about barycentric weights:

* Barycentric weights can be partially computed if less than threshold
  shares are present. When additional shares come in, computation can resume
  with no penalty to the total runtime.
* They can be determined totally independently from the y values of our points,
  and the x value we want to evaluate for. We only need to know the x values of
  our interpolation points.
2018-08-13 21:29:39 +02:00
2018-03-03 17:01:55 +01:00
2018-02-13 20:38:31 +01:00
2018-03-08 00:39:56 +01:00
2016-11-09 22:45:30 +01:00
2018-02-16 17:03:39 +01:00

Rusty Secrets

Build Status Coverage Status Crates.io LICENSE

Rusty Secrets is an implementation of a threshold Shamir's secret sharing scheme.

Documentation (latest)
Documentation (master)

Design goals

The main use for this library is to split a secret of an arbitrary length in n different shares and k-out-of-n shares are required to recover it. The dealer is assumed to be honest (and competent). We further assume that our adversary will only be able to compromise at most k-1 shares. Shares are kept offline.

A typical use case for this library would be splitting an encryption key to a TrueCrypt-like volume.

Implementation

Structure of the shares

  2-1-LiTyeXwEP71IUA
  ^ ^ ^^^^^^^^^^^^^^
  K N        D        

A share is built out of three parts separated with a dash: K-N-D.

  • K specifies the number of shares necessary to recover the secret.
  • N is the identifier of the share and varies between 1 and n where n is the total number of generated shares.
  • The D part is a Base64 encoding of a ShareData protobuf containing information about the share, and if signed, the signature.

Signatures

There are a few issues with regular Shamir's secret sharing that we wanted to address:

  • a share can be corrupted or incorrectly entered.
  • a malicious share holder can modify the secret that would be recovered by modifying his share.
  • a user has multiple shares from different secret shares and he doesn't know which one belongs to a specific instance.

All of these issues would result in a corrupted secret being outputted and the program, that wouldn't even know that the secret got corrupted, wouldn't be able to give any actionable information.

We addressed this by signing the shares by the dealer and encoding the public key into each share. After the generation of the shares, the dealer erases both the secret and the private signing key used to sign the shares. When recovering the secret, the program verifies that public keys and if some shares do not have the same public key, or a valid signature of that public key, signals the issue to the user with a helpful message.

Signing shares is optional and the usefulness of signing the shares depends on the use case. Since we're using hash-based signatures (using SHA-512 Merkle signing), there is a large overhead from using signatures.

Bug Reporting

Please report bugs either as pull requests or as issues in the issue tracker. RustySecrets has a full disclosure vulnerability policy. Please do NOT attempt to report any security vulnerability in this code privately to anybody.

License

See LICENSE.

Vocabulary

  • Dealer: Entity that will perform key splitting from a master secret
  • Shares: Part of the split secret distributed

Credits

Rusty Secrets was forked off sellibitze's secretshare.

Description
No description provided
Readme BSD-3-Clause 1.9 MiB
Languages
Rust 99.5%
Makefile 0.5%