Skip to content

Instantly share code, notes, and snippets.

@andris9
Created March 24, 2021 12:43
Show Gist options
  • Save andris9/ee2eb15cb3f729bae69a84258caef1ff to your computer and use it in GitHub Desktop.
Save andris9/ee2eb15cb3f729bae69a84258caef1ff to your computer and use it in GitHub Desktop.
Generate onion v3 address from ed25519 public key
// npm install hi-base32 sha3
const base32 = require("hi-base32");
const { SHA3 } = require("sha3");
function verifyOnionAddress(addr) {
const suffixLength = ".onion".length;
if (!/\.onion$/i.test(addr) || addr.length != 56 + suffixLength) {
return false;
}
let base32Encoded = addr.substr(0, addr.length - suffixLength).toUpperCase();
let decoded;
try {
decoded = Buffer.from(base32.decode.asBytes(base32Encoded));
} catch (err) {
return false;
}
const version = decoded.slice(decoded.length - 1);
if (!version || !version[0] || version[0] !== 3) {
return false;
}
const checksum = decoded.slice(decoded.length - 3, decoded.length - 1);
const pubkey = decoded.slice(0, decoded.length - 3);
const hash = new SHA3(256);
hash.update(Buffer.from(".onion checksum"));
hash.update(pubkey);
hash.update(version);
const calculatedChecksum = hash.digest().slice(0, 2);
return calculatedChecksum.toString("hex") === checksum.toString("hex") ? pubkey : false;
}
function encodeOnionAddress(pubkey) {
const version = Buffer.from([0x03]);
const hash = new SHA3(256);
hash.update(Buffer.from(".onion checksum"));
hash.update(pubkey);
hash.update(version);
const checksum = hash.digest().slice(0, 2);
const decoded = Buffer.concat([pubkey, checksum, version]);
return base32.encode(Array.from(decoded)).toLowerCase() + ".onion";
}
let address = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
let publicKey = verifyOnionAddress(address);
console.log(encodeOnionAddress(publicKey));
console.log(encodeOnionAddress(publicKey) === address);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment