Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pluggeable Crypto Frameworks #5

Open
jio-gl opened this issue Jan 30, 2021 · 6 comments
Open

Pluggeable Crypto Frameworks #5

jio-gl opened this issue Jan 30, 2021 · 6 comments
Assignees
Labels
enhancement New feature or request

Comments

@jio-gl
Copy link
Collaborator

jio-gl commented Jan 30, 2021

Choose your own public key crypto framework.

@jio-gl jio-gl added the enhancement New feature or request label Jan 30, 2021
@jio-gl jio-gl self-assigned this Jan 30, 2021
@sbazerque
Copy link
Member

This'd be great!

We've discussed this elsewhere, I'll try to post a summary here:

  • Crypto is currently used through identities, that contain user information and a master keypair.
  • The Identity type currently contains an RSA keypair.
  • It'd be fairly straightforward to abstract that, prefix signatures by some algo-identifying code and change the type definition to accept other keypair types besides RSA.
  • Since RSA provides methods both for signing/verifying and encrypting/decrypting using the keypair, the current Identity type provides both signatures and basic encryption (within the limits of RSA).
  • This could be a problem because many of the algorithms we'd use as alternatives don't provide encryption (only sign/verify). Besides that, using the same RSA key for signatures and encryption apparently is not an encouraged practice.
  • The data layer (i.e. everything contained in the /data folder) only uses the sign/verify functions, but the handshake used by the mesh to secure a connection does use the encryption provided by the RSA keypair within identities.
  • A simple solution would be to make some ad-hoc changes to the handshake so that it only uses signatures. A better solution (but I think this can be done as a second step) would be to adopt Diffie-Hellman or some other key exchange protocol to secure connections, as suggested by @sbillig .

@jio-gl
Copy link
Collaborator Author

jio-gl commented Feb 10, 2021

To my knowledge, ECDSA was favored in Mobile due to its smaller key sizes. Same rationale is valid for blockchains so the transactions and the blocks are small.

Example public key implementation for ECDSA:

const { randomBytes } = require('crypto')
const keccak256 = require('js-sha3').keccak256;

const secp256k1 = require('secp256k1')
// or require('secp256k1/elliptic')
//   if you want to use pure js implementation in node

// generate message to sign
// message should have 32-byte length, if you have some other length you can hash message
// for example `msg = sha256(rawMessage)`
const msg = randomBytes(32)
console.log("MSG::"+msg.toString('hex'))

// generate privKey
let privKey
do {
  privKey = randomBytes(32)
} while (!secp256k1.privateKeyVerify(privKey))
console.log("PrivKey::"+privKey.toString('hex'))

// get the public key in a compressed format
const pubKey = secp256k1.publicKeyCreate(privKey)
console.log("PubKey::"+Buffer.from(pubKey).toString('hex'))

// sign the message
const sigObj = secp256k1.ecdsaSign(msg, privKey)
console.log("Signature::"+Buffer.from(sigObj.signature).toString('hex'))

// verify the signature
console.log(secp256k1.ecdsaVerify(sigObj.signature, msg, pubKey))
// => true

const address = keccak256(Buffer.from(pubKey)) // keccak256 hash of  publicKey
const buf2 = Buffer.from(address, 'hex');
console.log("Ethereum Adress:::"+"0x"+buf2.slice(-20).toString('hex')) // take lat 20 bytes as ethereum adress

@jio-gl
Copy link
Collaborator Author

jio-gl commented Feb 10, 2021

$ node ex2.js
MSG::ab33e548697ee88e41a6b7600bff49bc812887f4335d424c2cba43cf56c48402
PrivKey::3dfac442d5059f2a9ab28a156b5c181b979ebed9f4254f3bac4b8e1ec156317a
PubKey::0395dadf30bda5c16fa0d39efa57631895edc129bcf4da2c1476e740c526f0ff3c
Signature::3fc64c9a62ba6fe6dde7aa888073d56c46a3ca23e8d6227f9e7c8f077edf46ca03671e1736cde40f47b75ab447c566918f365ea8573cf74434c3d2ae9fc64aab
true
Ethereum Adress:::0x5be9e8687aea7f500b44df566bb984dd67b8f26c

@jio-gl
Copy link
Collaborator Author

jio-gl commented Feb 10, 2021

Noble secp256k1 apparently is faster and has better security. Maybe later...

@jio-gl
Copy link
Collaborator Author

jio-gl commented Feb 10, 2021

@sbazerque
Copy link
Member

@joigno I just realized we can change the signing algorithm in the identities to whatever we want (make it pluggable as in the description of the issue) and then keep using RSA to make the simple shared secret handshake we are using now.

Say, the SecureNetworkAgent could generate a strong RSA keypair on startup, and then we modify the handshake so that the secret for symmetric crypto is encoded using this keypair, and its pubkey is signed by whatever scheme each identity has chosen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants