-
Notifications
You must be signed in to change notification settings - Fork 171
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from braydonf/feature/minify
Reduce Filesize of Browser Bundle
- Loading branch information
Showing
4 changed files
with
223 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,172 @@ | ||
var bitcore = require('bitcore'); | ||
var Key = bitcore.Key; | ||
var SIN = bitcore.SIN; | ||
var SINKey = bitcore.SINKey | ||
var util = bitcore.util; | ||
|
||
var BitAuth = {}; | ||
var elliptic = require('elliptic'); | ||
var ecdsa = new elliptic.ec(elliptic.curves.secp256k1); | ||
var hashjs = require('hash.js'); | ||
var bs58 = require('bs58'); | ||
var BitAuth = {}; | ||
|
||
/** | ||
* Will return a key pair and identity | ||
* | ||
* @returns {Object} An object with keys: created, priv, pub and sin | ||
*/ | ||
BitAuth.generateSin = function() { | ||
var sk = new SINKey(); | ||
sk.generate(); | ||
return sk.storeObj(); | ||
|
||
var keys = ecdsa.genKeyPair(); | ||
|
||
var privateKey = keys.getPrivate('hex'); | ||
var publicKey = this.getPublicKeyFromPrivateKey(privateKey); | ||
var sin = this.getSinFromPublicKey(publicKey); | ||
|
||
var sinObj = { | ||
created: Math.round(Date.now() / 1000), | ||
priv: privateKey, | ||
pub: publicKey, | ||
sin: sin | ||
}; | ||
|
||
return sinObj; | ||
}; | ||
|
||
/** | ||
* Will return a public key from a private key | ||
* | ||
* @param {String} A private key in hex | ||
* @returns {String} A compressed public key in hex | ||
*/ | ||
BitAuth.getPublicKeyFromPrivateKey = function(privkey) { | ||
try { | ||
var key = new Key(); | ||
|
||
key.private = new Buffer(privkey, 'hex'); | ||
key.regenerateSync(); | ||
var keys = ecdsa.keyPair(privkey, 'hex'); | ||
|
||
// compressed public key | ||
var pubKey = keys.getPublic(); | ||
var xbuf = new Buffer(pubKey.x.toString('hex', 64), 'hex'); | ||
var ybuf = new Buffer(pubKey.y.toString('hex', 64), 'hex'); | ||
var pub; | ||
|
||
return key.public.toString('hex'); | ||
} catch (err) { | ||
console.log(err); | ||
return null; | ||
if (ybuf[ybuf.length-1] % 2) { //odd | ||
pub = Buffer.concat([new Buffer([3]), xbuf]); | ||
} else { //even | ||
pub = Buffer.concat([new Buffer([2]), xbuf]); | ||
} | ||
|
||
var hexPubKey = pub.toString('hex'); | ||
|
||
return hexPubKey; | ||
|
||
}; | ||
|
||
/** | ||
* Will return a SIN from a compressed public key | ||
* | ||
* @param {String} A public key in hex | ||
* @returns {String} A SIN identity | ||
*/ | ||
BitAuth.getSinFromPublicKey = function(pubkey) { | ||
var pubkeyHash = util.sha256ripe160(new Buffer(pubkey, 'hex')); | ||
var sin = new SIN(SIN.SIN_EPHEM, pubkeyHash); | ||
return sin.toString(); | ||
} | ||
|
||
BitAuth.sign = function(data, privkey) { | ||
var hash = util.sha256(data); | ||
// sha256 hash the pubkey | ||
var pubHash = (new hashjs.sha256()).update(pubkey, 'hex').digest('hex'); | ||
|
||
// get the ripemd160 hash of the pubkey | ||
var pubRipe = (new hashjs.ripemd160()).update(pubHash, 'hex').digest('hex'); | ||
|
||
// add the version | ||
var pubPrefixed = '0f02'+pubRipe; | ||
|
||
// two rounds of hashing to generate the checksum | ||
var hash1 = (new hashjs.sha256()).update(pubPrefixed, 'hex').digest('hex'); | ||
var checksumTotal = (new hashjs.sha256()).update(hash1, 'hex').digest('hex'); | ||
|
||
// slice the hash to arrive at the checksum | ||
var checksum = checksumTotal.slice(0,8); | ||
|
||
// add the checksum to the ripemd160 pubkey | ||
var pubWithChecksum = pubPrefixed + checksum; | ||
|
||
// encode into base58 | ||
var sin = bs58.encode(new Buffer(pubWithChecksum, 'hex')); | ||
|
||
return sin; | ||
|
||
try { | ||
var key = new Key(); | ||
key.private = new Buffer(privkey, 'hex'); | ||
return key.signSync(hash).toString('hex'); | ||
} catch (err) { | ||
console.log(err.stack); | ||
console.log(err); | ||
return null; | ||
} | ||
}; | ||
|
||
BitAuth.verifySignature = function(data, pubkey, signature, callback) { | ||
var hash = util.sha256(data); | ||
/** | ||
* Will sign a string of data with a private key | ||
* | ||
* @param {String} data - A string of data to be signed | ||
* @param {String} privkey - A private key in hex | ||
* @returns {String} signature - A DER signature in hex | ||
*/ | ||
BitAuth.sign = function(data, privkey) { | ||
var hash = (new hashjs.sha256()).update(data).digest('hex'); | ||
var signature = ecdsa.sign(hash, privkey); | ||
var hexsignature = signature.toDER('hex'); | ||
return hexsignature; | ||
}; | ||
|
||
try { | ||
var key = new Key(); | ||
key.public = new Buffer(pubkey, 'hex'); | ||
key.verifySignature(hash, new Buffer(signature, 'hex'), callback); | ||
} catch (err) { | ||
callback(err, false); | ||
} | ||
/** | ||
* Will verify a signature | ||
* | ||
* @param {String} data - A string of data that has been signed | ||
* @param {String} pubkey - The compressed public key in hex that has signed the data | ||
* @param {String} hexsignature - A DER signature in hex | ||
* @returns {Function|Boolean} - If the signature is valid | ||
*/ | ||
BitAuth.verifySignature = function(data, pubkey, hexsignature, callback) { | ||
var hash = (new hashjs.sha256()).update(data).digest('hex'); | ||
var signature = new Buffer(hexsignature, 'hex'); | ||
var valid = ecdsa.verify(hash, signature, pubkey); | ||
if (callback) | ||
return callback(null, valid); | ||
return valid; | ||
}; | ||
|
||
|
||
/** | ||
* Will verify that a SIN is valid | ||
* | ||
* @param {String} sin - A SIN identity | ||
* @returns {Function|Boolean} - If the SIN identity is valid | ||
*/ | ||
BitAuth.validateSin = function(sin, callback) { | ||
var s = new SIN(sin); | ||
|
||
var pubWithChecksum; | ||
|
||
// check for non-base58 characters | ||
try { | ||
s.validate() | ||
pubWithChecksum = new Buffer(bs58.decode(sin), 'hex').toString('hex'); | ||
} catch(err) { | ||
if ( callback ) | ||
callback(err); | ||
if (callback) | ||
return callback(err); | ||
return false; | ||
} | ||
if ( callback ) | ||
callback(null); | ||
return true; | ||
|
||
// check the version | ||
if (pubWithChecksum.slice(0, 4) !== '0f02') { | ||
if (callback) | ||
return callback(new Error('Invalid prefix or SIN version')); | ||
return false; | ||
} | ||
|
||
// get the checksum | ||
var checksum = pubWithChecksum.slice(pubWithChecksum.length-8, | ||
pubWithChecksum.length); | ||
var pubPrefixed = pubWithChecksum.slice(0, pubWithChecksum.length-8); | ||
|
||
// two rounds of hashing to generate the checksum | ||
var hash1 = (new hashjs.sha256()).update(pubPrefixed, 'hex').digest('hex'); | ||
var checksumTotal = (new hashjs.sha256()).update(hash1, 'hex').digest('hex'); | ||
|
||
// check the checksum | ||
if (checksumTotal.slice(0,8) === checksum) { | ||
if (callback) | ||
return callback(null); | ||
return true; | ||
} else { | ||
if (callback) | ||
return callback(new Error('Checksum does not match')); | ||
return false; | ||
} | ||
|
||
}; | ||
|
||
module.exports = BitAuth; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
|
||
{ | ||
"name": "bitauth", | ||
"description": "Passwordless authentication using Bitcoin cryptography", | ||
|
@@ -18,17 +17,23 @@ | |
{ | ||
"name": "Gordon Hall", | ||
"email": "[email protected]" | ||
}, | ||
{ | ||
"name": "Braydon Fuller", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"scripts": { | ||
"make-dist": "sh scripts/make-dist.sh", | ||
"test": "mocha test/*.js --reporter spec", | ||
"postinstall": "npm run make-dist" | ||
"postinstall": "npm run make-dist", | ||
"test": "mocha test/*.js --reporter spec" | ||
}, | ||
"main": "index.js", | ||
"version": "0.1.1", | ||
"dependencies": { | ||
"bitcore": "0.1.32", | ||
"elliptic": "^0.15.12", | ||
"hash.js": "^0.3.2", | ||
"bs58": "^2.0.0", | ||
"request": "^2.36.0", | ||
"express": "^4.3.1", | ||
"base58-native": "^0.1.4", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,5 @@ | ||
cd node_modules/bitcore | ||
echo "Building browser bundle for bitcore..." | ||
node browser/build -s lib/Key,lib/SINKey,lib/SIN,util/util | ||
cd ../../ | ||
cp node_modules/bitcore/browser/bundle.js dist/bitcore.bundle.js | ||
echo "Building browser bundle for bitauth..." | ||
node_modules/.bin/browserify lib/bitauth.js -s bitauth -x buffertools -x bitcore -o dist/bitauth.bundle.js | ||
echo "Minifying bitcore and bitauth..." | ||
node_modules/.bin/uglifyjs dist/bitcore.bundle.js dist/bitauth.bundle.js -o dist/bitauth.browser.min.js | ||
node_modules/.bin/browserify lib/bitauth.js -s bitauth -o dist/bitauth.bundle.js | ||
echo "Minifying bitauth..." | ||
node_modules/.bin/uglifyjs dist/bitauth.bundle.js --compress --mangle -o dist/bitauth.browser.min.js | ||
echo "Done!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters