Skip to content

Commit

Permalink
Implements CLI signature verification
Browse files Browse the repository at this point in the history
(cherry picked from commit 681ce3d)
  • Loading branch information
ikonovalov committed May 1, 2017
1 parent 6ce0ce5 commit b2c090b
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
5 changes: 5 additions & 0 deletions bin/cli
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ program
'\n\t\t ecTag <ecTag-ipfs-hash>' +
'\n\t\t decryptEcTag <ecTag-ipfs-hash>'.red +
'\n\t\t decrypt <ecTag-ipfs-hash>' +
'\n\t\t signature <ecTag-ipfs-hash>' +
'\n\t\t delegate <ecTag-ipfs-hash> <party-pubkey>' +
'\n\t\t fwatch <filter>' +
'\n\t\t ecwatch <filter>' +
Expand Down Expand Up @@ -84,6 +85,10 @@ program
ipfs.delegate(arg, arg2);
break;
}
case ipfs.signature.name: {
ipfs.signature(arg);
break;
}
case ipfs.fwatch.name: {
ipfs.fwatch(nonEmptyObject(arg));
break;
Expand Down
30 changes: 30 additions & 0 deletions cmd-ipfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const validator = require('validator');
const fs = require('fs');
const tmp = require('tmp');
const colors = require('colors');
const ethUtils = require('ethereumjs-util');

const FileForce = require('./lib/libfileforce');
const FileForceEth = require('./lib/libfileforce-eth');
Expand Down Expand Up @@ -68,6 +69,35 @@ module.exports = {
fileForce.ecTagByHash(ecTagHash).then(ecTag => printObject(ecTag)).catch(error => console.log(error.getMessage().red));
},

signature: (ecTagHash) => {
fileForce
.ecTagByHash(ecTagHash)
.then(ecTag => {
let account = ecTag.partyAddress;
console.log(`Decrypting tag... Party account ${account}.`);
let password = ask.password({ignoreConfig: true});
const selfKeyPair = fileForce.unlockKeys(account, password);
return {
selfKeyPair: selfKeyPair,
ecTag: ecTag
};

})
.then(result => fileForce.decryptEcTag(result.ecTag, result.selfKeyPair))
.then(tag => fileForce.verifyByTag(tag))
.then(verificationResult => {
console.log(`Author public key: ${verificationResult.authorPublicKey}`);
console.log(`Author address: ${verificationResult.authorAddress}`);
console.log(`Signature: `);
console.log(`\tv: ${ethUtils.addHexPrefix(verificationResult.signature.v)}`);
console.log(`\tr: ${ethUtils.addHexPrefix(verificationResult.signature.r)}`);
console.log(`\ts: ${ethUtils.addHexPrefix(verificationResult.signature.s)}`);
console.log(`Digest | IPFS hash: ${verificationResult.digest}`);
console.log(verificationResult.validationResult ? "SIGNATURE VALID".bold.green : "SIGNATURE INVALID".bold.red);
})
.catch(e => console.log(e));
},

decryptEcTag: (ecTagHash) => {
fileForce
.ecTagByHash(ecTagHash)
Expand Down
12 changes: 7 additions & 5 deletions lib/libcrypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,23 @@ class LibCrypto {
}

// ECDSA ------------------------------------------------------------
sign(message, privateKey, options = {}) {
sign(message, privateKey) {
const keyPair = ec.keyFromPrivate(privateKey);
const bufMsg = str2buf(message);
const signature = keyPair.sign(bufMsg);
return signature;
}

verify(signature, message, pub, options = {}) {
if (options.v) {
options.recoveryParam = v;
}
verify(signature, message, pub) {
const key = ec.keyFromPublic(pub);
return key.verify(str2buf(message), signature);
}

/**
* Recovery public key form signature.
* @param signature
* @param message
*/
recovery(signature, message) {
let truncatedMsg = ec._truncateToN(new BN(message, 16));
let r = ec.recoverPubKey(truncatedMsg, signature, signature.recoveryParam);
Expand Down
33 changes: 30 additions & 3 deletions lib/libfileforce.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const EventEmitter = require('events');

const IPFS = require('./libipfs');
const libcrypto = require('./libcrypto');
const BN = require('bn.js');
const ethUtils = require('ethereumjs-util');

const ARROW = '\u2192';

Expand Down Expand Up @@ -280,11 +282,36 @@ class FileForce extends EventEmitter {
});
}

verifyByTag(tag) {
return new Promise((resolve, reject) => {
try {
let signature = {
r: new BN(tag.signature.r, 16),
s: new BN(tag.signature.s, 16),
recoveryParam: tag.signature.v
};
let message = multihash.fromB58String(tag.ipfs);

let recoveredPublicKey = libcrypto.recovery(signature, message);
let recoveredAddress = libcrypto.publicToAddress(recoveredPublicKey);
let signatureValidation = libcrypto.verify(signature, message, recoveredPublicKey);
resolve({
authorPublicKey: ethUtils.bufferToHex(Buffer.from(recoveredPublicKey)),
authorAddress: recoveredAddress,
signature: tag.signature,
digest: tag.ipfs,
validationResult: signatureValidation
});
} catch (e) {
reject(e);
}
})
}

/**
*
* @param ecTag
* @param account
* @param password
* @param ecTag object
* @param ownerKeyPair - pair of public and private keys {privateKey, publicKey}
* @return Promise (tag)
*/
decryptEcTag(ecTag, ownerKeyPair) {
Expand Down

0 comments on commit b2c090b

Please sign in to comment.