Skip to content

Instantly share code, notes, and snippets.

@paulmillr
paulmillr / inp-nacl.mjs
Created April 23, 2024 16:08
noble vs tweetnacl
export { box_keyPair, sign_detached_verify, sign, box, box_open } from 'tweetnacl-ts';
@paulmillr
paulmillr / metamask-sign.md
Last active September 10, 2023 13:36
Tracing cryptography in Metamask dependencies

Tracing cryptography in Metamask dependencies

Metamask uses noble for low-level cryptography operations, such as signature creation. The audit path as per Sep 2023, where every item is name of NPM package:

flowchart TD;
    MM[metamask-extension] -->|imports KeyringController| MMKC["@metamask/keyring-controller"];
    MMKC -->|imports HDKeyring| MMHD["@metamask/eth-hd-keyring"];
 MMKC -->|imports SimpleKeyring| MMSK["@metamask/eth-simple-keyring"];
@paulmillr
paulmillr / noble-vs-elliptic.js
Last active July 26, 2023 08:29
Timing differences between different keys in noble and elliptic
import { secp256k1 } from '@noble/curves/secp256k1';
import elliptic from 'elliptic';
import { mark } from 'micro-bmark';
const EC = elliptic.ec;
(async () => {
var ec = new EC('secp256k1');
const a = '0000000000000000000000000000000000000000000000000000000000000003';
const b = '3000000000000000000000000000000000000000000000000000000000000000';
@paulmillr
paulmillr / hybrid-pkg.md
Last active February 10, 2024 17:45
Why writing hybrid Common.js + ESM NPM packages is hard
  • BigInt literals (15n) are not supported in some environments
    • Must use BigInt('15') instead
    • It was not supported in React Native 0.70. Need to test in new versions
  • Must use hybrid ESM-Common.js package
    • ESM (ECMAScript modules) are not supported in Electron, Jest
      • Electron needs pre-compilation step aka bundler
      • Jest has experimental esm flag, also can be replaced with micro-should
    • Common.js modules (legacy node.js modules) are not supported in browsers, Deno
      • Browsers can be worked around with UMD wrapper
  • Doesn’t play well with ESM in-browser imports
@paulmillr
paulmillr / guide.md
Last active November 4, 2023 15:22
Sign git commits with ssh key

Sign git commits with ssh key

  • git version must be >= 2.34. Earlier versions don't support gpg.format ssh (signing commits with ssh keys).

    If you're printing signature keys in git log by using %GK %GF %GP %GT in git.format.pretty, earlier versions will crash when doing git log with following error:

    BUG: gpg-interface.c:284: bad signature

  • OpenSSH version must be >= 8.8. Earlier versions don't support valid-after,valid-before options.

Fun parts of developing noble-hashes and scure-base

  • Base58 is quadratic (O(n^2)). Basically you can’t encode 1MB of data with it. This has been found with our DoS tests, which we employ for scure-base and noble-hashes. See README for more details
  • Hashes are additionally tested against huge multi-gig inputs, scrypt/pbkdf2 are tested against all possible combination of options. They take 2 hours to run on a decent machine
  • Hashes are actually faster than many wasm alternatives. A single sha256 hashing of 32 bytes of data takes 888 nanoseconds on mac with M1
  • The last fact is extremely remarkable, because we do not employ loop unrolls in the code. A loop unroll is when you’re writing code which could have been executed in loop like for (let step = 0; step < 64), but instead, you’re writing every iteration step-by-step. Which incr
@paulmillr
paulmillr / unrolled-noble-sha3.ts
Last active September 2, 2022 11:32
Replace sha3.js in node_modules/@noble/hashes with unrolled-sha3.js
const rotlHs = (h: string, l: string, s: number) =>
s > 32 ? `(${l} << ${s - 32}) | (${h} >>> ${64 - s})` : `(${h} << ${s}) | (${l} >>> ${32 - s})`;
const rotlLs = (h: string, l: string, s: number) =>
s > 32 ? `(${h} << ${s - 32}) | (${l} >>> ${64 - s})` : `(${l} << ${s}) | (${h} >>> ${32 - s})`;
export const keccakP = (() => {
let out = 'let h, l, s = state;\n';
const vars = [];
for (let i = 0; i < 200 / 4; i++) vars.push(`s${i} = s[${i}]`);
out += `let ${vars.join(', ')};\n`;
@paulmillr
paulmillr / pgp_proof.txt
Last active July 2, 2022 22:49
PGP verification
Proving ownership of
- paulmillr.com/pgp_proof.txt via paulmillr.com/pgp_proof.txt.asc
- twitter.com/paulmillr
- github.com/paulmillr via gist.github.com/paulmillr/cb3ad3b9cd4ac849eb1def3634f93421
- Active key: Paul Miller (PGP 697079DA6878B89B) from 3 Jul 2022
- Revoked key: Paul Miller (PGP 46BEEF337A641ABB) was active from 15 Apr 2020 to 2 Jul 2022
Full pubkey:

Hal Finney's explanation of secp256k1 "efficiently computable endomorphism" parameters used secp256k1 libraries, archived from source.

The same optimization could be applied to any Koblitz curve (e.g. Short Weistrass curve with a=0).


I implemented an optimized ECDSA verify for the secp256k1 curve, based on pages 125-129 of the Guide to Elliptic Curve Cryptography, by Hankerson, Menezes and Vanstone. I own the book but I also found a PDF on a Russian site which is more convenient.

secp256k1 uses the following prime for its x and y coordinates:

@paulmillr
paulmillr / BLS_Signature.md
Last active December 17, 2024 15:13
BLS Signature for Busy People

BLS Signature for Busy People

Summary

  • BLS stands for

    • Barreto-Lynn-Scott: BLS12, a Pairing Friendly Elliptic Curve.
    • Boneh-Lynn-Shacham: A Signature Scheme.
  • Signature Aggregation

  • It is possible to verify n aggregate signatures on the same message with just 2 pairings instead of n+1.