I am using this code to generate a private key, public key and address, acording to this:
The public key is generated from the private key using the Elliptic Curve Digital Signature Algorithm. You get a public address for your account by taking the last 20 bytes of the Keccak-256 hash of the public key and adding 0x to the beginning.
const { secp256k1 } = require("ethereum-cryptography/secp256k1");
const { keccak256 } = require("ethereum-cryptography/keccak");
const { toHex } = require("ethereum-cryptography/utils");
const privateKey = secp256k1.utils.randomPrivateKey();
console.log('private key : ', toHex(privateKey));
const publicKey = secp256k1.getPublicKey(privateKey);
console.log('public key :', toHex(publicKey));
const address = keccak256(publicKey.slice(1)).slice(-20);
console.log('address :', '0x' + toHex(address));
However, I get a valid private and public key pair, but not the corresponding address (compared to some online converters like this and this).
The bug in your code is that you generate the address on the basis of the compressed key, but it must be generated on the basis of the uncompressed key (0x04|x|y).
The leading marker byte has to be removed, from the rest, i.e. the 32 bytes x coordinate and the 32 bytes y coordinate, the Keccak-256 hash is generated, the last 20 bytes of which are the address.
Code with sample data:
Note that the current solution does not yet implement the checksum for Ethereum addresses (EIP-55).
This functionality is provided e.g. by the NodeJS package eip55 and can be applied as followed:
This code now generates the same address as the website you referenced (here), if the public key (compressed or uncompressed, with leading marker byte) is specified there.