I found this Bitcoin Paper Wallet: https://bitcoinpaperwallet.com/bitcoinpaperwallet/generate-wallet.html
I would like to add it Ethereum just for fun.
On this question, they show how to create address offline.
I have tried to use the same EllipticCurve library they are using, you can check it here, I guess Elliptic Curve is the same everywhere right?
Based on that I created the script shown below. I get private key, public key and address but... If I try to generate address from private key using web3, I get a different one.
Any ideas will be greatly appreciated.
<script type="text/javascript">
//Ethereum - January 2018
Ethereum.ECDSA = Bitcoin.ECDSA;
Ethereum.ECKey = (function() {
var ECDSA = Ethereum.ECDSA;
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var rng = new SecureRandom();
var ECKey = function (input) {
console.log("ethereum input");
console.log(input);
if (!input) {
var n = ecparams.getN();
console.log("getN");
this.priv = ECDSA.getBigRandom(n);
console.log();
console.log("this.priv");
console.log(this.priv);
console.log("====");
}
}
ECKey.prototype.getEthereumAddress = function () {
console.log("getEthereumAddress");
var hash = this.getPubKeyHash();
console.log("hashEther");
console.log(hash);
var ola = Crypto.util.bytesToHex(hash).toString().toUpperCase();
console.log("ola");
console.log(ola);
//var sourceAddress = keccak256(hash);
var sourceBuffer = keccak256.buffer(hash).slice(-20);
address = this.buffer2Hex(sourceBuffer);
console.log("AAAAAA");
console.log(address);
return address.toString();
};
/*
* Return public key as a byte array in DER encoding
*/
ECKey.prototype.getPub = function () {
console.log("getPub");
if (this.pubUncomp) return this.pubUncomp;
return this.pubUncomp = this.getPubPoint().getEncoded(0);
};
ECKey.prototype.getPubKeyHash = function () {
console.log("getPubKeyHashx");
console.log(this.getPub());
console.log("====");
if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp;
return this.pubKeyHashUncomp = this.getPub();
};
/**
* Return public point as ECPoint object.
*/
ECKey.prototype.getPubPoint = function () {
if (!this.pubPoint) {
this.pubPoint = ecparams.getG().multiply(this.priv);
this.pubPoint.compressed = this.compressed;
}
return this.pubPoint;
};
ECKey.prototype.buffer2Hex = function(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16))).join('');
}
/**
* Set whether the public key should be returned compressed or not.
*/
ECKey.prototype.setCompressed = function (v) {
this.compressed = !!v;
if (this.pubPoint) this.pubPoint.compressed = this.compressed;
return this;
};
// Private Key Hex Format
ECKey.prototype.getEthereumPrivateKeyHexFormat = function () {
var ola = Crypto.util.bytesToHex(this.getEthereumPrivateKeyByteArray()).toString().toUpperCase();
console.log("getBitcoinHexFormat");
console.log(ola);
return ola;
};
ECKey.prototype.getEthereumAddressHexFormat = function () {
var ola = Crypto.util.bytesToHex(this.getEthereumPrivateKeyByteArray()).toString().toUpperCase();
console.log("getBitcoinHexFormat");
console.log(ola);
return ola;
};
ECKey.prototype.getEthereumPrivateKeyByteArray = function () {
// Get a copy of private key as a byte array
var bytes = this.priv.toByteArrayUnsigned();
// zero pad if private key is less than 32 bytes
while (bytes.length < 32) bytes.unshift(0x00);
return bytes;
};
// Sipa Private Key Wallet Import Format
ECKey.prototype.getEthereumPrivateKey = function () {
console.log("getEthereumPrivateKey");
var bytes = this.getEthereumPrivateKeyByteArray();
return Crypto.util.bytesToHex(bytes).toString().toUpperCase();
};
return ECKey;
})();
</script>