SLIP39
The javascript implementation of the SLIP39 for Shamir's Secret-Sharing for Mnemonic Codes.
The code based on my Dart implementation of SLIP-0039.
DISCLAIMER
This project is still in early development phase. Use it at your own risk.
Description
This SLIP39 implementation uses a 3 level height (l=3) of a 16 degree (d=16) tree (T), which is represented as an array of the level two nodes (groups, G).
The degree (d) and the level (l) of the tree are 16 and 3 respectively, which means that max d^(l-1), i.e. 16^2, leaf nodes (M) can be in a complete tree (or forest).
The first level (l=1) node of the tree is the the root (R), the level 2 ones are the SSS
groups (Gs or group nodes) e.g. [G0, ..., Gd]
.
The last, the third, level nodes are the only leafs (M, group members) which contains the generated mnemonics.
Every node has two values:
- the N and
- M i.e. n(N,M).
Whihc means, that N (threshold
) number of M children are required to reconstruct the node's secret.
Format
The tree's human friendly array representation only uses the group (l=2) nodes as arrays.
For example. : [[1,1], [1,1], [3,5], [2,6]]
The group's first parameter is the N
(group threshold) while the second is the M
, the number of members in the group. See, and example in Using.
Installing
npm install slip39
Using
See example/main.js
const slip39 = ;const assert = ;// threshold (N) number of group shares required to reconstruct the master secret.const threshold = 2;const masterSecret = 'ABCDEFGHIJKLMNOP';const passphrase = 'TREZOR';/*** 4 groups shares.* = two for Alice* = one for friends and* = one for family members* Two of these group shares are required to reconstruct the master secret.*/const groups =// Alice group shares. 1 is enough to reconstruct a group share,// therefore she needs at least two group shares to be reconstructed,1 11 1// 3 of 5 Friends' shares are required to reconstruct this group share3 5// 2 of 6 Family's shares are required to reconstruct this group share2 6;const slip = slip39;// One of Alice's shareconst aliceShare = slipmnemonics;// and any two of family's shares.const familyShares = slipmnemonics;const allShares = aliceShare;console;allShares;const recoveredSecret = slip39;console;console;;
Testing
$ npm install$ npm testBasic TestsTest threshold 1 with 5 of 7 shares of a group combinations✓ Test combination 0 1 2 3 4.✓ Test combination 0 1 2 3 5.✓ Test combination 0 1 2 3 6.✓ Test combination 0 1 2 4 5.✓ Test combination 0 1 2 4 6.✓ Test combination 0 1 2 5 6.✓ Test combination 0 1 3 4 5.✓ Test combination 0 1 3 4 6.✓ Test combination 0 1 3 5 6.✓ Test combination 0 1 4 5 6.✓ Test combination 0 2 3 4 5.✓ Test combination 0 2 3 4 6.✓ Test combination 0 2 3 5 6.✓ Test combination 0 2 4 5 6.✓ Test combination 0 3 4 5 6.✓ Test combination 1 2 3 4 5.✓ Test combination 1 2 3 4 6.✓ Test combination 1 2 3 5 6.✓ Test combination 1 2 4 5 6.✓ Test combination 1 3 4 5 6.✓ Test combination 2 3 4 5 6.Test passhrase✓ should return valid mastersecret when user submits valid passphrse✓ should NOT return valid mastersecret when user submits invalid passphrse✓ should return valid mastersecret when user does not submit passphrseTest iteration exponent✓ should return valid mastersecret when user apply valid iteration exponent (44ms)✓ should throw an Error when user submits invalid iteration exponentGroup Shares TestsTest all valid combinations of mnemonics✓ should return the valid mastersecret when valid mnemonics used for recoveryOriginal test vectors Tests✓ 1. Valid mnemonic without sharing (128 bits)✓ 2. Mnemonic with invalid checksum (128 bits)✓ 3. Mnemonic with invalid padding (128 bits)✓ 4. Basic sharing 2-of-3 (128 bits)✓ 5. Basic sharing 2-of-3 (128 bits)✓ 6. Mnemonics with different identifiers (128 bits)✓ 7. Mnemonics with different iteration exponents (128 bits)✓ 8. Mnemonics with mismatching group thresholds (128 bits)✓ 9. Mnemonics with mismatching group counts (128 bits)✓ 10. Mnemonics with greater group threshold than group counts (128 bits)✓ 11. Mnemonics with duplicate member indices (128 bits)✓ 12. Mnemonics with mismatching member thresholds (128 bits)✓ 13. Mnemonics giving an invalid digest (128 bits)✓ 14. Insufficient number of groups (128 bits, case 1)✓ 15. Insufficient number of groups (128 bits, case 2)✓ 16. Threshold number of groups, but insufficient number of members in one group (128 bits)✓ 17. Threshold number of groups and members in each group (128 bits, case 1)✓ 18. Threshold number of groups and members in each group (128 bits, case 2)✓ 19. Threshold number of groups and members in each group (128 bits, case 3)✓ 20. Valid mnemonic without sharing (256 bits)✓ 21. Mnemonic with invalid checksum (256 bits)✓ 22. Mnemonic with invalid padding (256 bits)✓ 23. Basic sharing 2-of-3 (256 bits)✓ 24. Basic sharing 2-of-3 (256 bits)✓ 25. Mnemonics with different identifiers (256 bits)✓ 26. Mnemonics with different iteration exponents (256 bits)✓ 27. Mnemonics with mismatching group thresholds (256 bits)✓ 28. Mnemonics with mismatching group counts (256 bits)✓ 29. Mnemonics with greater group threshold than group counts (256 bits)✓ 30. Mnemonics with duplicate member indices (256 bits)✓ 31. Mnemonics with mismatching member thresholds (256 bits)✓ 32. Mnemonics giving an invalid digest (256 bits)✓ 33. Insufficient number of groups (256 bits, case 1)✓ 34. Insufficient number of groups (256 bits, case 2)✓ 35. Threshold number of groups, but insufficient number of members in one group (256 bits)✓ 36. Threshold number of groups and members in each group (256 bits, case 1)✓ 37. Threshold number of groups and members in each group (256 bits, case 2)✓ 38. Threshold number of groups and members in each group (256 bits, case 3)✓ 39. Mnemonic with insufficient length✓ 40. Mnemonic with invalid master secret lengthInvalid Shares✓ Short master secret✓ Odd length master secret✓ Group threshold exceeds number of groups✓ Invalid group threshold.✓ Member threshold exceeds number of members✓ Invalid member threshold✓ Group with multiple members and threshold 174 passing (477ms)
TODOS
- Add unit tests.
- Test with the reference code's test vectors.
- Refactor the helpers to different helper classes e.g.
CryptoHelper()
,ShamirHelper()
etc. - Add
JSON
representation, see JSON representation below. - Refactor to much simpler code.
JSON Representation
LICENSE
CopyRight (c) 2019 Pal Dorogi "iLap"
pal.dorogi@gmail.com