Why i am getting different public key values from same private key

bip32hd-walletsprivate-keypublic-key

I have been exploring ethereum-cryptography library to build HD wallet features for my demo application. I have used HDkey library to generate master private key from master seed.

The code is below create HDKey and generate master private and public key pair.

const { HDKey } = require('ethereum-cryptography/hdkey')
const { wordlist } = require('ethereum-cryptography/bip39/wordlists/english')
const { generateMnemonic, mnemonicToSeedSync } = require('ethereum-cryptography/bip39')
const { hexToBytes } = require('ethereum-cryptography/utils')

const _generateMnemonic = () => {
  const strength = 256 // 256 bits
  const mnemonic = generateMnemonic(wordlist, strength)
  return mnemonic
}

const _mnemonicToSeed =  (_mnemonic) => {
  const seed = mnemonicToSeedSync(_mnemonic)
  return seed
}

const _getMasterHDKey = (_seed) => {
  return HDKey.fromMasterSeed(_seed)
}

let privateKey
let publicKey
const createHDWallet = () => {
  const mnemonic = _generateMnemonic()
  const seed = _mnemonicToSeed(mnemonic)
  const masterHDKey = _getMasterHDKey(seed)
  privateKey = masterHDKey.privateKey
  publicKey = masterHDKey.publicKey
  return publicKey
}

console.log(createHDWallet())
// Console logged value
Uint8Array(33) [
  3, 154, 134, 108,  86, 139,  17, 160,
177,  83,  73,  20, 147, 128, 180,  80,
 91, 172,  92, 128,  29, 174,  30, 139,
 50, 112, 123, 175,  15, 140, 103, 158,
139
]

Since, the HDKey class is also using "getPublicKey" function from secp256k1 to generate master public key from master private key. But when i use the same function from secp256k1 to generate public, the first bit in the array is different and also returning 65 bytes of public key instead of 33 bytes.

The another part of code is below.

const { getPublicKey } = require('ethereum-cryptography/secp256k1')

const _getPublicKey = (_privateKey) => {
  return getPublicKey(_privateKey)
}

console.log(_getPublicKey(privateKey))
// Console logged value
Uint8Array(65) [
  4, 154, 134, 108,  86, 139,  17, 160, 177,  83,  73,
 20, 147, 128, 180,  80,  91, 172,  92, 128,  29, 174,
 30, 139,  50, 112, 123, 175,  15, 140, 103, 158, 139,
230, 230, 244,   8,  55,   8, 156,  32, 118, 149, 198,
178,  66, 255,  84, 147, 133, 156, 130, 117, 119, 196,
112,  99, 123, 126, 223, 135, 182, 233, 206, 223
]

I also get into the code written in HDKey and secp256k1 library but iam not able to get my head around, why they returning different value using same private key?

Thanks in advance!

Best Answer

The first byte indicate the public key format

  • 02 - compressed format 33 bytes y is odd
  • 03 - compressed format 33 bytes y is even
  • 04 - uncompressed format 65 bytes