{"id":13632877,"url":"https://github.com/paulmillr/noble-curves","last_synced_at":"2025-05-13T19:04:17.450Z","repository":{"id":64216921,"uuid":"573750299","full_name":"paulmillr/noble-curves","owner":"paulmillr","description":"Audited \u0026 minimal JS implementation of elliptic curve cryptography.","archived":false,"fork":false,"pushed_at":"2025-04-30T03:17:13.000Z","size":17795,"stargazers_count":765,"open_issues_count":13,"forks_count":75,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-05T11:13:00.428Z","etag":null,"topics":["bitcoin","bls12-381","bn128","bn254","crypto","cryptography","ecdsa","ed25519","ed448","eddsa","elliptic-curve-cryptography","elliptic-curves","ethereum","jubjub","noble","p256","p384","p521","secp256k1","x448"],"latest_commit_sha":null,"homepage":"https://paulmillr.com/noble","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paulmillr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/funding.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/2023-01-trailofbits-audit-curves.pdf","citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"paulmillr"}},"created_at":"2022-12-03T10:08:21.000Z","updated_at":"2025-05-04T07:41:17.000Z","dependencies_parsed_at":"2024-01-02T08:47:37.748Z","dependency_job_id":"38f8c123-c1e9-4e5d-86bb-2d17466e3e4c","html_url":"https://github.com/paulmillr/noble-curves","commit_stats":{"total_commits":548,"total_committers":17,"mean_commits":32.23529411764706,"dds":0.05656934306569339,"last_synced_commit":"301cb9cbfbd99ba22f0657e923cd296b824d17e2"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-curves","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-curves/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-curves/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-curves/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulmillr","download_url":"https://codeload.github.com/paulmillr/noble-curves/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010798,"owners_count":21998993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","bls12-381","bn128","bn254","crypto","cryptography","ecdsa","ed25519","ed448","eddsa","elliptic-curve-cryptography","elliptic-curves","ethereum","jubjub","noble","p256","p384","p521","secp256k1","x448"],"created_at":"2024-08-01T22:03:21.425Z","updated_at":"2025-05-13T19:04:17.441Z","avatar_url":"https://github.com/paulmillr.png","language":"JavaScript","funding_links":["https://github.com/sponsors/paulmillr"],"categories":["TypeScript","JavaScript Libraries","Frameworks and Libs","Cryptography \u0026 TLS"],"sub_categories":["JavaScript"],"readme":"# noble-curves\n\nAudited \u0026 minimal JS implementation of elliptic curve cryptography.\n\n- 🔒 [**Audited**](#security) by independent security firms\n- 🔻 Tree-shakeable: unused code is excluded from your builds\n- 🏎 Fast: hand-optimized for caveats of JS engines\n- 🔍 Reliable: cross-library / wycheproof tests and fuzzing ensure correctness\n- ➰ Short Weierstrass, Edwards, Montgomery curves\n- ✍️ ECDSA, EdDSA, Schnorr, BLS, ECDH, hashing to curves, Poseidon ZK-friendly hash\n- 🔖 SUF-CMA, SBS (non-repudiation), ZIP215 (consensus friendliness) features for ed25519 \u0026 ed448\n- 🪶 93KB (36KB gzipped) for everything with hashes, 26KB (11KB gzipped) for single-curve build\n\nCurves have 4KB sister projects\n[secp256k1](https://github.com/paulmillr/noble-secp256k1) \u0026 [ed25519](https://github.com/paulmillr/noble-ed25519).\nThey have smaller attack surface, but less features.\n\nTake a glance at [GitHub Discussions](https://github.com/paulmillr/noble-curves/discussions) for questions and support.\n\n### This library belongs to _noble_ cryptography\n\n\u003e **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n- All libraries:\n  [ciphers](https://github.com/paulmillr/noble-ciphers),\n  [curves](https://github.com/paulmillr/noble-curves),\n  [hashes](https://github.com/paulmillr/noble-hashes),\n  [post-quantum](https://github.com/paulmillr/noble-post-quantum),\n  4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /\n  [ed25519](https://github.com/paulmillr/noble-ed25519)\n- [Check out homepage](https://paulmillr.com/noble/)\n  for reading resources, documentation and apps built with noble\n\n## Usage\n\n\u003e `npm install @noble/curves`\n\n\u003e `deno add jsr:@noble/curves`\n\n\u003e `deno doc jsr:@noble/curves` # command-line documentation\n\nWe support all major platforms and runtimes.\nFor React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).\nA standalone file [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.\n\n```ts\n// import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size\nimport { secp256k1, schnorr } from '@noble/curves/secp256k1';\nimport { ed25519, ed25519ph, ed25519ctx, x25519 } from '@noble/curves/ed25519';\nimport { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';\nimport { p256, p384, p521 } from '@noble/curves/nist';\nimport { bls12_381 } from '@noble/curves/bls12-381';\nimport { bn254 } from '@noble/curves/bn254';\nimport { jubjub, babyjubjub } from '@noble/curves/misc';\nimport { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils';\n```\n\n- [ECDSA signatures over secp256k1 and others](#ecdsa-signatures-over-secp256k1-and-others)\n- [Hedged ECDSA with noise](#hedged-ecdsa-with-noise)\n- [ECDH: Diffie-Hellman shared secrets](#ecdh-diffie-hellman-shared-secrets)\n- [secp256k1 Schnorr signatures from BIP340](#secp256k1-schnorr-signatures-from-bip340)\n- [ed25519](#ed25519) / [X25519](#x25519) / [ristretto255](#ristretto255)\n- [ed448](#ed448) / [X448](#x448) / [decaf448](#decaf448)\n- [bls12-381](#bls12-381)\n- [bn254 aka alt_bn128](#bn254-aka-alt_bn128)\n- [misc curves](#misc-curves)\n- [Low-level methods](#low-level-methods)\n- [Abstract API](#abstract-api)\n  - [weierstrass](#weierstrass-short-weierstrass-curve), [edwards](#edwards-twisted-edwards-curve), [montgomery](#montgomery-montgomery-curve), [bls](#bls-barreto-lynn-scott-curves)\n  - [hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points), [poseidon](#poseidon-poseidon-hash)\n  - [modular](#modular-modular-arithmetics-utilities), [utils](#utils-useful-utilities)\n- [Security](#security)\n- [Speed](#speed)\n- [Upgrading](#upgrading)\n- [Contributing \u0026 testing](#contributing--testing)\n- [License](#license)\n\n### Implementations\n\n#### ECDSA signatures over secp256k1 and others\n\n```ts\nimport { secp256k1 } from '@noble/curves/secp256k1';\n// import { p256 } from '@noble/curves/nist'; // or p384 / p521\n\nconst priv = secp256k1.utils.randomPrivateKey();\nconst pub = secp256k1.getPublicKey(priv);\nconst msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa\nconst sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available\nconst isValid = secp256k1.verify(sig, msg, pub) === true;\n\n// hex strings are also supported besides Uint8Array-s:\nconst privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';\nconst pub2 = secp256k1.getPublicKey(privHex);\n\n// public key recovery\n// let sig = secp256k1.Signature.fromCompact(sigHex); // or .fromDER(sigDERHex)\n// sig = sig.addRecoveryBit(bit); // bit is not serialized into compact / der format\nsig.recoverPublicKey(msg).toRawBytes(); // === pub; // public key recovery\n```\n\nThe same code would work for NIST P256 (secp256r1), P384 (secp384r1) \u0026 P521 (secp521r1).\n\n#### Hedged ECDSA with noise\n\n```ts\nconst noisySignature = secp256k1.sign(msg, priv, { extraEntropy: true });\nconst ent = new Uint8Array(32).fill(3); // set custom entropy\nconst noisySignature2 = secp256k1.sign(msg, priv, { extraEntropy: ent });\n```\n\nHedged ECDSA is add-on, providing improved protection against fault attacks.\nIt adds noise to signatures. The technique is used by default in BIP340; we also implement them\noptionally for ECDSA. Check out blog post\n[Deterministic signatures are not your friends](https://paulmillr.com/posts/deterministic-signatures/)\nand [spec draft](https://datatracker.ietf.org/doc/draft-irtf-cfrg-det-sigs-with-noise/).\n\n#### ECDH: Diffie-Hellman shared secrets\n\n```ts\nconst someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());\nconst shared = secp256k1.getSharedSecret(priv, someonesPub);\n// NOTE:\n// - `shared` includes parity byte: strip it using shared.slice(1)\n// - `shared` is not hashed: more secure way is sha256(shared) or hkdf(shared)\n```\n\n#### secp256k1 Schnorr signatures from BIP340\n\n```ts\nimport { schnorr } from '@noble/curves/secp256k1';\nconst priv = schnorr.utils.randomPrivateKey();\nconst pub = schnorr.getPublicKey(priv);\nconst msg = new TextEncoder().encode('hello');\nconst sig = schnorr.sign(msg, priv);\nconst isValid = schnorr.verify(sig, msg, pub);\n```\n\n#### ed25519\n\n```ts\nimport { ed25519 } from '@noble/curves/ed25519';\nconst priv = ed25519.utils.randomPrivateKey();\nconst pub = ed25519.getPublicKey(priv);\nconst msg = new TextEncoder().encode('hello');\nconst sig = ed25519.sign(msg, priv);\ned25519.verify(sig, msg, pub); // Default mode: follows ZIP215\ned25519.verify(sig, msg, pub, { zip215: false }); // SBS / e-voting / RFC8032 / FIPS 186-5\n\n// Variants from RFC8032: with context, prehashed\nimport { ed25519ctx, ed25519ph } from '@noble/curves/ed25519';\n```\n\nDefault `verify` behavior follows ZIP215 and\ncan be used in consensus-critical applications.\nIf you need SBS (Strongly Binding Signatures) and FIPS 186-5 compliance,\nuse `zip215: false`. Check out [Edwards Signatures section for more info](#edwards-twisted-edwards-curve).\nBoth options have SUF-CMA (strong unforgeability under chosen message attacks).\n\n#### X25519\n\n```ts\n// X25519 aka ECDH on Curve25519 from [RFC7748](https://www.rfc-editor.org/rfc/rfc7748)\nimport { x25519 } from '@noble/curves/ed25519';\nconst priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';\nconst pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';\nx25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases\nx25519.getPublicKey(priv) === x25519.scalarMultBase(priv);\nx25519.getPublicKey(x25519.utils.randomPrivateKey());\n\n// ed25519 =\u003e x25519 conversion\nimport { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';\nedwardsToMontgomeryPub(ed25519.getPublicKey(ed25519.utils.randomPrivateKey()));\nedwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());\n```\n\n#### ristretto255\n\n```ts\n// ristretto255 from [RFC9496](https://www.rfc-editor.org/rfc/rfc9496)\nimport { utf8ToBytes } from '@noble/hashes/utils';\nimport { sha512 } from '@noble/hashes/sha512';\nimport {\n  hashToCurve,\n  encodeToCurve,\n  RistrettoPoint,\n  hashToRistretto255,\n} from '@noble/curves/ed25519';\n\nconst msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');\nhashToCurve(msg);\n\nconst rp = RistrettoPoint.fromHex(\n  '6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919'\n);\nRistrettoPoint.BASE.multiply(2n).add(rp).subtract(RistrettoPoint.BASE).toRawBytes();\nRistrettoPoint.ZERO.equals(dp) === false;\n// pre-hashed hash-to-curve\nRistrettoPoint.hashToCurve(sha512(msg));\n// full hash-to-curve including domain separation tag\nhashToRistretto255(msg, { DST: 'ristretto255_XMD:SHA-512_R255MAP_RO_' });\n```\n\n#### ed448\n\n```ts\nimport { ed448 } from '@noble/curves/ed448';\nconst priv = ed448.utils.randomPrivateKey();\nconst pub = ed448.getPublicKey(priv);\nconst msg = new TextEncoder().encode('whatsup');\nconst sig = ed448.sign(msg, priv);\ned448.verify(sig, msg, pub);\n\n// Variants from RFC8032: prehashed\nimport { ed448ph } from '@noble/curves/ed448';\n```\n\n#### X448\n\n```ts\n// X448 aka ECDH on Curve448 from [RFC7748](https://www.rfc-editor.org/rfc/rfc7748)\nimport { x448 } from '@noble/curves/ed448';\nx448.getSharedSecret(priv, pub) === x448.scalarMult(priv, pub); // aliases\nx448.getPublicKey(priv) === x448.scalarMultBase(priv);\n\n// ed448 =\u003e x448 conversion\nimport { edwardsToMontgomeryPub } from '@noble/curves/ed448';\nedwardsToMontgomeryPub(ed448.getPublicKey(ed448.utils.randomPrivateKey()));\n```\n\n#### decaf448\n\n```ts\n// decaf448 from [RFC9496](https://www.rfc-editor.org/rfc/rfc9496)\nimport { utf8ToBytes } from '@noble/hashes/utils';\nimport { shake256 } from '@noble/hashes/sha3';\nimport { hashToCurve, encodeToCurve, DecafPoint, hashToDecaf448 } from '@noble/curves/ed448';\n\nconst msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');\nhashToCurve(msg);\n\nconst dp = DecafPoint.fromHex(\n  'c898eb4f87f97c564c6fd61fc7e49689314a1f818ec85eeb3bd5514ac816d38778f69ef347a89fca817e66defdedce178c7cc709b2116e75'\n);\nDecafPoint.BASE.multiply(2n).add(dp).subtract(DecafPoint.BASE).toRawBytes();\nDecafPoint.ZERO.equals(dp) === false;\n// pre-hashed hash-to-curve\nDecafPoint.hashToCurve(shake256(msg, { dkLen: 112 }));\n// full hash-to-curve including domain separation tag\nhashToDecaf448(msg, { DST: 'decaf448_XOF:SHAKE256_D448MAP_RO_' });\n```\n\n#### bls12-381\n\n```ts\nimport { bls12_381 as bls } from '@noble/curves/bls12-381';\n\n// G1 keys, G2 signatures\nconst privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';\nconst message = '64726e3da8';\nconst publicKey = bls.getPublicKey(privateKey);\nconst signature = bls.sign(message, privateKey);\nconst isValid = bls.verify(signature, message, publicKey);\nconsole.log({ publicKey, signature, isValid });\n\n// G2 keys, G1 signatures\n// getPublicKeyForShortSignatures(privateKey)\n// signShortSignature(message, privateKey)\n// verifyShortSignature(signature, message, publicKey)\n// aggregateShortSignatures(signatures)\n\n// Custom DST\nconst htfEthereum = { DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_' };\nconst signatureEth = bls.sign(message, privateKey, htfEthereum);\nconst isValidEth = bls.verify(signature, message, publicKey, htfEthereum);\n\n// Aggregation\nconst aggregatedKey = bls.aggregatePublicKeys([\n  bls.utils.randomPrivateKey(),\n  bls.utils.randomPrivateKey(),\n]);\n// const aggregatedSig = bls.aggregateSignatures(sigs)\n\n// Pairings, with and without final exponentiation\n// bls.pairing(PointG1, PointG2);\n// bls.pairing(PointG1, PointG2, false);\n// bls.fields.Fp12.finalExponentiate(bls.fields.Fp12.mul(PointG1, PointG2));\n\n// Others\n// bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE;\n// bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr;\n```\n\nSee [abstract/bls](#bls-barreto-lynn-scott-curves).\nFor example usage, check out [the implementation of BLS EVM precompiles](https://github.com/ethereumjs/ethereumjs-monorepo/blob/361f4edbc239e795a411ac2da7e5567298b9e7e5/packages/evm/src/precompiles/bls12_381/noble.ts).\n\n#### bn254 aka alt_bn128\n\n```ts\nimport { bn254 } from '@noble/curves/bn254';\n\nconsole.log(bn254.G1, bn254.G2, bn254.pairing);\n```\n\nThe API mirrors [BLS](#bls12-381). The curve was previously called alt_bn128.\nThe implementation is compatible with [EIP-196](https://eips.ethereum.org/EIPS/eip-196) and\n[EIP-197](https://eips.ethereum.org/EIPS/eip-197).\n\nWe don't implement Point methods toHex / toRawBytes.\nTo work around this limitation, has to initialize points on their own from BigInts.\nReason it's not implemented is because [there is no standard](https://github.com/privacy-scaling-explorations/halo2curves/issues/109).\nPoints of divergence:\n\n- Endianness: LE vs BE (byte-swapped)\n- Flags as first hex bits (similar to BLS) vs no-flags\n- Imaginary part last in G2 vs first (c0, c1 vs c1, c0)\n\nFor example usage, check out [the implementation of bn254 EVM precompiles](https://github.com/paulmillr/noble-curves/blob/3ed792f8ad9932765b84d1064afea8663a255457/test/bn254.test.js#L697).\n\n#### misc curves\n\n```ts\nimport { jubjub, babyjubjub } from '@noble/curves/misc';\n```\n\nMiscellaneous, rarely used curves are contained in the module.\nJubjub curves have Fp over scalar fields of other curves. They are friendly to ZK proofs.\njubjub Fp = bls n. babyjubjub Fp = bn254 n.\n\n#### Low-level methods\n\n```ts\nimport { secp256k1 } from '@noble/curves/secp256k1';\n\n// Curve's variables\n// Every curve has `CURVE` object that contains its parameters, field, and others\nconsole.log(secp256k1.CURVE.p); // field modulus\nconsole.log(secp256k1.CURVE.n); // curve order\nconsole.log(secp256k1.CURVE.a, secp256k1.CURVE.b); // equation params\nconsole.log(secp256k1.CURVE.Gx, secp256k1.CURVE.Gy); // base point coordinates\n\n// MSM\nconst p = secp256k1.ProjectivePoint;\nconst points = [p.BASE, p.BASE.multiply(2n), p.BASE.multiply(4n), p.BASE.multiply(8n)];\np.msm(points, [3n, 5n, 7n, 11n]).equals(p.BASE.multiply(129n)); // 129*G\n```\n\nMulti-scalar-multiplication (MSM) is basically `(Pa + Qb + Rc + ...)`.\nIt's 10-30x faster vs naive addition for large amount of points.\nPippenger algorithm is used underneath.\n\n## Abstract API\n\nImplementations use [noble-hashes](https://github.com/paulmillr/noble-hashes).\nIf you want to use a different hashing library, abstract API doesn't depend on them.\n\nAbstract API allows to define custom curves. All arithmetics is done with JS\nbigints over finite fields, which is defined from `modular` sub-module. For\nscalar multiplication, we use\n[precomputed tables with w-ary non-adjacent form (wNAF)](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/).\nPrecomputes are enabled for weierstrass and edwards BASE points of a curve. You\ncould precompute any other point (e.g. for ECDH) using `utils.precompute()`\nmethod: check out examples.\n\n### weierstrass: Short Weierstrass curve\n\n```ts\nimport { weierstrass } from '@noble/curves/abstract/weierstrass';\nimport { Field } from '@noble/curves/abstract/modular';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hmac } from '@noble/hashes/hmac';\nimport { concatBytes, randomBytes } from '@noble/hashes/utils';\n\nconst hmacSha256 = (key: Uint8Array, ...msgs: Uint8Array[]) =\u003e\n  hmac(sha256, key, concatBytes(...msgs));\n\n// secQ (not secP) - secq256k1 is a cycle of secp256k1 with Fp/N flipped.\n// https://personaelabs.org/posts/spartan-ecdsa\n// https://zcash.github.io/halo2/background/curves.html#cycles-of-curves\nconst secq256k1 = weierstrass({\n  a: 0n,\n  b: 7n,\n  Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),\n  n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,\n  Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,\n  Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,\n  hash: sha256,\n  hmac: hmacSha256,\n  randomBytes,\n});\n\n// NIST secp192r1 aka p192\n// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1\nconst secp192r1 = weierstrass({\n  a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn,\n  b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,\n  Fp: Field(0xfffffffffffffffffffffffffffffffeffffffffffffffffn),\n  n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,\n  Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,\n  Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n,\n  hash: sha256,\n  hmac: hmacSha256,\n  randomBytes,\n});\n```\n\nShort Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`\nexpects arguments `a`, `b`, field `Fp`, curve order `n`, cofactor `h`\nand coordinates `Gx`, `Gy` of generator point.\n`hmac` and `hash` must be specified for deterministic `k` generation.\n\n**Weierstrass points:**\n\n- Are exported as `ProjectivePoint`\n- Are represented in projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)\n- Use complete exception-free formulas for addition and doubling\n- Can be decoded/encoded from/to Uint8Array / hex strings using\n  `ProjectivePoint.fromHex` and `ProjectivePoint#toRawBytes()`\n- Have `assertValidity()` which checks for being on-curve\n- Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates\n\n**ECDSA signatures:**\n\n- Are represented by `Signature` instances with `r, s` and optional `recovery` properties\n- Have `recoverPublicKey()`, `toCompactRawBytes()` and `toDERRawBytes()` methods\n- Can be prehashed, or non-prehashed:\n  - `sign(msgHash, privKey)` (default, prehash: false) - you did hashing before\n  - `sign(msg, privKey, {prehash: true})` - curves will do hashing for you\n- Are generated deterministically, following [RFC6979](https://www.rfc-editor.org/rfc/rfc6979).\n  - Consider [hedged ECDSA with noise](#hedged-ecdsa-with-noise) for adding randomness into\n    for signatures, to get improved security against fault attacks.\n\nMore examples:\n\n```typescript\n// All curves expose same generic interface.\nconst priv = secq256k1.utils.randomPrivateKey();\nsecq256k1.getPublicKey(priv); // Convert private key to public.\nconst sig = secq256k1.sign(msg, priv); // Sign msg with private key.\nconst sig2 = secq256k1.sign(msg, priv, { prehash: true }); // hash(msg)\nsecq256k1.verify(sig, msg, priv); // Verify if sig is correct.\n\n// Default behavior is \"try DER, then try compact if fails\". Can be explicit:\nsecq256k1.verify(sig.toCompactHex(), msg, priv, { format: 'compact' });\n\nconst Point = secq256k1.ProjectivePoint;\nconst point = Point.BASE; // Elliptic curve Point class and BASE point static var.\npoint.add(point).equals(point.double()); // add(), equals(), double() methods\npoint.subtract(point).equals(Point.ZERO); // subtract() method, ZERO static var\npoint.negate(); // Flips point over x/y coordinate.\npoint.multiply(31415n); // Multiplication of Point by scalar.\n\npoint.assertValidity(); // Checks for being on-curve\npoint.toAffine(); // Converts to 2d affine xy coordinates\n\nsecq256k1.CURVE.n;\nsecq256k1.CURVE.p;\nsecq256k1.CURVE.Fp.mod();\nsecq256k1.CURVE.hash();\n\n// precomputes\nconst fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));\nfast.multiply(privKey); // much faster ECDH now\n```\n\n### edwards: Twisted Edwards curve\n\n```ts\nimport { twistedEdwards } from '@noble/curves/abstract/edwards';\nimport { Field } from '@noble/curves/abstract/modular';\nimport { sha512 } from '@noble/hashes/sha512';\nimport { randomBytes } from '@noble/hashes/utils';\n\nconst Fp = Field(2n ** 255n - 19n);\nconst ed25519 = twistedEdwards({\n  a: Fp.create(-1n),\n  d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p\n  Fp: Fp,\n  n: 2n ** 252n + 27742317777372353535851937790883648493n,\n  h: 8n,\n  Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,\n  Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,\n  hash: sha512,\n  randomBytes,\n  adjustScalarBytes(bytes) {\n    // optional; but mandatory in ed25519\n    bytes[0] \u0026= 248;\n    bytes[31] \u0026= 127;\n    bytes[31] |= 64;\n    return bytes;\n  },\n} as const);\n```\n\nTwisted Edwards curve's formula is `ax² + y² = 1 + dx²y²`.\nYou must specify `a`, `d`, field `Fp`, order `n`, cofactor `h`\nand coordinates `Gx`, `Gy` of generator point.\nFor EdDSA signatures, `hash` param required.\n`adjustScalarBytes` which instructs how to change private scalars could be specified.\n\n**Edwards points:**\n\n- Are exported as `ExtendedPoint`\n- Are represented in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z)\n- Use complete exception-free formulas for addition and doubling\n- Can be decoded/encoded from/to Uint8Array / hex strings using `ExtendedPoint.fromHex` and `ExtendedPoint#toRawBytes()`\n- Have `assertValidity()` which checks for being on-curve\n- Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates\n- Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions\n\n**EdDSA signatures:**\n\n- `zip215: true` is default behavior. It has slightly looser verification logic\n  to be [consensus-friendly](https://hdevalence.ca/blog/2020-10-04-its-25519am), following [ZIP215](https://zips.z.cash/zip-0215) rules\n- `zip215: false` switches verification criteria to strict\n  [RFC8032](https://www.rfc-editor.org/rfc/rfc8032) / [FIPS 186-5](https://csrc.nist.gov/publications/detail/fips/186/5/final)\n  and additionally provides [non-repudiation with SBS](https://eprint.iacr.org/2020/1244),\n  which is useful for:\n  - Contract Signing: if A signed an agreement with B using key that allows repudiation, it can later claim that it signed a different contract\n  - E-voting: malicious voters may pick keys that allow repudiation in order to deny results\n  - Blockchains: transaction of amount X might also be valid for a different amount Y\n- Both modes have SUF-CMA (strong unforgeability under chosen message attacks).\n\nCheck out [RFC9496](https://www.rfc-editor.org/rfc/rfc9496) for description of\nristretto and decaf groups which we implement.\n\n### montgomery: Montgomery curve\n\nThe module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.\nProper Elliptic Curve Points are not implemented yet.\n\n### bls: Barreto-Lynn-Scott curves\n\nThe module abstracts BLS (Barreto-Lynn-Scott) pairing-friendly elliptic curve construction.\nThey allow to construct [zk-SNARKs](https://z.cash/technology/zksnarks/) and\nuse aggregated, batch-verifiable\n[threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),\nusing Boneh-Lynn-Shacham signature scheme.\n\nThe module doesn't expose `CURVE` property: use `G1.CURVE`, `G2.CURVE` instead.\nOnly BLS12-381 is currently implemented.\nDefining BLS12-377 and BLS24 should be straightforward.\n\nThe default BLS uses short public keys (with public keys in G1 and signatures in G2).\nShort signatures (public keys in G2 and signatures in G1) are also supported.\n\n### hash-to-curve: Hashing strings to curve points\n\nThe module allows to hash arbitrary strings to elliptic curve points. Implements [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).\n\nEvery curve has exported `hashToCurve` and `encodeToCurve` methods. You should always prefer `hashToCurve` for security:\n\n```ts\nimport { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';\nimport { randomBytes } from '@noble/hashes/utils';\nhashToCurve('0102abcd');\nconsole.log(hashToCurve(randomBytes()));\nconsole.log(encodeToCurve(randomBytes()));\n\nimport { bls12_381 } from '@noble/curves/bls12-381';\nbls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });\nbls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });\n```\n\nLow-level methods from the spec:\n\n```ts\n// produces a uniformly random byte string using a cryptographic hash function H that outputs b bits.\nfunction expand_message_xmd(\n  msg: Uint8Array,\n  DST: Uint8Array,\n  lenInBytes: number,\n  H: CHash // For CHash see abstract/weierstrass docs section\n): Uint8Array;\n// produces a uniformly random byte string using an extendable-output function (XOF) H.\nfunction expand_message_xof(\n  msg: Uint8Array,\n  DST: Uint8Array,\n  lenInBytes: number,\n  k: number,\n  H: CHash\n): Uint8Array;\n// Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F\nfunction hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];\n\n/**\n * * `DST` is a domain separation tag, defined in section 2.2.5\n * * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m\n * * `m` is extension degree (1 for prime fields)\n * * `k` is the target security target in bits (e.g. 128), from section 5.1\n * * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)\n * * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props\n */\ntype UnicodeOrBytes = string | Uint8Array;\ntype Opts = {\n  DST: UnicodeOrBytes;\n  p: bigint;\n  m: number;\n  k: number;\n  expand?: 'xmd' | 'xof';\n  hash: CHash;\n};\n```\n\n### poseidon: Poseidon hash\n\nImplements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash:\npermutation and sponge.\n\nThere are many poseidon variants with different constants.\nWe don't provide them: you should construct them manually.\nCheck out [micro-starknet](https://github.com/paulmillr/micro-starknet) package for a proper example.\n\n```ts\nimport { poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon';\n\nconst rate = 2;\nconst capacity = 1;\nconst { mds, roundConstants } = poseidon.grainGenConstants({\n  Fp,\n  t: rate + capacity,\n  roundsFull: 8,\n  roundsPartial: 31,\n});\nconst opts = {\n  Fp,\n  rate,\n  capacity,\n  sboxPower: 17,\n  mds,\n  roundConstants,\n  roundsFull: 8,\n  roundsPartial: 31,\n};\nconst permutation = poseidon.poseidon(opts);\nconst sponge = poseidon.poseidonSponge(opts); // use carefully, not specced\n```\n\n### modular: Modular arithmetics utilities\n\n```ts\nimport * as mod from '@noble/curves/abstract/modular';\n\n// Finite Field utils\nconst fp = mod.Field(2n ** 255n - 19n); // Finite field over 2^255-19\nfp.mul(591n, 932n); // multiplication\nfp.pow(481n, 11024858120n); // exponentiation\nfp.div(5n, 17n); // division: 5/17 mod 2^255-19 == 5 * invert(17)\nfp.inv(5n); // modular inverse\nfp.sqrt(21n); // square root\n\n// Non-Field generic utils are also available\nmod.mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10\nmod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse\nmod.invertBatch([1n, 2n, 4n], 21n); // =\u003e [1n, 11n, 16n] in one inversion\n```\n\nField operations are not constant-time: they are using JS bigints, see [security](#security).\nThe fact is mostly irrelevant, but the important method to keep in mind is `pow`,\nwhich may leak exponent bits, when used naïvely.\n\n`mod.Field` is always **field over prime number**. Non-prime fields aren't supported for now.\nWe don't test for prime-ness for speed and because algorithms are probabilistic anyway.\nInitializing a non-prime field could make your app suspectible to\nDoS (infilite loop) on Tonelli-Shanks square root calculation.\n\nUnlike `mod.inv`, `mod.invertBatch` won't throw on `0`: make sure to throw an error yourself.\n\n#### Creating private keys from hashes\n\nYou can't simply make a 32-byte private key from a 32-byte hash.\nDoing so will make the key [biased](https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/).\n\nTo make the bias negligible, we follow [FIPS 186-5 A.2](https://csrc.nist.gov/publications/detail/fips/186/5/final)\nand [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380#section-5.2).\nThis means, for 32-byte key, we would need 48-byte hash to get 2^-128 bias, which matches curve security level.\n\n`hashToPrivateScalar()` that hashes to **private key** was created for this purpose.\nUse [abstract/hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points)\nif you need to hash to **public key**.\n\n```ts\nimport { p256 } from '@noble/curves/nist';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport * as mod from '@noble/curves/abstract/modular';\nconst someKey = new Uint8Array(32).fill(2); // Needs to actually be random, not .fill(2)\nconst derived = hkdf(sha256, someKey, undefined, 'application', 48); // 48 bytes for 32-byte priv\nconst validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);\n```\n\n### utils: Useful utilities\n\n```ts\nimport * as utils from '@noble/curves/abstract/utils';\n\nutils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));\nutils.hexToBytes('deadbeef');\nutils.numberToHexUnpadded(123n);\nutils.hexToNumber();\n\nutils.bytesToNumberBE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));\nutils.bytesToNumberLE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));\nutils.numberToBytesBE(123n, 32);\nutils.numberToBytesLE(123n, 64);\n\nutils.concatBytes(Uint8Array.from([0xde, 0xad]), Uint8Array.from([0xbe, 0xef]));\nutils.nLength(255n);\nutils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));\n```\n\n## Security\n\nThe library has been independently audited:\n\n- at version 1.6.0, in Sep 2024, by [Cure53](https://cure53.de)\n  - PDFs: [website](https://cure53.de/audit-report_noble-crypto-libs.pdf), [in-repo](./audit/2024-09-cure53-audit-nbl4.pdf)\n  - [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.6.0..main)\n  - Scope: ed25519, ed448, their add-ons, bls12-381, bn254,\n    hash-to-curve, low-level primitives bls, tower, edwards, montgomery.\n  - The audit has been funded by [OpenSats](https://opensats.org)\n- at version 1.2.0, in Sep 2023, by [Kudelski Security](https://kudelskisecurity.com)\n  - PDFs: [in-repo](./audit/2023-09-kudelski-audit-starknet.pdf)\n  - [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.2.0..main)\n  - Scope: [scure-starknet](https://github.com/paulmillr/scure-starknet) and its related\n    abstract modules of noble-curves: `curve`, `modular`, `poseidon`, `weierstrass`\n  - The audit has been funded by [Starkware](https://starkware.co)\n- at version 0.7.3, in Feb 2023, by [Trail of Bits](https://www.trailofbits.com)\n  - PDFs: [website](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf),\n    [in-repo](./audit/2023-01-trailofbits-audit-curves.pdf)\n  - [Changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main)\n  - Scope: abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass` and\n    top-level modules `_shortw_utils` and `secp256k1`\n  - The audit has been funded by [Ryan Shea](https://www.shea.io)\n\nIt is tested against property-based, cross-library and Wycheproof vectors,\nand is being fuzzed in [the separate repo](https://github.com/paulmillr/fuzzing).\n\nIf you see anything unusual: investigate and report.\n\n### Constant-timeness\n\nWe're targetting algorithmic constant time. _JIT-compiler_ and _Garbage Collector_ make \"constant time\"\nextremely hard to achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance\nin a scripting language. Which means _any other JS library can't have\nconstant-timeness_. Even statically typed Rust, a language without GC,\n[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)\nfor some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.\nUse low-level libraries \u0026 languages.\n\n### Supply chain security\n\n- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures\n- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs\n  - Use GitHub CLI to verify single-file builds:\n    `gh attestation verify --owner paulmillr noble-curves.js`\n- **Rare releasing** is followed to ensure less re-audit need for end-users\n- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.\n  - We make sure to use as few dependencies as possible\n  - Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`\n- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code\n\nFor this package, there is 1 dependency; and a few dev dependencies:\n\n- [noble-hashes](https://github.com/paulmillr/noble-hashes) provides cryptographic hashing functionality\n- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author\n- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size\n\n### Randomness\n\nWe're deferring to built-in\n[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)\nwhich is considered cryptographically secure (CSPRNG).\n\nIn the past, browsers had bugs that made it weak: it may happen again.\nImplementing a userspace CSPRNG to get resilient to the weakness\nis even worse: there is no reliable userspace source of quality entropy.\n\n### Quantum computers\n\nCryptographically relevant quantum computer, if built, will allow to\nbreak elliptic curve cryptography (both ECDSA / EdDSA \u0026 ECDH) using Shor's algorithm.\n\nConsider switching to newer / hybrid algorithms, such as SPHINCS+. They are available in\n[noble-post-quantum](https://github.com/paulmillr/noble-post-quantum).\n\nNIST prohibits classical cryptography (RSA, DSA, ECDSA, ECDH) [after 2035](https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf). Australian ASD prohibits it [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography).\n\n## Speed\n\n```sh\nnpm run bench:install \u0026\u0026 npm run bench\n```\n\nDuring first call of most methods, `init` is done, which calculates base point precomputes.\nThe method consumes 20MB+ of memory and takes some time.\nYou can adjust how many precomputes are generated,\nby using `_setWindowSize`. Check out the source code.\n\nBenchmark results on Apple M4:\n\n```\n# secp256k1\ninit 10ms\ngetPublicKey x 9,099 ops/sec @ 109μs/op\nsign x 7,182 ops/sec @ 139μs/op\nverify x 1,188 ops/sec @ 841μs/op\ngetSharedSecret x 735 ops/sec @ 1ms/op\nrecoverPublicKey x 1,265 ops/sec @ 790μs/op\nschnorr.sign x 957 ops/sec @ 1ms/op\nschnorr.verify x 1,210 ops/sec @ 825μs/op\n\n# ed25519\ninit 14ms\ngetPublicKey x 14,216 ops/sec @ 70μs/op\nsign x 6,849 ops/sec @ 145μs/op\nverify x 1,400 ops/sec @ 713μs/op\n\n# ed448\ninit 37ms\ngetPublicKey x 5,273 ops/sec @ 189μs/op\nsign x 2,494 ops/sec @ 400μs/op\nverify x 476 ops/sec @ 2ms/op\n\n# p256\ninit 17ms\ngetPublicKey x 8,977 ops/sec @ 111μs/op\nsign x 7,236 ops/sec @ 138μs/op\nverify x 877 ops/sec @ 1ms/op\n\n# p384\ninit 42ms\ngetPublicKey x 4,084 ops/sec @ 244μs/op\nsign x 3,247 ops/sec @ 307μs/op\nverify x 331 ops/sec @ 3ms/op\n\n# p521\ninit 83ms\ngetPublicKey x 2,049 ops/sec @ 487μs/op\nsign x 1,748 ops/sec @ 571μs/op\nverify x 170 ops/sec @ 5ms/op\n\n# ristretto255\nadd x 931,966 ops/sec @ 1μs/op\nmultiply x 15,444 ops/sec @ 64μs/op\nencode x 21,367 ops/sec @ 46μs/op\ndecode x 21,715 ops/sec @ 46μs/op\n\n# decaf448\nadd x 478,011 ops/sec @ 2μs/op\nmultiply x 416 ops/sec @ 2ms/op\nencode x 8,562 ops/sec @ 116μs/op\ndecode x 8,636 ops/sec @ 115μs/op\n\n# ECDH\nx25519 x 1,981 ops/sec @ 504μs/op\nx448 x 743 ops/sec @ 1ms/op\nsecp256k1 x 728 ops/sec @ 1ms/op\np256 x 705 ops/sec @ 1ms/op\np384 x 268 ops/sec @ 3ms/op\np521 x 137 ops/sec @ 7ms/op\n\n# hash-to-curve\nhashToPrivateScalar x 1,754,385 ops/sec @ 570ns/op\nhash_to_field x 135,703 ops/sec @ 7μs/op\nhashToCurve secp256k1 x 3,194 ops/sec @ 313μs/op\nhashToCurve p256 x 5,962 ops/sec @ 167μs/op\nhashToCurve p384 x 2,230 ops/sec @ 448μs/op\nhashToCurve p521 x 1,063 ops/sec @ 940μs/op\nhashToCurve ed25519 x 4,047 ops/sec @ 247μs/op\nhashToCurve ed448 x 1,691 ops/sec @ 591μs/op\nhash_to_ristretto255 x 8,733 ops/sec @ 114μs/op\nhash_to_decaf448 x 3,882 ops/sec @ 257μs/op\n\n# modular over secp256k1 P field\ninvert a x 866,551 ops/sec @ 1μs/op\ninvert b x 693,962 ops/sec @ 1μs/op\nsqrt p = 3 mod 4 x 25,738 ops/sec @ 38μs/op\nsqrt tonneli-shanks x 847 ops/sec @ 1ms/op\n\n# bls12-381\ninit 22ms\ngetPublicKey x 1,325 ops/sec @ 754μs/op\nsign x 80 ops/sec @ 12ms/op\nverify x 62 ops/sec @ 15ms/op\npairing x 166 ops/sec @ 6ms/op\npairing10 x 54 ops/sec @ 18ms/op ± 23.48% (15ms..36ms)\nMSM 4096 scalars x points 3286ms\naggregatePublicKeys/8 x 173 ops/sec @ 5ms/op\naggregatePublicKeys/32 x 46 ops/sec @ 21ms/op\naggregatePublicKeys/128 x 11 ops/sec @ 84ms/op\naggregatePublicKeys/512 x 2 ops/sec @ 335ms/op\naggregatePublicKeys/2048 x 0 ops/sec @ 1346ms/op\naggregateSignatures/8 x 82 ops/sec @ 12ms/op\naggregateSignatures/32 x 21 ops/sec @ 45ms/op\naggregateSignatures/128 x 5 ops/sec @ 178ms/op\naggregateSignatures/512 x 1 ops/sec @ 705ms/op\naggregateSignatures/2048 x 0 ops/sec @ 2823ms/op\n```\n\n## Upgrading\n\nPreviously, the library was split into single-feature packages\n[noble-secp256k1](https://github.com/paulmillr/noble-secp256k1),\n[noble-ed25519](https://github.com/paulmillr/noble-ed25519) and\n[noble-bls12-381](https://github.com/paulmillr/noble-bls12-381).\n\nCurves continue their original work. The single-feature packages changed their\ndirection towards providing minimal 4kb implementations of cryptography,\nwhich means they have less features.\n\nUpgrading from noble-secp256k1 2.0 or noble-ed25519 2.0: no changes, libraries are compatible.\n\nUpgrading from noble-secp256k1 1.7:\n\n- `getPublicKey`\n  - now produce 33-byte compressed signatures by default\n  - to use old behavior, which produced 65-byte uncompressed keys, set\n    argument `isCompressed` to `false`: `getPublicKey(priv, false)`\n- `sign`\n  - is now sync\n  - now returns `Signature` instance with `{ r, s, recovery }` properties\n  - `canonical` option was renamed to `lowS`\n  - `recovered` option has been removed because recovery bit is always returned now\n  - `der` option has been removed. There are 2 options:\n    1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.\n       Compact encoding is simply a concatenation of 32-byte r and 32-byte s.\n    2. If you must use DER encoding, switch to noble-curves (see above).\n- `verify`\n  - is now sync\n  - `strict` option was renamed to `lowS`\n- `getSharedSecret`\n  - now produce 33-byte compressed signatures by default\n  - to use old behavior, which produced 65-byte uncompressed keys, set\n    argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`\n- `recoverPublicKey(msg, sig, rec)` was changed to `sig.recoverPublicKey(msg)`\n- `number` type for private keys have been removed: use `bigint` instead\n- `Point` (2d xy) has been changed to `ProjectivePoint` (3d xyz)\n- `utils` were split into `utils` (same api as in noble-curves) and\n  `etc` (`hmacSha256Sync` and others)\n\nUpgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:\n\n- Methods are now sync by default\n- `bigint` is no longer allowed in `getPublicKey`, `sign`, `verify`. Reason: ed25519 is LE, can lead to bugs\n- `Point` (2d xy) has been changed to `ExtendedPoint` (xyzt)\n- `Signature` was removed: just use raw bytes or hex now\n- `utils` were split into `utils` (same api as in noble-curves) and\n  `etc` (`sha512Sync` and others)\n- `getSharedSecret` was moved to `x25519` module\n- `toX25519` has been moved to `edwardsToMontgomeryPub` and `edwardsToMontgomeryPriv` methods\n\nUpgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):\n\n- Methods and classes were renamed:\n  - PointG1 -\u003e G1.Point, PointG2 -\u003e G2.Point\n  - PointG2.fromSignature -\u003e Signature.decode, PointG2.toSignature -\u003e Signature.encode\n- Fp2 ORDER was corrected\n\n## Contributing \u0026 testing\n\n- `npm install \u0026\u0026 npm run build \u0026\u0026 npm test` will build the code and run tests.\n- `npm run lint` / `npm run format` will run linter / fix linter issues.\n- `npm run bench` will run benchmarks, which may need their deps first (`npm run bench:install`)\n- `npm run build:release` will build single file\n\nCheck out [github.com/paulmillr/guidelines](https://github.com/paulmillr/guidelines)\nfor general coding practices and rules.\n\nSee [paulmillr.com/noble](https://paulmillr.com/noble/)\nfor useful resources, articles, documentation and demos\nrelated to the library.\n\nMuSig2 signature scheme and BIP324 ElligatorSwift mapping for secp256k1\nare available [in a separate package](https://github.com/paulmillr/scure-btc-signer).\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2022 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)\n\nSee LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulmillr%2Fnoble-curves","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulmillr%2Fnoble-curves","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulmillr%2Fnoble-curves/lists"}