ed25519-keygen
Advanced tools
Comparing version 0.2.0 to 0.2.1
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
throw new Error('The module has no entry-point: consult README for usage'); | ||
export {}; |
{ | ||
"name": "ed25519-keygen", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "Generate ed25519 keys deterministically for SSH, PGP (GPG) and TOR", | ||
"type": "module", | ||
"main": "index.js", | ||
"module": "index.js", | ||
"files": [ | ||
"src/index.ts", | ||
"index.js", | ||
"index.d.ts", | ||
"index.js", | ||
"esm/index.js", | ||
"index.d.ts.map", | ||
"src/pgp.ts", | ||
"pgp.js", | ||
"pgp.d.ts", | ||
"pgp.js", | ||
"esm/pgp.js", | ||
"pgp.d.ts.map", | ||
"src/ssh.ts", | ||
"ssh.js", | ||
"ssh.d.ts", | ||
"ssh.js", | ||
"esm/ssh.js", | ||
"ssh.d.ts.map", | ||
"src/tor.ts", | ||
"tor.js", | ||
"tor.d.ts", | ||
"tor.js", | ||
"esm/tor.js" | ||
"tor.d.ts.map" | ||
], | ||
"scripts": { | ||
"build": "tsc && tsc -p tsconfig.esm.json", | ||
"lint": "prettier --check index.ts", | ||
"test": "node test/index.js" | ||
}, | ||
"author": "Paul Miller (https://paulmillr.com)", | ||
"license": "MIT", | ||
"homepage": "https://github.com/paulmillr/ed25519-keygen", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/paulmillr/ed25519-keygen.git" | ||
}, | ||
"dependencies": { | ||
@@ -42,42 +37,49 @@ "@noble/ed25519": "^1.6.1", | ||
}, | ||
"keywords": [ | ||
"ed25519", | ||
"PGP", | ||
"GPG", | ||
"RFC 4880", | ||
"RFC 6637", | ||
"SSH", | ||
"TOR", | ||
"onion", | ||
"key generation", | ||
"ec", | ||
"elliptic" | ||
], | ||
"exports": { | ||
".": { | ||
"import": "./esm/index.js", | ||
"types": "./index.d.ts", | ||
"default": "./index.js" | ||
}, | ||
"./index.d.ts": "./index.d.ts", | ||
"./ssh": { | ||
"import": "./esm/ssh.js", | ||
"types": "./ssh.d.ts", | ||
"default": "./ssh.js" | ||
}, | ||
"./ssh.d.ts": "./ssh.d.ts", | ||
"./pgp": { | ||
"import": "./esm/pgp.js", | ||
"types": "./pgp.d.ts", | ||
"default": "./pgp.js" | ||
}, | ||
"./pgp.d.ts": "./pgp.d.ts", | ||
"./tor": { | ||
"import": "./esm/tor.js", | ||
"types": "./tor.d.ts", | ||
"default": "./tor.js" | ||
}, | ||
"./tor.d.ts": "./tor.d.ts", | ||
"./utils": { | ||
"import": "./esm/utils.js", | ||
"types": "./utils.d.ts", | ||
"default": "./utils.js" | ||
}, | ||
"./utils.d.ts": "./utils.d.ts" | ||
} | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"lint": "prettier --check index.ts", | ||
"test": "node test/index.js" | ||
}, | ||
"author": "Paul Miller (https://paulmillr.com)", | ||
"license": "MIT", | ||
"homepage": "https://github.com/paulmillr/ed25519-keygen", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/paulmillr/ed25519-keygen.git" | ||
}, | ||
"keywords": [ | ||
"ed25519", | ||
"PGP", | ||
"GPG", | ||
"RFC 4880", | ||
"RFC 6637", | ||
"SSH", | ||
"TOR", | ||
"onion", | ||
"key generation", | ||
"ec", | ||
"elliptic" | ||
], | ||
"funding": [ | ||
@@ -84,0 +86,0 @@ { |
@@ -65,1 +65,2 @@ import * as P from 'micro-packed'; | ||
export default getKeys; | ||
//# sourceMappingURL=pgp.d.ts.map |
105
pgp.js
@@ -1,15 +0,12 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getKeys = exports.formatPrivate = exports.formatPublic = exports.privArmor = exports.pubArmor = exports.decodeSecretKey = exports.Stream = exports.PacketLen = exports.oid = exports.opaquempi = exports.mpi = void 0; | ||
const ed25519 = require("@noble/ed25519"); | ||
const sha1_1 = require("@noble/hashes/sha1"); | ||
const ripemd160_1 = require("@noble/hashes/ripemd160"); | ||
const sha256_1 = require("@noble/hashes/sha256"); | ||
const sha512_1 = require("@noble/hashes/sha512"); | ||
const sha3_1 = require("@noble/hashes/sha3"); | ||
const utils_1 = require("@noble/hashes/utils"); | ||
const crypto_1 = require("@noble/hashes/crypto"); | ||
const P = require("micro-packed"); | ||
const micro_packed_1 = require("micro-packed"); | ||
const base_1 = require("@scure/base"); | ||
import * as ed25519 from '@noble/ed25519'; | ||
import { sha1 } from '@noble/hashes/sha1'; | ||
import { ripemd160 } from '@noble/hashes/ripemd160'; | ||
import { sha256 } from '@noble/hashes/sha256'; | ||
import { sha512 } from '@noble/hashes/sha512'; | ||
import { sha3_256 } from '@noble/hashes/sha3'; | ||
import { randomBytes } from '@noble/hashes/utils'; | ||
import { crypto } from '@noble/hashes/crypto'; | ||
import * as P from 'micro-packed'; | ||
import { concatBytes } from 'micro-packed'; | ||
import { utf8, hex } from '@scure/base'; | ||
function numberToHexUnpadded(num) { | ||
@@ -21,3 +18,3 @@ let hex = num.toString(16); | ||
function bytesToNumber(bytes) { | ||
return BigInt('0x' + base_1.hex.encode(bytes)); | ||
return BigInt('0x' + hex.encode(bytes)); | ||
} | ||
@@ -38,11 +35,11 @@ function equalBytes(a, b) { | ||
throw new Error('Invalid key length'); | ||
if (crypto_1.crypto.web) { | ||
if (crypto.web) { | ||
const mode = { name: `AES-CBC`, length: key.length * 8 }; | ||
const wKey = await crypto_1.crypto.web.subtle.importKey('raw', key, mode, true, ['encrypt']); | ||
const cipher = await crypto_1.crypto.web.subtle.encrypt({ name: `aes-cbc`, iv: IV, counter: IV, length: 64 }, wKey, msg); | ||
const wKey = await crypto.web.subtle.importKey('raw', key, mode, true, ['encrypt']); | ||
const cipher = await crypto.web.subtle.encrypt({ name: `aes-cbc`, iv: IV, counter: IV, length: 64 }, wKey, msg); | ||
return new Uint8Array(cipher).subarray(0, 16); | ||
} | ||
else if (crypto_1.crypto.node) { | ||
else if (crypto.node) { | ||
const mode = key.length === 32 ? 'aes-256-cbc' : 'aes-128-cbc'; | ||
return crypto_1.crypto.node.createCipheriv(mode, key, IV).update(msg).subarray(0, 16); | ||
return crypto.node.createCipheriv(mode, key, IV).update(msg).subarray(0, 16); | ||
} | ||
@@ -69,3 +66,3 @@ else { | ||
} | ||
return (0, micro_packed_1.concatBytes)(...blocks); | ||
return concatBytes(...blocks); | ||
} | ||
@@ -78,3 +75,3 @@ function createAesCfb(len) { | ||
} | ||
exports.mpi = P.wrap({ | ||
export const mpi = P.wrap({ | ||
encodeStream: (w, value) => { | ||
@@ -85,7 +82,7 @@ let bitLen = 0; | ||
P.U16BE.encodeStream(w, bitLen); | ||
w.bytes(base_1.hex.decode(numberToHexUnpadded(value))); | ||
w.bytes(hex.decode(numberToHexUnpadded(value))); | ||
}, | ||
decodeStream: (r) => bytesToNumber(r.bytes((P.U16BE.decodeStream(r) + 7) >>> 3)), | ||
}); | ||
exports.opaquempi = P.wrap({ | ||
export const opaquempi = P.wrap({ | ||
encodeStream: (w, value) => { | ||
@@ -99,3 +96,3 @@ P.U16BE.encodeStream(w, value.length * 8); | ||
const OID_NO_MSB = 2 ** 7 - 1; | ||
exports.oid = P.wrap({ | ||
export const oid = P.wrap({ | ||
encodeStream: (w, value) => { | ||
@@ -130,3 +127,3 @@ const items = value.split('.').map((i) => +i); | ||
}); | ||
exports.PacketLen = P.wrap({ | ||
export const PacketLen = P.wrap({ | ||
encodeStream: (w, value) => { | ||
@@ -168,3 +165,3 @@ if (typeof value !== 'number') | ||
}); | ||
const ECEnum = P.map(P.prefix(P.U8, exports.oid), { | ||
const ECEnum = P.map(P.prefix(P.U8, oid), { | ||
nistP256: '1.2.840.10045.3.1.7', | ||
@@ -191,3 +188,3 @@ nistP384: '1.3.132.0.34', | ||
}); | ||
const Hash = { ripemd160: ripemd160_1.ripemd160, sha256: sha256_1.sha256, sha512: sha512_1.sha512, sha3_256: sha3_1.sha3_256, sha1: sha1_1.sha1 }; | ||
const Hash = { ripemd160, sha256, sha512, sha3_256, sha1 }; | ||
const EncryptionEnum = P.map(P.U8, { | ||
@@ -227,6 +224,6 @@ plaintext: 0, | ||
}); | ||
const ECDSAPub = P.struct({ curve: ECEnum, pub: exports.mpi }); | ||
const ECDSAPub = P.struct({ curve: ECEnum, pub: mpi }); | ||
const ECDHPub = P.struct({ | ||
curve: ECEnum, | ||
pub: exports.mpi, | ||
pub: mpi, | ||
params: P.prefix(P.U8, P.struct({ | ||
@@ -302,3 +299,3 @@ magic: P.magic(P.hex(1), '01'), | ||
}); | ||
const SignatureSubpacket = P.prefix(exports.PacketLen, P.tag(signatureSubpacket, { | ||
const SignatureSubpacket = P.prefix(PacketLen, P.tag(signatureSubpacket, { | ||
issuerFingerprint: P.struct({ version: PGP_PACKET_VERSION, fingerprint: P.hex(20) }), | ||
@@ -337,3 +334,3 @@ signatureCreationTime: P.U32BE, | ||
hashPrefix: P.bytes(2), | ||
sig: P.array(null, exports.mpi), | ||
sig: P.array(null, mpi), | ||
}); | ||
@@ -344,3 +341,3 @@ const UserPacket = P.string(null); | ||
count = count === undefined ? 0 : EXPBIAS6(count); | ||
const data = salt ? (0, micro_packed_1.concatBytes)(salt, password) : password; | ||
const data = salt ? concatBytes(salt, password) : password; | ||
let out = new Uint8Array([]); | ||
@@ -360,3 +357,3 @@ const hashC = Hash[hash]; | ||
} | ||
out = (0, micro_packed_1.concatBytes)(h.digest()); | ||
out = concatBytes(h.digest()); | ||
} | ||
@@ -396,3 +393,3 @@ return out.subarray(0, len); | ||
} | ||
const getFingerprint = (pubKey) => base_1.hex.encode((0, sha1_1.sha1)(hashPubKey.encode({ pubKey }))); | ||
const getFingerprint = (pubKey) => hex.encode(sha1(hashPubKey.encode({ pubKey }))); | ||
const getKeyId = (fp) => fp.slice(-16); | ||
@@ -457,3 +454,3 @@ function crc24(data) { | ||
}); | ||
exports.Stream = P.array(null, Packet); | ||
export const Stream = P.array(null, Packet); | ||
const EDSIGN = P.array(null, P.U256BE); | ||
@@ -466,3 +463,3 @@ async function signData(head, unhashed, data, privateKey) { | ||
} | ||
async function decodeSecretKey(password, key) { | ||
export async function decodeSecretKey(password, key) { | ||
if (key.s2k_type !== 254) | ||
@@ -474,3 +471,3 @@ throw new Error(`PGP.secretKey Unsupported s2k_type=${key.s2k_type}`); | ||
throw new Error(`PGP.secretKey: unknown encryption mode=${key.enc}`); | ||
const encKey = deriveKey(data.hash, keyLen, base_1.utf8.decode(password), data.salt, data.count); | ||
const encKey = deriveKey(data.hash, keyLen, utf8.decode(password), data.salt, data.count); | ||
const decrypted = await Encryption[key.enc].decrypt(key.secret, encKey, key.iv); | ||
@@ -483,5 +480,4 @@ const decryptedKey = decrypted.subarray(0, -20); | ||
throw new Error(`PGP.secretKey unsupported publicKey algorithm: ${key.pub.algo.TAG}`); | ||
return exports.mpi.decode(decryptedKey); | ||
return mpi.decode(decryptedKey); | ||
} | ||
exports.decodeSecretKey = decodeSecretKey; | ||
async function createPrivKey(pub, key, password, salt, iv, hash = 'sha1', count = 240, enc = 'aes128') { | ||
@@ -491,5 +487,5 @@ const keyLen = EncryptionKeySize[enc]; | ||
throw new Error(`PGP.secretKey: unknown encryption mode=${enc}`); | ||
const encKey = deriveKey(hash, keyLen, base_1.utf8.decode(password), salt, count); | ||
const keyBytes = exports.opaquempi.encode(key); | ||
const secretClear = (0, micro_packed_1.concatBytes)(keyBytes, (0, sha1_1.sha1)(keyBytes)); | ||
const encKey = deriveKey(hash, keyLen, utf8.decode(password), salt, count); | ||
const keyBytes = opaquempi.encode(key); | ||
const secretClear = concatBytes(keyBytes, sha1(keyBytes)); | ||
const secret = await Encryption[enc].encrypt(secretClear, encKey, iv); | ||
@@ -499,6 +495,6 @@ const S2K = { TAG: 'iterated', data: { hash, salt, count } }; | ||
} | ||
exports.pubArmor = P.base64armor('PGP PUBLIC KEY BLOCK', 64, exports.Stream, crc24); | ||
exports.privArmor = P.base64armor('PGP PRIVATE KEY BLOCK', 64, exports.Stream, crc24); | ||
export const pubArmor = P.base64armor('PGP PUBLIC KEY BLOCK', 64, Stream, crc24); | ||
export const privArmor = P.base64armor('PGP PRIVATE KEY BLOCK', 64, Stream, crc24); | ||
async function getPublicPackets(edPriv, cvPriv, created = 0) { | ||
const edPub = bytesToNumber((0, micro_packed_1.concatBytes)(new Uint8Array([0x40]), await ed25519.getPublicKey(edPriv))); | ||
const edPub = bytesToNumber(concatBytes(new Uint8Array([0x40]), await ed25519.getPublicKey(edPriv))); | ||
const edPubPacket = { | ||
@@ -509,3 +505,3 @@ created, | ||
const cvPoint = ed25519.curve25519.scalarMultBase(cvPriv); | ||
const cvPub = bytesToNumber((0, micro_packed_1.concatBytes)(new Uint8Array([0x40]), cvPoint)); | ||
const cvPub = bytesToNumber(concatBytes(new Uint8Array([0x40]), cvPoint)); | ||
const cvPubPacket = { | ||
@@ -556,5 +552,5 @@ created, | ||
} | ||
async function formatPublic(edPriv, cvPriv, user, created = 0) { | ||
export async function formatPublic(edPriv, cvPriv, user, created = 0) { | ||
const { edPubPacket, cvPubPacket, edCert, cvCert } = await getCerts(edPriv, cvPriv, user, created); | ||
return exports.pubArmor.encode([ | ||
return pubArmor.encode([ | ||
{ TAG: 'publicKey', data: edPubPacket }, | ||
@@ -567,4 +563,3 @@ { TAG: 'userId', data: user }, | ||
} | ||
exports.formatPublic = formatPublic; | ||
async function formatPrivate(edPriv, cvPriv, user, password, created = 0, edSalt = (0, utils_1.randomBytes)(8), edIV = (0, utils_1.randomBytes)(16), cvSalt = (0, utils_1.randomBytes)(8), cvIV = (0, utils_1.randomBytes)(16)) { | ||
export async function formatPrivate(edPriv, cvPriv, user, password, created = 0, edSalt = randomBytes(8), edIV = randomBytes(16), cvSalt = randomBytes(8), cvIV = randomBytes(16)) { | ||
const { edPubPacket, cvPubPacket, edCert, cvCert } = await getCerts(edPriv, cvPriv, user, created); | ||
@@ -574,3 +569,3 @@ const edSecret = await createPrivKey(edPubPacket, edPriv, password, edSalt, edIV); | ||
const cvSecret = await createPrivKey(cvPubPacket, cvPrivLE, password, cvSalt, cvIV); | ||
return exports.privArmor.encode([ | ||
return privArmor.encode([ | ||
{ TAG: 'secretKey', data: edSecret }, | ||
@@ -583,4 +578,3 @@ { TAG: 'userId', data: user }, | ||
} | ||
exports.formatPrivate = formatPrivate; | ||
async function getKeys(privKey, user, password, created = 0) { | ||
export async function getKeys(privKey, user, password, created = 0) { | ||
const { keyId } = await getPublicPackets(privKey, privKey, created); | ||
@@ -592,3 +586,2 @@ const { head: cvPrivate } = await ed25519.utils.getExtendedPublicKey(privKey); | ||
} | ||
exports.getKeys = getKeys; | ||
exports.default = getKeys; | ||
export default getKeys; |
@@ -44,1 +44,2 @@ import * as P from 'micro-packed'; | ||
export default getKeys; | ||
//# sourceMappingURL=ssh.d.ts.map |
83
ssh.js
@@ -1,53 +0,48 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.authSign = exports.getKeys = exports.getFingerprint = exports.formatPublicKey = exports.PrivateExport = exports.AuthData = exports.PublicKey = exports.SSHKeyType = exports.SSHBuf = exports.SSHString = void 0; | ||
const ed25519 = require("@noble/ed25519"); | ||
const sha256_1 = require("@noble/hashes/sha256"); | ||
const micro_packed_1 = require("micro-packed"); | ||
const P = require("micro-packed"); | ||
const base_1 = require("@scure/base"); | ||
const utils_1 = require("@noble/hashes/utils"); | ||
exports.SSHString = P.string(P.U32BE); | ||
exports.SSHBuf = P.bytes(P.U32BE); | ||
exports.SSHKeyType = P.magic(exports.SSHString, 'ssh-ed25519'); | ||
exports.PublicKey = P.struct({ keyType: exports.SSHKeyType, pubKey: P.bytes(P.U32BE) }); | ||
import * as ed25519 from '@noble/ed25519'; | ||
import { sha256 } from '@noble/hashes/sha256'; | ||
import { concatBytes } from 'micro-packed'; | ||
import * as P from 'micro-packed'; | ||
import { base64 } from '@scure/base'; | ||
import { randomBytes } from '@noble/hashes/utils'; | ||
export const SSHString = P.string(P.U32BE); | ||
export const SSHBuf = P.bytes(P.U32BE); | ||
export const SSHKeyType = P.magic(SSHString, 'ssh-ed25519'); | ||
export const PublicKey = P.struct({ keyType: SSHKeyType, pubKey: P.bytes(P.U32BE) }); | ||
const PrivateKey = P.padRight(8, P.struct({ | ||
check1: P.bytes(4), | ||
check2: P.bytes(4), | ||
keyType: exports.SSHKeyType, | ||
pubKey: exports.SSHBuf, | ||
privKey: exports.SSHBuf, | ||
comment: exports.SSHString, | ||
keyType: SSHKeyType, | ||
pubKey: SSHBuf, | ||
privKey: SSHBuf, | ||
comment: SSHString, | ||
}), (i) => i + 1); | ||
exports.AuthData = P.struct({ | ||
nonce: exports.SSHBuf, | ||
export const AuthData = P.struct({ | ||
nonce: SSHBuf, | ||
userAuthRequest: P.U8, | ||
user: exports.SSHString, | ||
conn: exports.SSHString, | ||
auth: exports.SSHString, | ||
user: SSHString, | ||
conn: SSHString, | ||
auth: SSHString, | ||
haveSig: P.U8, | ||
keyType: exports.SSHKeyType, | ||
pubKey: P.prefix(P.U32BE, exports.PublicKey), | ||
keyType: SSHKeyType, | ||
pubKey: P.prefix(P.U32BE, PublicKey), | ||
}); | ||
exports.PrivateExport = P.base64armor('openssh private key', 70, P.struct({ | ||
export const PrivateExport = P.base64armor('openssh private key', 70, P.struct({ | ||
magic: P.magicBytes('openssh-key-v1\0'), | ||
ciphername: P.magic(exports.SSHString, 'none'), | ||
kdfname: P.magic(exports.SSHString, 'none'), | ||
kdfopts: P.magic(exports.SSHString, ''), | ||
ciphername: P.magic(SSHString, 'none'), | ||
kdfname: P.magic(SSHString, 'none'), | ||
kdfopts: P.magic(SSHString, ''), | ||
keys: P.array(P.U32BE, P.struct({ | ||
pubKey: P.prefix(P.U32BE, exports.PublicKey), | ||
pubKey: P.prefix(P.U32BE, PublicKey), | ||
privKey: P.prefix(P.U32BE, PrivateKey), | ||
})), | ||
})); | ||
function formatPublicKey(bytes, comment) { | ||
const blob = exports.PublicKey.encode({ pubKey: bytes }); | ||
return `ssh-ed25519 ${base_1.base64.encode(blob)}${comment ? ` ${comment}` : ''}`; | ||
export function formatPublicKey(bytes, comment) { | ||
const blob = PublicKey.encode({ pubKey: bytes }); | ||
return `ssh-ed25519 ${base64.encode(blob)}${comment ? ` ${comment}` : ''}`; | ||
} | ||
exports.formatPublicKey = formatPublicKey; | ||
function getFingerprint(bytes) { | ||
const blob = exports.PublicKey.encode({ pubKey: bytes }); | ||
return `SHA256:${base_1.base64.encode((0, sha256_1.sha256)(blob)).replace(/=$/, '')}`; | ||
export function getFingerprint(bytes) { | ||
const blob = PublicKey.encode({ pubKey: bytes }); | ||
return `SHA256:${base64.encode(sha256(blob)).replace(/=$/, '')}`; | ||
} | ||
exports.getFingerprint = getFingerprint; | ||
async function getKeys(privateKey, comment, checkBytes = (0, utils_1.randomBytes)(4)) { | ||
export async function getKeys(privateKey, comment, checkBytes = randomBytes(4)) { | ||
const pubKey = await ed25519.getPublicKey(privateKey); | ||
@@ -58,3 +53,3 @@ return { | ||
fingerprint: getFingerprint(pubKey), | ||
privateKey: exports.PrivateExport.encode({ | ||
privateKey: PrivateExport.encode({ | ||
keys: [ | ||
@@ -67,3 +62,3 @@ { | ||
pubKey, | ||
privKey: (0, micro_packed_1.concatBytes)(privateKey, pubKey), | ||
privKey: concatBytes(privateKey, pubKey), | ||
comment: comment || '', | ||
@@ -76,7 +71,5 @@ }, | ||
} | ||
exports.getKeys = getKeys; | ||
function authSign(privateKey, data) { | ||
return ed25519.sign(exports.AuthData.encode(data), privateKey); | ||
export function authSign(privateKey, data) { | ||
return ed25519.sign(AuthData.encode(data), privateKey); | ||
} | ||
exports.authSign = authSign; | ||
exports.default = getKeys; | ||
export default getKeys; |
@@ -9,1 +9,2 @@ export declare function formatPublicKey(pubBytes: Uint8Array): string; | ||
export default getKeys; | ||
//# sourceMappingURL=tor.d.ts.map |
34
tor.js
@@ -1,19 +0,15 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getKeys = exports.parseAddress = exports.formatPublicKey = void 0; | ||
const ed25519 = require("@noble/ed25519"); | ||
const sha3_1 = require("@noble/hashes/sha3"); | ||
const base_1 = require("@scure/base"); | ||
const micro_packed_1 = require("micro-packed"); | ||
import * as ed25519 from '@noble/ed25519'; | ||
import { sha3_256 } from '@noble/hashes/sha3'; | ||
import { utf8, base32, base64 } from '@scure/base'; | ||
import { concatBytes } from 'micro-packed'; | ||
const ADDRESS_VERSION = new Uint8Array([0x03]); | ||
function formatPublicKey(pubBytes) { | ||
const checksum = (0, sha3_1.sha3_256)((0, micro_packed_1.concatBytes)(base_1.utf8.decode('.onion checksum'), pubBytes, ADDRESS_VERSION)); | ||
const addr = (0, micro_packed_1.concatBytes)(pubBytes, checksum.slice(0, 2), ADDRESS_VERSION); | ||
return `${base_1.base32.encode(addr).toLowerCase()}.onion`; | ||
export function formatPublicKey(pubBytes) { | ||
const checksum = sha3_256(concatBytes(utf8.decode('.onion checksum'), pubBytes, ADDRESS_VERSION)); | ||
const addr = concatBytes(pubBytes, checksum.slice(0, 2), ADDRESS_VERSION); | ||
return `${base32.encode(addr).toLowerCase()}.onion`; | ||
} | ||
exports.formatPublicKey = formatPublicKey; | ||
function parseAddress(address) { | ||
export function parseAddress(address) { | ||
if (!address.endsWith('.onion')) | ||
throw new Error('Address must end with .onion'); | ||
const addr = base_1.base32.decode(address.replace(/\.onion$/, '').toUpperCase()); | ||
const addr = base32.decode(address.replace(/\.onion$/, '').toUpperCase()); | ||
const skip = addr.slice(0, addr.length - 3); | ||
@@ -25,13 +21,11 @@ const key = formatPublicKey(skip); | ||
} | ||
exports.parseAddress = parseAddress; | ||
async function getKeys(seed) { | ||
export async function getKeys(seed) { | ||
const { head, prefix, pointBytes } = await ed25519.utils.getExtendedPublicKey(seed); | ||
const added = (0, micro_packed_1.concatBytes)(head, prefix); | ||
const added = concatBytes(head, prefix); | ||
return { | ||
publicKeyBytes: pointBytes, | ||
publicKey: formatPublicKey(pointBytes), | ||
privateKey: `ED25519-V3:${base_1.base64.encode(added)}`, | ||
privateKey: `ED25519-V3:${base64.encode(added)}`, | ||
}; | ||
} | ||
exports.getKeys = getKeys; | ||
exports.default = getKeys; | ||
export default getKeys; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
65701
18
1560
Yes
1