It’s not clear to me why you need to generate additional private/public key pairs. Ethereum address is defined by its private key. You can use it to sign a message using web3:
import ethUtils from 'ethereumjs-util';
const msg = ethUtil.bufferToHex(Buffer.from(data, 'utf8'));
const signed = await asyncCall(web3.personal.sign, msg, account);
where account is the public address you what to prove you own.
On the receiving side you can verify the signature using:
import { recoverPersonalSignature } from 'eth-sig-util';
import { bufferToHex } from 'ethereumjs-util';
import { toLower } from 'lodash';
function checkSignedData({ sign, data, account }) {
const msg = bufferToHex(new Buffer(data, 'utf8'));
const params = { data: msg, sig: sign };
let pub;
try {
pub = recoverPersonalSignature(params);
} catch (e) {
return false;
}
return toLower(pub) === toLower(account);
}