1+ const BASE64 = require ( "base64-js" ) ;
12const CRYPTO = require ( "tweetnacl" ) ;
23const SCRYPT = require ( "scryptsy" ) ;
34
@@ -55,13 +56,17 @@ function decrypt(data, salt, passphrase, nonce) {
5556function share ( data , title , passphrase , totalShards , requiredShards ) {
5657 var salt = hashString ( title ) ;
5758 var encrypted = encrypt ( data , salt , passphrase ) ;
58- var nonce = hexify ( encrypted . nonce ) ;
59+ var nonce = BASE64 . fromByteArray ( encrypted . nonce ) ;
5960 var hexEncrypted = hexify ( encrypted . value ) ;
6061 return SECRETS . share ( hexEncrypted , totalShards , requiredShards ) . map ( function ( shard ) {
62+ // First char is non-hex (base36) and signifies the bitfield size of our share
63+ var encodedShard = shard [ 0 ] + BASE64 . fromByteArray ( dehexify ( shard . slice ( 1 ) ) ) ;
64+
6165 return JSON . stringify ( {
66+ v : 1 ,
6267 t : title ,
6368 r : requiredShards ,
64- d : shard ,
69+ d : encodedShard ,
6570 n : nonce
6671 } ) . replace ( / [ \u007F - \uFFFF ] / g, function ( chr ) {
6772 return "\\u" + ( "0000" + chr . charCodeAt ( 0 ) . toString ( 16 ) ) . substr ( - 4 )
@@ -72,6 +77,7 @@ function share(data, title, passphrase, totalShards, requiredShards) {
7277function parse ( payload ) {
7378 let parsed = JSON . parse ( payload ) ;
7479 return {
80+ version : parsed . v || 0 , // 'undefined' version is treated as 0
7581 title : parsed . t ,
7682 requiredShards : parsed . r ,
7783 data : parsed . d ,
@@ -80,8 +86,6 @@ function parse(payload) {
8086}
8187
8288function reconstruct ( shardObjects , passphrase ) {
83- var shardData = shardObjects . map ( shard => shard . data ) ;
84-
8589 var shardsRequirements = shardObjects . map ( shard => shard . requiredShards ) ;
8690 if ( ! shardsRequirements . every ( r => r === shardsRequirements [ 0 ] ) ) {
8791 throw "Mismatching min shards requirement among shards!"
@@ -100,11 +104,31 @@ function reconstruct(shardObjects, passphrase) {
100104 throw "Titles mismatch among shards!"
101105 }
102106
103- var encryptedSecret = SECRETS . combine ( shardData ) ;
104- var secret = dehexify ( encryptedSecret ) ;
105- var nonce = dehexify ( nonces [ 0 ] ) ;
106- var salt = hashString ( titles [ 0 ] ) ;
107- return uint8ArrayToStr ( decrypt ( secret , salt , passphrase , nonce ) ) ;
107+ var versions = shardObjects . map ( shard => shard . version ) ;
108+ if ( ! versions . every ( v => v === versions [ 0 ] ) ) {
109+ throw "Versions mismatch along shards!"
110+ }
111+
112+ switch ( versions [ 0 ] ) {
113+ case 0 :
114+ var shardData = shardObjects . map ( shard => shard . data ) ;
115+ var encryptedSecret = SECRETS . combine ( shardData ) ;
116+ var secret = dehexify ( encryptedSecret ) ;
117+ var nonce = dehexify ( nonces [ 0 ] ) ;
118+ var salt = hashString ( titles [ 0 ] ) ;
119+ return uint8ArrayToStr ( decrypt ( secret , salt , passphrase , nonce ) ) ;
120+
121+ case 1 :
122+ var shardDataV1 = shardObjects . map ( shard => shard . data [ 0 ] + hexify ( BASE64 . toByteArray ( shard . data . slice ( 1 ) ) ) ) ;
123+ var encryptedSecretV1 = SECRETS . combine ( shardDataV1 ) ;
124+ var secretV1 = dehexify ( encryptedSecretV1 ) ;
125+ var nonceV1 = BASE64 . toByteArray ( nonces [ 0 ] ) ;
126+ var saltV1 = hashString ( titles [ 0 ] ) ;
127+ return uint8ArrayToStr ( decrypt ( secretV1 , saltV1 , passphrase , nonceV1 ) ) ;
128+
129+ default :
130+ throw "Version is not supported!" ;
131+ }
108132}
109133
110134export default {
0 commit comments