ESSS
Elliptic SSS scheme implementation in Node.js.
algorithm features
 use secp256k1 to restore secret
 each share can be signed with the corresponding private key
Description
The ESSS scheme is an extended version of SSS (Shamir Shared Secret) scheme, which use elliptic curve properties for making sure, that only certain private key owners are able to restore the secret.
How does it work?
The original algorithm is based on polynomial interpolation, where we have to find (x0, y0). The x0 = 0
, and y0 = secret
.
In ESSS scheme, each peer should have its own private and public keys. The workflow looks like so:
 during split phase, the peer should provide all involved public keys with restoration factor (m, in mofn)
 the result of the split is an [xCoef, y] for each peer (each will have its own pair).
 each peer should receive its own [xCoef, y]
 To restore the secret, m of n peers should sign the xCoef with their private key
 the next step is to exchange with [signature, y].
 the last step is to restore the secret from m shares
Explanation
During the split phase, algorithm generates a random xCoef for each provided public key. The xCoef should belong to prime: xCoef <= prime
.
Then the algorithm calculates the x
coordinate: xCoef * publicKey[i]
, where publicKey[i]
 is an i
public key of provided public keys array.
Mofn peers should sign the xCoef
: signature = xCoef * privateKey
.
During the restoration phase, the algorithm calculates the initial x
coordinate as: x = signature * G
.
By knowing mofn shares, the algorithm restores initial secret through interpolation.
The proof: xCoef * publicKey = xCoef * privateKey * G = signature * G
Installation
Via npm
$ npm install esss save
From repo
$ npm run build
API
esss.split(secret: string, needed: number, publicKeys: string[]): Array<[string, string]>
Arguments:

secret
 the source secret, which should be split. Make sure, that secret doesn't start from0
 otherwise it will be wiped during restoration. 
needed
 how many keys required for restoration (m, mofn) 
publicKeys
 all involved public keys
Return: Array<[string, string]>
, where each element of array is [xCoef, y], which should be distributed to the certain peer.
The publicKey index is the same as index of [xCoef, y] (so it returns in the same order as publicKeys were provided).
esss.sign(share: string, privateKey: string): string
Arguments:

share
 the y coordinate (which is also known as share) 
privateKey
 peer's private key
Return: signature, which is string
.
esss.partialValidate(xCoef: string, publicKey: string, signature: string): boolean
An optional step to validate the signature of the certain peer
Arguments:

xCoef
 the peer'sxCoef

publicKey
 peer's public key 
signature
 peer's signature for providedxCoef
Return: boolean
. If signature valid returns true
otherwise  false
esss.join(shares: Array<[string, string]>): string
Arguments:

Array<[string, string]>
 array of [signature, share]
Return: string
. Should return the secret
esss.utils.generateSafeKeyPair(): { privateKey: string, publicKey: string }
Should generate the safe keypair. The safe means that private key doesn't start with 0
.
It's important since algorithm works with bigNumbers and this 0 can be wiped during convertation process.
Return: { privateKey: string, publicKey: string }
 should return the keyPair.
Example
import esss from 'esss'
const keyPair1 = esss.utils.generateSafeKeyPair();
const keyPair2 = esss.utils.generateSafeKeyPair();
const keyPair3 = esss.utils.generateSafeKeyPair();
const secret = '2e2ce090ee475752b19e79501897d3f3cb92d687f8c028df092a18e7838edac3';
const m = 2;
const [share1, share2, share3] = esss.split(secret, m, [keyPair1.publicKey, keyPair2.publicKey, keyPair3.publicKey]);
const signature1 = esss.sign(share1[0], keyPair1.privateKey);
const reply1: [string, string] = [signature1, share1[1]];
const signature3 = esss.sign(share3[0], keyPair3.privateKey);
const reply3: [string, string] = [signature3, share3[1]];
const joined = esss.join([reply1, reply3]);
console.log(`are equal: ${secret === joined}`); //are equal: true
Please check out test files for an advanced example.
Running test
$ npm run test
License
Copyright
Copyright (c) 20202021 Egor Zuev