etkframework
Version:
First test release of Etk over colored coins SDK
145 lines (127 loc) • 5.26 kB
JavaScript
/**
* Etk library.
* Module for compounded salting.
*
* Copyright (C) 2015 Akul Mathur
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Parts of the software are provided under separate licenses, as follows:
"colu-nodejs" SDK is under the MIT License
"pbkdf2-sha256" is under the BSD License
"bip38" is under the MIT License
"scryptsy" is under the MIT License
"coinstring" is under the MIT License
* For a conceptual demo of Scrypt hashing visit:
* http://dchest.github.io/scrypt-async-js/demo.html
*
* TODO: Implement http://cryptocoinjs.com/modules/crypto/scryptsy/
*
*/
;
const
scrypt = require('scryptsy'),
N = 16384,
r = 8,
p = 2,
keyLenBytes = 64,
savePass = function savePass (masterpassword, slavepass) {
/** scrypt(key, salt, N, r, p, keyLenBytes, [progressCallback])
* @params:
* masterpassword: User password
* slavepass: is a DETERMINISITC salt
*
* masterpassword is the User password.
* A slavepass is the secondary password needed to enter
* digital banking section and is used to confirm the correctness
* of masterpassword.
*
*/
let data = scrypt(masterpassword, slavepass, N, r, p, keyLenBytes);
data = data.toString('hex');
//console.log("scrypted data is: " + data);
return data;
},
compoundFunctionConstructor = (function compoundFunctionConstructor () {
/**
* Create a push and mergeHash procedure.
* push accumulates the inputs
* mergehash merges the exisiting salt with new input
* OR two new inputs using savePass
*
* hash: clears the accumulated aray. Returns the salt.
*/
return {
init: function init () {
this.acc = [];
this.salt;
},
push: function push (arg1) {
this.acc.push(arg1);
this._mergeHash();
},
_mergeHash: function mergeHash () {
//console.log("this is: ");
//console.log(this);
//console.log("salt is: "+ this.salt + " inside mergeHash. list is: " + this.acc + " with length: "+ this.acc.length);
if ( this.acc.length >= 2 ) {
this.salt = savePass( this.acc[0], this.acc[1] );
//console.log("len=2 salt is: " + this.salt);
//clear efficiently all reference to this list
// this.acc.splice(0, this.acc.length);
// this.acc.push(this.salt);
// same as above 2 lines
this.acc.push( this.hash() );
}
},
unshift: function unshift (arg1) {
this.acc.unshift(arg1);
this._mergeHash();
},
hash: function salt() {
this.acc.splice(0, this.acc.length); //clear efficiently all reference to this list
return this.salt;
}
};
})(),
compoundedSalt = function compoundedSalt () {
//if not more than 2 arguments, throw error
if ( !( arguments.length > 1 ) ) {
throw Error("Not enough arguments. Inputs absent");
}
let
args=[], masterpassword='',
//Create instance of the compoundFunctionConstructor
compoundFn = Object.create( compoundFunctionConstructor );
for (let ix=0, ln = arguments.length; ix<ln; ix++ ) {
args.push(arguments[ix]);
}
masterpassword = args[0];
compoundFn.init();
/**
* salt the inputs
* pushing each time
* creating scrypt output with each accumulation
* via push and mergeHash
*/
args.slice(1).forEach(function iterArgs (inputVal, index) {
//console.log(inputVal+ " " + index);
compoundFn.push(inputVal);
});
//generate salt by passing masterpassword with
//var preSalt = compoundFn.hash();
compoundFn.unshift(masterpassword);
var res = compoundFn.hash();
//console.log("hash is: " + res);
return res;
};
exports.savePass = savePass;
exports.compoundFunctionConstructor = compoundFunctionConstructor;
exports.compoundedSalt = compoundedSalt;