npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

spectrev4

v0.6.0

Published

Utilities around Master Password Algorithm (Spectre.app, by Maarten Billemont) and crypto, using Noble and Scure by Paul Miller. Stateless accounts & passwords, 2fa HOTP/TOTP, shamir secret sharing, crypto/bitcoin/nostr public and private keys, and more.

Downloads

29

Readme

cryptils npm version License Libera Manifesto

Code style bunning bitcoin ready nostr ready Make A Pull Request Time Since Last Commit

Utilities around Spectre / Master Password Algorithm (by Maarten Billemont), implemented in TypeScript, using Noble & Scure cryptography by @paulmillr. Used for deriving stateless accounts & passwords, 2fa, shamir secret sharing, crypto/bitcoin/nostr public and private keys, and more.

Highlights

  • Don't store, derive! Derive passwords and keys from a master password and a name
  • Cloud-less & storage-less password manager, stateless password derivation
  • Uses only audited Noble & Scure cryptography by @paulmillr
  • TypeScript implementation of Spectre.app / Master Password Algorithm by Maarten Billemont
  • Stateless account & password derivation - no need to store anything
  • Stateless wallet/keys derivation for Ethereum, Bitcoin, Litecoin, Vertcoin, Nostr
  • Support for splitting the secret key with Shamir Secret Sharing scheme
  • AES-256-GCM encrypt/decrypt a private thing using the secret key
  • Generate and validate 2FA tokens (HOTP & TOTP)
    • RFC 4226 & RFC 6238
    • support SHA-1, SHA-256, SHA-512 hashing algorithms
    • support different digits lengths, up to 10

Install

npm add cryptils
bun add cryptils
deno add npm:cryptils

Usage

import {
  bech32encode,
  deriveAccount,
  deriveCryptoAccount,
  deriveKeys,
  randomBytes,
  spectreV4,
  splitKeyToShares,
} from 'cryptils';

const usrName = 'wgw';
const passwd = 'secret master password';

// Derive password for `wgw` user on `twitter.com` and `github.com`,
const twitter = deriveAccount(usrName, passwd, 'twitter.com');
const github = deriveAccount(usrName, passwd, 'github.com');

// in addition to above, it uses the generated secret
// to derive crypto keys like ethereum address, bitcoin keys and nostr keys
const crypto_1 = deriveCryptoAccount(usrName, passwd, 'crypto.0');
const crypto_2 = deriveCryptoAccount(usrName, passwd, 'crypto.1');
const { secret: crypto_3_secret, ...crypto_3 } = spectreV4(usrName, passwd, 'crypto.2');

// deriveKeys is used inside `deriveCryptoKeys`, it's standalone function
const crypto_3_keys = deriveKeys(crypto_3_secret);

// Using Shamir Secret Sharing, split the secret into 3 keys and 5 shares
const crypto_3_keys_shares = await splitKeyToShares(crypto_3_secret, 3, 5);

const info = {
  twitter,
  github,
  crypto_1,
  crypto_2,
  crypto_3: { ...crypto_3, keys: crypto_3_keys, shares: crypto_3_keys_shares },
};

console.log();
console.log(JSON.stringify(info, null, 2));
console.log();

const rndSecret = randomBytes(32);
const otherKeys = deriveKeys(rndSecret);
console.log('other keys:', otherKeys);

// create Bitcoin bech32 bc1p address from a public key
const bc1p = bech32encode('bc', otherKeys.pubkey, true);
console.log('bc1p:', bc1p, bc1p === otherKeys.bitcoin);

Docs

Example with 2FA OTP

import {
  generateBase32Secret,
  getHotpToken,
  getTokenUri,
  getTotpToken,
  validateHotpToken,
  validateToken,
  validateTotpToken,
} from 'cryptils';
import qrcode from 'qrcode';

const secret = generateBase32Secret();
const token = await getTotpToken(secret);
const valid = await validateTotpToken(secret, token);

console.log({ secret, token, valid });

const hotpToken = await getHotpToken(secret);
console.log({ hotpToken, valid: await validateHotpToken(secret, hotpToken) });

Example with AES-256-GCM

import { decryptWithSecret, encryptWithSecret } from 'cryptils/aes';
import { spectreV4 } from 'cryptils/derive';
import { randomBytes } from 'cryptils/utils';

const account = spectreV4('usrname', 'foo pass bar', 'twt.com');

// or try with random one
const secret = randomBytes(32);

console.log({ account });

const encrypted = await encryptWithSecret(account.pass, account.secret);
const decrypted = await decryptWithSecret(encrypted, account.secret);

console.log({ encrypted, decrypted, same: decrypted === account.pass });

Types

export type SpectreOptions = { template?: string; hash?: any; iterations?: number };
export type SpectreResult = { secret: Uint8Array; name: string; user: string; pass: string };

export type HexString = string;
export type Input = Uint8Array | string;
export type SecretKey = Uint8Array | HexString;
export type HashAlgo = 'SHA-1' | 'SHA-256' | 'SHA-512' | string;
export type TokenResult = string;

export type KeysResult = {
  mnemonic: string;
  privkey: HexString;
  pubkey: HexString;
  npub: string; // npub1...abc
  nsec: string; // nsec1...abc
  nrepo: string; // nrepo1...abc
  ethereum: `0x${string}`; // 0x1987...abc
  bitcoin: string; // bc1p...abc
  litecoin: string; // ltc1p...abc
  vertcoin: string; // vtc1p...abc
};

LICENSE

SPDX-License-Identifier: MPL-2.0