This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

micro-ecc (crypto) generating different shared secret to Node.js

Hi there,

I'm currently using micro-ecc on an nRF52 compiled using Nordic's makefiles and implementing the secp256r1 curve. I'm mirroring this in Node.js using the Crypto library.

I generated two sets of pub/priv keys on Node.js and hardcoded one set on the nRF52 and the other into my Node.js application. I then hardcoded each client's pub key into the other's respective shared secret calculation function, however the shared secret being produced is different on each client.

My example code can be found below, I would greatly appreciate any feedback to help resolve or at least identify the cause of this mismatch.

Node.js Application

const crypto = require('crypto');
//...
const client = crypto.createECDH( 'prime256v1' ); // Is different term for secp256r1

var privKeyBuf = Buffer.from([0xac,0xeb,0xdc,0x3e,0x73,0x4b,0xdd,0xd0,0x28,0xf5,0x28,0x91,0xb3,0xbe,0x0c,0x69,0x73,0xec,0xdd,0xaf,0xae,0xed,0xe5,0x2b,0x4f,0x65,0x01,0xbb,0x9c,0x9f,0x86,0x45]);
var clientPubKeyBuf = Buffer.from([0x04,0x3d,0xe5,0xcb,0x74,0x6f,0xff,0x04,0x94,0xeb,0x9e,0x1e,0x43,0x6e,0xd7,0x68,0x29,0x3f,0x6e,0x07,0xe4,0xa5,0xc1,0x28,0x06,0x9f,0xaf,0x59,0x83,0xb8,0x9b,0x25,0x3a,0x0e,0x4e,0x44,0x86,0xc4,0x14,0x02,0xff,0x19,0x99,0x2b,0x6d,0xef,0xc0,0xca,0x36,0xc0,0xdf,0xc5,0xf6,0xac,0x08,0xc6,0x2b,0xe6,0x80,0x1b,0xf2,0x87,0xa2,0xd7,0xae]);

client.setPrivateKey( privKeyBuf );

var sharedSecret = client.computeSecret( clientPubKeyBuf, null, 'hex' );
console.log("Shared Secret: " + sharedSecret);

The resultant secret is: 4fcd8f87a8995a0ff2b57bcafbf8e9bf90ede53a650cf103ac32a7339c44471f.

nRF52 Application

const __align(4) uint8_t privateKey[SECURITY_PRIV_KEY_SIZE] = { 0x78,0x05,0x3c,0xd4,0xcd,0xff,0x8d,0xdc,0xc3,0xd3,0x94,0x5b,0xb9,0x67,0xdd,0x49,0x63,0x82,0xc9,0x11,0xb4,0xa0,0x12,0x35,0xa9,0xf8,0xed,0xec,0xe5,0x53,0x6d,0xc8 };
const __align(4) uint8_t publicKey[SECURITY_PUB_KEY_SIZE] = { 0x3d,0xe5,0xcb,0x74,0x6f,0xff,0x04,0x94,0xeb,0x9e,0x1e,0x43,0x6e,0xd7,0x68,0x29,0x3f,0x6e,0x07,0xe4,0xa5,0xc1,0x28,0x06,0x9f,0xaf,0x59,0x83,0xb8,0x9b,0x25,0x3a,0x0e,0x4e,0x44,0x86,0xc4,0x14,0x02,0xff,0x19,0x99,0x2b,0x6d,0xef,0xc0,0xca,0x36,0xc0,0xdf,0xc5,0xf6,0xac,0x08,0xc6,0x2b,0xe6,0x80,0x1b,0xf2,0x87,0xa2,0xd7,0xae }; // Note the removal of prefixed '0x04' byte as required by micro-ecc
//...
__align(4) uint8_t peerPublicKey[64] = { 0x39, 0x8c,0x22,0x0a,0xb7,0xc1,0x65,0x97,0xa1,0xc4,0x75,0x2b,0xbd,0x4a,0x96,0x43,0x34,0x87,0x98,0xd4,0x85,0x7a,0x87,0x99,0xab,0x90,0x5b,0x8b,0x36,0xde,0x40,0x4d,0xe2,0x73,0x71,0xd7,0x89,0xca,0x65,0x51,0x06,0x7d,0x45,0xa6,0x03,0xce,0x38,0x03,0x03,0xbb,0x33,0xc3,0x1f,0x50,0xe6,0x78,0x75,0xd7,0x25,0x1d,0xd7,0xae,0xfb,0x80 }; // Note the removal of prefixed '0x04' byte as required by micro-ecc
__align(4) uint8_t sharedSecret[32];

uECC_shared_secret( peerPublicKey, privateKey, sharedSecret, uECC_secp256r1() );

The resultant secret is: be5fcd555a0213f89019013e642c4af455128625a2d574c0493772b4606189f6.

Many thanks

Related