Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
noble-curves — 監査済みで最小限の楕円曲線暗号のJS実装。 | Kitploit
ツール/GitHubGitHub/paulmillr/noble-curves
暗号化/復号化ツールハッシュ分析暗号化ユーティリティとフレームワーク学習と教育
GitHubpaulmillr/noble-curves

noble-curves

監査済みで最小限の楕円曲線暗号のJS実装。

リポジトリを見る
958101157日前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
ウェブサイト

noble-curves

監査済みで最小限の楕円曲線暗号のJS実装。

  • 🔒 独立したセキュリティ企業による監査済み
  • 🪶 最小限: 15KB (gzip圧縮時) のsecp256k1、未使用コードはビルドから除外される
  • 🏎 高速: JSエンジンの特性に合わせて手作業で最適化
  • 🔍 信頼性: クロスライブラリ / wycheproofテストで正確性を保証
  • ➰ Weierstrass曲線、Edwards曲線; ECDSA、EdDSA、Schnorr、BLS署名
  • ✍️ ECDH、hash-to-curve、OPRF、FROST、Poseidonハッシュ、FFT
  • 🔖 ed25519、ed448における否認防止 (SUF-CMA、SBS) とコンセンサス親和性 (ZIP215)
  • 🥈 ネイティブWebCrypto上で同一APIを持つラッパー

各曲線には5kbの姉妹プロジェクトがあります secp256k1 と ed25519。 これらは攻撃対象領域が小さいですが、機能は少なくなっています。

このライブラリは noble cryptographyに属します

noble cryptography — 高セキュリティで監査が容易な、自己完結型の暗号ライブラリとツールのセット。

  • 依存関係はゼロまたは最小限
  • 非常に読みやすいTypeScript / JSコード
  • PGP署名されたリリースと透過的なNPMビルド
  • すべてのライブラリ: ciphers、 curves、 hashes、 post-quantum、 5kb secp256k1 / ed25519
  • WASM版: awasm-noble
  • 読み物リソース、ドキュメント、nobleで構築されたアプリについては ホームページをチェックしてください

使用方法

npm install @noble/curves

deno add jsr:@noble/curves

すべての主要なプラットフォームとランタイムをサポートしています。 React Nativeでは、getRandomValuesのpolyfillが必要になる場合があります。 スタンドアロンファイル noble-curves.js も利用可能です。```js // import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size import { secp256k1 } from '@noble/curves/secp256k1.js'; const { secretKey, publicKey } = secp256k1.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = secp256k1.sign(msg, secretKey); const isValid = secp256k1.verify(sig, msg, publicKey);

root@kitploit:~
- [ECDSA、EdDSA、Schnorr署名](#ecdsa-eddsa-schnorr-signatures)
- [ECDH: Diffie-Hellman共有秘密](#ecdh-diffie-hellman-shared-secrets)
- [webcrypto: フレンドリーなラッパー](#webcrypto-friendly-wrapper)
- [BLS署名、bls12-381、bn254別名alt\_bn128](#bls-signatures-bls12-381-bn254-aka-alt_bn128)
- [hash-to-curve: 曲線点へのハッシュ](#hash-to-curve-hashing-to-curve-points)
- [OPRF](#oprfs) | [FROST閾値署名](#frost-threshold-signatures)
- [poseidon: Poseidonハッシュ](#poseidon-poseidon-hash) | [fft: 高速フーリエ変換](#fft-fast-fourier-transform) | [utils](#utils-byte-shuffling-conversion)
- 内部: [点演算](#elliptic-curve-point-math) | [modular](#modular-modular-arithmetics--finite-fields) | [カスタム曲線](#weierstrass-custom-weierstrass-curve--ecdsa)
- [仕様](#specs)
- [セキュリティ](#security) | [速度](#speed) | [アップグレード](#upgrading) | [コントリビューションとテスト](#contributing--testing) | [ライセンス](#license)

### ECDSA、EdDSA、Schnorr署名

#### secp256k1、p256、p384、p521、ed25519、ed448、brainpool```js
import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
import { p256, p384, p521 } from '@noble/curves/nist.js';
import { ed25519 } from '@noble/curves/ed25519.js';
import { ed448 } from '@noble/curves/ed448.js';
import { brainpoolP256r1, brainpoolP384r1, brainpoolP512r1 } from '@noble/curves/misc.js';
for (const curve of [
  secp256k1, schnorr,
  p256, p384, p521,
  ed25519, ed448,
  brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
]) {
  const { secretKey, publicKey } = curve.keygen();
  const msg = new TextEncoder().encode('hello noble');
  const sig = curve.sign(msg, secretKey);
  const isValid = curve.verify(sig, msg, publicKey);
  console.log(curve, secretKey, publicKey, sig, isValid);
}

// Specific private key
import { hexToBytes } from '@noble/curves/utils.js';
const secret2 = hexToBytes('46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236');
const pub2 = secp256k1.getPublicKey(secret2);

メッセージは常に最初にハッシュ化されます: prehashed signingを参照してください。 ECDSAは決定論的kを使用し、EdDSAはRFC 8032に準拠し、Schnorr(secp256k1のみ)はBIP 340に準拠します: Specsを参照してください。

MuSig2署名スキームとsecp256k1用のBIP324 ElligatorSwiftマッピングは 別のパッケージで利用可能です。

ristretto255, decaf448```ts

import { ristretto255, ristretto255_hasher, ristretto255_oprf } from '@noble/curves/ed25519.js'; import { decaf448, decaf448_hasher, decaf448_oprf } from '@noble/curves/ed448.js';

console.log(ristretto255.Point, decaf448.Point);

root@kitploit:~
[RFC 9496](https://www.rfc-editor.org/rfc/rfc9496) で ristretto255 と decaf448 の詳細を確認してください。
[Point](#elliptic-curve-point-math)、[hasher](#hash-to-curve-hashing-to-curve-points)、[oprf](#oprfs) の個別ドキュメントも確認してください。

#### 事前ハッシュ署名```js
import { secp256k1 } from '@noble/curves/secp256k1.js';
import { keccak_256 } from '@noble/hashes/sha3.js';
const { secretKey } = secp256k1.keygen();
const msg = new TextEncoder().encode('hello noble');
// prehash: true (default) - hash using secp256k1.hash (sha256)
const sig = secp256k1.sign(msg, secretKey);
// prehash: false - hash using custom hash
const sigKeccak = secp256k1.sign(keccak_256(msg), secretKey, { prehash: false });

デフォルトでは(prehash: true)、sign() と verify() はまずメッセージに曲線の組み込みハッシュを適用します: secp256k1 には sha256、p521 には sha512。prehash: false を使用するとカスタムハッシュ (例:secp256k1 + keccak_256)を使用できます。noble-curves v1 では、prehash: false がデフォルトでした。

署名から公開鍵を復元する```js

import { secp256k1 } from '@noble/curves/secp256k1.js'; const { secretKey, publicKey } = secp256k1.keygen(); const msg = new TextEncoder().encode('hello noble'); const sigRec = secp256k1.sign(msg, secretKey, { format: 'recovered' }); const publicKey_ = secp256k1.recoverPublicKey(sigRec, msg); // == publicKey

// recovered sig is compact sig with an extra byte const sigNoRec = secp256k1.sign(msg, secretKey, { format: 'compact' }); // sigNoRec == sigRec.slice(1)

// Signature instance const sigInstance = secp256k1.Signature.fromBytes(sigRec, 'recovered');

root@kitploit:~
公開鍵復元はECDSAでのみサポートされています。これは単純な数学的操作です。
署名が実際に行われたという保証はありません。偽造された (r, s, h) はランダムな公開鍵に復元されますが、この特定の偽造された h につながる m を見つけることは現実的ではありません。

#### ノイズを用いたヘッジ付きECDSA```js
import { secp256k1 } from '@noble/curves/secp256k1.js';
const { secretKey } = secp256k1.keygen();
const msg = new TextEncoder().encode('hello noble');
// extraEntropy: false - default, hedging disabled
const sigNoisy = secp256k1.sign(msg, secretKey);
// extraEntropy: true - fetch 32 random bytes from CSPRNG
const sigNoisyA = secp256k1.sign(msg, secretKey, { extraEntropy: true });
// extraEntropy: bytes - specific extra entropy
const ent = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]);
const sigNoisy2 = secp256k1.sign(msg, secretKey, { extraEntropy: ent });

デフォルトでは、ECDSA署名は決定論的です(RFC 6979)。純粋に決定論的な署名はフォールト攻撃に対して脆弱であるため、BIP340 schnorrのような新しいスキームでは、署名生成にランダム性を取り入れています。これはヘッジングとも呼ばれます。extraEntropyはヘッジモードを有効にします。詳細については、Deterministic signatures are not your friendsをご覧ください。

コンセンサスフレンドリー性 vs 電子投票```js

import { ed25519 } from '@noble/curves/ed25519.js'; const { secretKey, publicKey } = ed25519.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = ed25519.sign(msg, secretKey); // zip215: true const isValid = ed25519.verify(sig, msg, publicKey); // SBS / e-voting / RFC8032 / FIPS 186-5 const isValidRfc = ed25519.verify(sig, msg, publicKey, { zip215: false });

root@kitploit:~
* `zip215: true`(デフォルト)は、[ZIP215](https://zips.z.cash/zip-0215) で定義された、より寛容で[コンセンサスに優しい](https://hdevalence.ca/blog/2020-10-04-its-25519am)検証ルールを使用します。
* `zip215: false` は厳格な RFC 8032 / FIPS 186-5 検証を強制し、SBS ベースの
  否認防止を追加します。これは契約署名、電子投票、ブロックチェーンに有用です。

どちらのモードも SUF-CMA(選択メッセージ攻撃に対する強存在的偽造不可能性)を備えています。
他のほとんどのライブラリは SUF-CMA も SBS も備えていません。
詳細は [Taming the many EdDSAs](https://eprint.iacr.org/2020/1244) を参照してください。

### ECDH: Diffie-Hellman 共有秘密```js
import { x25519 } from '@noble/curves/ed25519.js';
const alice = x25519.keygen();
const bob = x25519.keygen();
const sharedKey = x25519.getSharedSecret(alice.secretKey, bob.publicKey);
// Same API: secp256k1, p256, p384, p521, x448

// converting ed25519 keys to x25519
import { ed25519 } from '@noble/curves/ed25519.js';
const alice2 = ed25519.keygen();
const bob2 = ed25519.keygen();
const aliceSecX = ed25519.utils.toMontgomerySecret(alice2.secretKey);
const bobPubX = ed25519.utils.toMontgomery(bob2.publicKey);
const sharedKey2 = x25519.getSharedSecret(aliceSecX, bobPubX);

すべてのWeierstrass曲線、および2つのMontgomery曲線 X25519 (Curve25519) と X448 (Curve448) 上でECDHを提供し、RFC 7748 に準拠しています。

Weierstrass曲線では、共有秘密は:

  • y-parityバイトを含みます:key.slice(1) を使用してそれを除去します
  • ハッシュ化されません:sha256(shared) や hkdf(shared) のように、その上でハッシュ化またはKDFを使用します

webcrypto: フレンドリーなラッパー```js

import { ed25519, x25519 } from '@noble/curves/webcrypto.js';

// signatures: p256, p384, p521, ed25519, ed448 const keys = await ed25519.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = await ed25519.sign(msg, keys.secretKey); const isValid = await ed25519.verify(sig, msg, keys.publicKey);

// ECDH: p256, p384, p521, x25519, x448 const alice = await x25519.keygen(); const bob = await x25519.keygen(); const shared = await x25519.getSharedSecret(alice.secretKey, bob.publicKey);

// key conversion between noble (raw) and webcrypto (pkcs8 / spki) formats import { p256 as p256n } from '@noble/curves/nist.js'; import { p256 } from '@noble/curves/webcrypto.js'; const nobleKeys = p256n.keygen(); const secretKeyPkcs8 = await p256.utils.convertSecretKey(nobleKeys.secretKey, 'raw', 'pkcs8'); const publicKeySpki = await p256.utils.convertPublicKey(nobleKeys.publicKey, 'raw', 'spki');

root@kitploit:~
組み込みのWebCryptoを薄くラップし、noble APIを模倣しています。メソッドは常に非同期です。
ランタイムのサポートは異なります - `await curve.isSupported()` で確認してください。
純粋なJSの鍵変換ユーティリティについては、[micro-key-producer](https://github.com/paulmillr/micro-key-producer) をチェックしてください。

### BLS署名、bls12-381、bn254 別名 alt_bn128```ts
import { bls12_381 } from '@noble/curves/bls12-381.js';

// G1 pubkeys, G2 sigs
const blsl = bls12_381.longSignatures;
const { secretKey, publicKey } = blsl.keygen();
const msg = new TextEncoder().encode('hello noble');
const msgp = blsl.hash(msg); // hash to point, default DST
const msgpd = blsl.hash(msg, 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_'); // custom DST (Ethereum)
const signature = blsl.sign(msgp, secretKey);
const isValid = blsl.verify(signature, msgp, publicKey);

// G1 sigs, G2 pubkeys: identical API
const blss = bls12_381.shortSignatures;

// Aggregation
const aggregatedKey = blsl.aggregatePublicKeys([
  blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
  blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
]);
// const aggregatedSig = blsl.aggregateSignatures(sigs)

// Pairings: bls12_381.pairing(PointG1, PointG2)
// Fields: bls12_381.fields.Fp, Fp2, Fp12, Fr

例えば、BLS EVMプリコンパイルの実装を参照してください。

BN254 APIはbls12-381を反映しています。この曲線は以前alt_bn128と呼ばれていました。 この実装はEIP-196および EIP-197と互換性があります: bn254 EVMプリコンパイルの実装を参照してください。 bn254の点はtoBytesを実装していません。シリアライゼーション標準が存在しないためです: 実装はエンディアン、フラグ、G2の虚部の順序で分岐します。 代わりにbigintから点を初期化してください。

hash-to-curve: 曲線点へのハッシュ```ts

import { secp256k1_hasher } from '@noble/curves/secp256k1.js';

const msg = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]); const point = secp256k1_hasher.hashToCurve(msg); const pointDst = secp256k1_hasher.hashToCurve(msg, { DST: 'hello noble' }); const pointNu = secp256k1_hasher.encodeToCurve(msg); const scalar = secp256k1_hasher.hashToScalar(msg);

// Same API: p256_hasher, p384_hasher, p521_hasher (nist.js), // ed25519_hasher, ristretto255_hasher (ed25519.js), ed448_hasher, decaf448_hasher (ed448.js), // bls12_381.G1, bls12_381.G2. // ristretto255 & decaf448 also provide deriveToCurve.

// abstract methods import { expand_message_xmd, expand_message_xof, hash_to_field } from '@noble/curves/abstract/hash-to-curve.js';

root@kitploit:~
モジュールは任意の文字列を楕円曲線上の点にハッシュ化できるようにします。[RFC 9380](https://www.rfc-editor.org/rfc/rfc9380) を実装しています。
`_hasher` 名前空間はツリーシェイキングのために曲線とは分離されています:
hash-to-curve を必要としないユーザーのビルドには含まれません。

### OPRFs```js
import { p256_oprf, p384_oprf, p521_oprf } from '@noble/curves/nist.js';
import { ristretto255_oprf } from '@noble/curves/ed25519.js';
import { decaf448_oprf } from '@noble/curves/ed448.js';

我々は、RFC 9497 に準拠した OPRF(oblivious pseudorandom functions)を提供します。

OPRF は、Output = PRF(Input, serverSecretKey) を対話的に生成することを可能にします:

  • サーバーは単独で Output を計算できません:サーバーは Input を知りません
  • クライアントは単独で Output を計算できません:クライアントは server secretKey を知りません
  • 通信を傍受した攻撃者は Input/Output/serverSecretKey を復元できず、Input を何らかの値に 関連付けることもできません。

FROST しきい値署名

FROST は RFC 9591 しきい値 Schnorr 署名を実装しています。 アプリケーションの観点からはマルチシグに似ています:max 人中 min 人の参加者が 共同で共有公開鍵の下で1つの Schnorr 署名を生成できます。 サポートされる暗号スイートは p256_FROST、ed25519_FROST、ed448_FROST、ristretto255_FROST、 secp256k1_FROST、および schnorr_FROST(Taproot 互換の secp256k1)です。 署名は2ラウンドで行われます:選択された署名者が最初にコミットし、その後署名シェアを生成します。```js import { p256_FROST } from '@noble/curves/nist.js';

const signers = { min: 2, max: 3 }; const alice = p256_FROST.Identifier.derive('[email protected]'); const bob = p256_FROST.Identifier.derive('[email protected]'); const carol = p256_FROST.Identifier.derive('[email protected]'); // trusted dealer const deal = p256_FROST.trustedDealer(signers, [alice, bob, carol]); for (const id of [alice, bob, carol]) p256_FROST.validateSecret(deal.secretShares[id], deal.public);

const msg = new TextEncoder().encode('hello threshold'); // round 1: selected signers commit const aliceRound1 = p256_FROST.commit(deal.secretShares[alice]); const bobRound1 = p256_FROST.commit(deal.secretShares[bob]); const commitmentList = [aliceRound1.commitments, bobRound1.commitments]; // round 2: signers produce signature shares const sigShares = { [alice]: https://raw.githubusercontent.com/paulmillr/noble-curves/main/p256_FROST.signShare( deal.secretShares[alice], deal.public, aliceRound1.nonces, commitmentList, msg ), [bob]: https://raw.githubusercontent.com/paulmillr/noble-curves/main/p256_FROST.signShare( deal.secretShares[bob], deal.public, bobRound1.nonces, commitmentList, msg ), }; const sig = p256_FROST.aggregate(deal.public, commitmentList, msg, sigShares); const isValid = p256_FROST.verify(sig, msg, deal.public.commitments[0]);

root@kitploit:~
鍵生成は、信頼できるディーラー(上記)または DKG(分散鍵生成)で行えます。
DKG には 3 つのラウンドがあります。参加者が鍵生成にコミットし、秘密シェアを交換し、
その後、最終的な参加者鍵を導出します - [テスト](https://github.com/paulmillr/noble-curves/blob/main/test/rfc9591-frost.test.ts) の
`DKG.round1` / `round2` / `round3` の使用例を参照してください。
このライブラリは暗号処理のステップを実装しており、周辺のアプリケーションプロトコルは実装していません。
呼び出し側は依然として、認証された通信、調整、リトライ、セッション管理、ポリシーを用意する必要があります。

### poseidon: Poseidon ハッシュ

[Poseidon](https://www.poseidon-hash.info) ZK フレンドリーなハッシュを実装しています。
置換とスポンジです。

poseidon には異なる定数を持つ多くのバリアントがあります。
それらは提供していません。手動で構築する必要があります。
適切な例については [scure-starknet](https://github.com/paulmillr/scure-starknet) パッケージを参照してください。```ts
import { bn254 } from '@noble/curves/bn254.js';
import { grainGenConstants, poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon.js';

const rate = 2;
const capacity = 1;
const Fp = bn254.fields.Fr;
const { mds, roundConstants } = grainGenConstants({
  Fp,
  t: rate + capacity,
  roundsFull: 8,
  roundsPartial: 31,
});
const opts = {
  Fp,
  rate,
  capacity,
  sboxPower: 17,
  mds,
  roundConstants,
  roundsFull: 8,
  roundsPartial: 31,
};
const permutation = poseidon({ ...opts, t: rate + capacity });
const sponge = poseidonSponge(opts); // use carefully, not specced

fft: 高速フーリエ変換```ts

import * as fft from '@noble/curves/abstract/fft.js'; import { bls12_381 } from '@noble/curves/bls12-381.js'; const Fr = bls12_381.fields.Fr; const roots = fft.rootsOfUnity(Fr, 7n); const fftFr = fft.FFT(roots, Fr);

root@kitploit:~
有限体上の NTT / FFT (高速フーリエ変換)。

### utils: バイトシャッフリング、変換```ts
import { bytesToHex, concatBytes, equalBytes, hexToBytes } from '@noble/curves/utils.js';

bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23]));
hexToBytes('cafe0123');
concatBytes(Uint8Array.from([0xca, 0xfe]), Uint8Array.from([0x01, 0x23]));
equalBytes(Uint8Array.of(0xca), Uint8Array.of(0xca));

内部構造

楕円曲線ポイント演算```js

import { secp256k1 } from '@noble/curves/secp256k1.js'; const { Point } = secp256k1; const { BASE, ZERO, Fp, Fn } = Point; const p = BASE.multiply(2n);

// Math const p1 = p.add(p); const p2 = p.double(); const p3 = p.subtract(p); const p4 = p.negate(); const p5 = p.multiply(451n);

// MSM (multi-scalar multiplication) import { pippenger } from '@noble/curves/abstract/curve.js'; const pa = [BASE, BASE.multiply(2n), BASE.multiply(4n), BASE.multiply(8n)]; const p6 = pippenger(Point, pa, [3n, 5n, 7n, 11n]); // == BASE.multiply(129n)

// Cofactor const pcl = p.clearCofactor(); const isTorsionFree = p.isTorsionFree();

// Conversions const bytes = p.toBytes(); const p_ = Point.fromBytes(bytes); const { x, y } = p.toAffine(); const p__ = Point.fromAffine({ x, y });

root@kitploit:~
各曲線は自身の Point クラスを公開しています: secp256k1、schnorr、p256、p384、p521、ed25519、ed448、
ristretto255、decaf448、bls12_381.G1 / G2、bn254.G1、jubjub、babyjubjub。
Weierstrass 点は射影(同次)座標 `new Point(X, Y, Z)` を使用し、
edwards 点は拡張座標 `new Point(X, Y, Z, T)` を使用します。どちらも x=X/Z、y=Y/Z です。

#### modular: モジュラー演算と有限体```js
import { mod, invert, Field } from '@noble/curves/abstract/modular.js';

// Finite Field utils
const fp = Field(2n ** 255n - 19n); // Finite field over 2^255-19
fp.mul(591n, 932n); // multiplication
fp.pow(481n, 11024858120n); // exponentiation
fp.div(5n, 17n); // division: 5/17 mod 2^255-19 == 5 * invert(17)
fp.inv(5n); // modular inverse
fp.sqrt(4n); // square root

// Non-Field generic utils are also available
mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse

すべての算術演算は、modular サブモジュールで定義された有限体上の JS bigint を用いて行われます。

体の演算は定数時間ではありません: security を参照してください。 この事実はほとんど無関係ですが、念頭に置くべき重要なメソッドは pow であり、これは素朴に使用すると指数のビットが漏洩する可能性があります。

weierstrass: カスタム Weierstrass 曲線 & ECDSA```js

import { weierstrass, ecdsa } from '@noble/curves/abstract/weierstrass.js'; import { sha256 } from '@noble/hashes/sha2.js'; // NIST secp192r1 aka p192. https://www.secg.org/sec2-v2.pdf const p192_CURVE = { p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn, n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n, h: 1n, a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn, b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n, Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n, Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n, }; const p192_Point = weierstrass(p192_CURVE); const p192 = ecdsa(p192_Point, sha256);

const keys = p192.keygen(); const msg = new TextEncoder().encode('custom curve'); const sig = p192.sign(msg, keys.secretKey); const isValid = p192.verify(sig, msg, keys.publicKey);

root@kitploit:~
Short Weierstrass 曲線の式は `y² = x³ + ax + b` です。`weierstrass` は引数として `a`、`b`、体の標数 `p`、曲線の位数 `n`、余因子 `h`、生成点の座標 `Gx`、`Gy` を受け取り、Point クラスを返します。`ecdsa` は Point クラスとハッシュ関数を組み合わせて署名スキームにします。

#### edwards: カスタム Edwards 曲線```js
import { edwards } from '@noble/curves/abstract/edwards.js';
const ed25519_CURVE = {
  p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
  n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
  h: 8n,
  a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
  d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
  Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
  Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,
};
const ed25519_Point = edwards(ed25519_CURVE);

Twisted Edwards曲線の式は ax² + y² = 1 + dx²y² です。 a、d、体の標数 p、曲線の位数 n(L と呼ばれることもあります)、 コファクター h、生成点の座標 Gx、Gy を指定する必要があります。

仕様

  • ECDSA: RFC 6979 による決定論的 k、 cfrg-det-sigs-with-noise draft によるヘッジ付き署名
  • EdDSA: RFC 8032、 FIPS 186-5、 コンセンサスフレンドリーな検証: ZIP215
  • Schnorr署名: BIP 340
  • X25519、X448 ECDH: RFC 7748
  • ristretto255、decaf448: RFC 9496
  • hash-to-curve: RFC 9380
  • OPRF: RFC 9497
  • FROST: RFC 9591
  • bn254: EIP-196、EIP-197
  • Poseidon: サイト

セキュリティ

このライブラリは監査を受けています:

  • バージョン2.3.0、2026年8月、Trail of Bits による、OpenAIとの協力のもと
    • 「Patch the Planet」イニシアチブの期間中に実施されました
    • 対象範囲: すべて
  • バージョン1.6.0、2024年9月、Cure53 による独立した監査
    • PDF: ウェブサイト、リポジトリ内
    • 対象範囲: ed25519、ed448、それらのアドオン、bls12-381、bn254、 hash-to-curve、低レベルプリミティブ bls、tower、edwards、montgomery
    • この監査は OpenSats によって資金提供されました
  • バージョン1.2.0、2023年9月、Kudelski Security による独立した監査
    • PDF: リポジトリ内
    • 対象範囲: scure-starknet およびその関連する noble-curves の抽象モジュール: curve、modular、poseidon、weierstrass
    • この監査は Starkware によって資金提供されました
  • バージョン0.7.3、2023年2月、Trail of Bits による独立した監査
    • PDF: ウェブサイト、 リポジトリ内
    • 対象範囲: 抽象モジュール curve、、、、、 および トップレベルモジュール と

2026年4月から定期的なAI支援による自己監査を開始しました。

プロパティベース、クロスライブラリ、Wycheproofのテストベクターに対してテストされ、 GitHub CIでファジングされています。

異常な点を見つけた場合は、調査して報告してください。

定数時間性

私たちはアルゴリズム的な定数時間を目標としています。JITコンパイラ と ガベージコレクタ は、 スクリプト言語において「定数時間」のタイミング攻撃耐性を 達成することを極めて困難にします。つまり、他のどのJSライブラリも定数時間性を持ち得ません。 GCのない言語である静的に型付けされたRustでさえ、 一部のケースでは定数時間の達成をより困難にします。 絶対的なセキュリティを目標とするなら、ネイティブへのバインディングを含め、どのJSライブラリも使用しないでください。 低レベルのライブラリと言語を使用してください。

これらの制限の中で、秘密スカラー乗算は具体的で測定可能な特性を提供します:

  • 固定された演算順序: multiply() はデータ難読化されたテーブルスキャンを伴う符号付き固定ウィンドウテーブルを使用します — 点演算の数と順序はスカラー値に依存しません。
  • スカラーブラインディング: 秘密スカラーはさらに、乗算の前にランダムな128ビットの r を用いて s + r·n としてマスクされます。 これはコファクター1の曲線(p256、p384、p521、secp256k1)上のすべての乗算、およびすべての場所での基点乗算に適用されます。
  • 統計的検証: dudectスタイルのWelchのt検定ハーネス(benchmark/ct.ts)が、 敵対的なスカラークラス(疎 vs 密、低ビット vs 高ビット、位数付近、ビットパターン)間でタイミングを比較します。 基点乗算はどの曲線でも識別可能なタイミングを示さず、ランダム点乗算はWeierstrass曲線で何も示しません (1000サンプルで最大 |t| ≤ 2.8、閾値4.5)。

既知の制限: コファクター付きEdwards曲線(ed25519、ed448)では、非基点を秘密スカラーで乗算する場合、 ブラインディングされません。同じハーネスがこれを確実に検出します。EdDSA署名は影響を受けず(ブラインドされた基点のみを乗算します)、 X25519/X448は別のMontgomery-ladder実装を使用します(これも影響を受けません)。これは、任意のEdwards/Ristretto点を 長期間存続する秘密スカラーで乗算するプロトコルにとって重要です。そのような場合は、構造上フル幅であるスカラーを優先してください。 孤立したハーネスでの検出可能性は、実用的な悪用可能性を意味しないことに注意してください。現実的な クロステナント/ブラウザ内設定でスカラー抽出を試みましたが、100,000のタイミングサンプルがあっても Edwardsスカラーを復元することはできませんでした。

メモリダンプ

絶対的なセキュリティを目標とするなら、JS / WASM の代わりに低レベルの言語を使用してください。

このライブラリは主にUint8Arrayとbigintを使用します。

  • Uint8Arrayには .fill(0) があり、内容をゼロで埋めるよう指示しますが、 JSでは保証はありません
  • bigintは不変であり、その内容をゼロ化するメソッドがありません: ユーザーは次のガベージコレクションサイクルまで待つ必要があります
  • 16進文字列も不変です: それらをゼロ化する方法はありません
  • await fn() はすべての内部変数をメモリに書き込みます。非同期関数では、 コードチャンクがいつ実行されるかの保証はありません。つまり、攻撃者は メモリからデータを読み取る十分な時間を持つ可能性があります。

これは、一部の秘密が予想よりも長くメモリに留まる可能性があることを意味します。 しかし、攻撃者がアプリケーションメモリを読み取れるなら、いずれにせよ手遅れです: プロセスメモリをダンプして機密データが残っていないことを検証する複雑なテストスイートなしには、 機密データのゼロ化について何も保証する方法はありません。JSの場合、それはすべてのブラウザ(モバイルを含む)を テストすることを意味します。そしてもちろん、このライブラリを利用する実際のアプリケーションで 同じテストスイートを使用しなければ役に立ちません。

サプライチェーンセキュリティ

  • コミット は偽造を防ぐためにPGPキーで署名されています。コミット署名を必ず検証してください
  • リリース はトークンなしのGitHub CIとTrusted Publishingを通じて透過的に行われます。真正性のためにprovenanceログを必ず検証してください。
  • リリース頻度の抑制 は、エンドユーザーによる再監査の必要性を最小限に抑えるために実践されています。
  • 依存関係 はサプライチェーンリスクを減らすために最小化され、厳密に固定されています。
    • できるだけ少ない依存関係を使用します。
    • バージョン範囲はロックされ、変更はnpm-diffでチェックされます。
  • 開発依存関係 はエンドユーザーのインストールから除外されます。それらは開発とビルドのステップにのみ使用されます。

このパッケージには1つの依存関係があり、いくつかの開発依存関係があります:

  • noble-hashes は暗号学的ハッシュ機能を提供します
  • jsbtはベンチマーク/テスト/ビルドツールに使用され、同じ作者によって開発されています
  • prettier、fast-check、typescriptはコード品質/テスト生成/TSコンパイルに使用されます

ランダム性

私たちは、暗号学的に安全なPRNGと見なされる組み込みの crypto.getRandomValues に依存しています。

ブラウザは過去に弱点を持っていました — そして再び持つ可能性もあります — が、ユーザー空間のCSPRNGを実装するのはさらに悪いことです。 なぜなら、高品質なエントロピーの信頼できるユーザー空間の供給源が存在しないからです。

量子コンピュータ

暗号学的に関連する量子コンピュータが構築されれば、Shorのアルゴリズムを使用して 楕円曲線暗号(ECDSA / EdDSA と ECDH の両方)を破ることが可能になります。

SPHINCS+ など、より新しい/ハイブリッドなアルゴリズムへの切り替えを検討してください。それらは noble-post-quantum で利用可能です。

NISTは古典暗号(RSA、DSA、ECDSA、ECDH)を2035年以降禁止しています。オーストラリアのASDは2030年以降禁止しています。

速度```sh

npm run benchmark

root@kitploit:~
noble-curvesは、20MB以上のベースポイント事前計算を生成するのに10ms以上を費やします。
これはカーブごとに**一度だけ**行われます。

生成は、いずれかのメソッド(pubkey、sign、verify)が呼び出されるまで遅延されます。
ユーザーは `Point.BASE.precompute(windowSize, false)` を手動で呼び出すことで、事前計算の生成を強制できます。
ソースコードを確認してください。

Apple M4でのベンチマーク結果:```
# algorithm=getPublicKey
ed25519                    7,299 ops/sec · 137 μs/op
secp256k1                  4,872 ops/sec · 205 μs/op · -1.5x
p256                       4,724 ops/sec · 212 μs/op · -1.5x
bls12_381 (long, G2 sig)   3,466 ops/sec · 288 μs/op · -2.1x
ed448                      3,224 ops/sec · 310 μs/op · -2.3x
p384                       2,185 ops/sec · 458 μs/op · -3.3x
p521                       1,221 ops/sec · 819 μs/op · -6x
bls12_381 (short, G1 sig)  1,070 ops/sec · 934 μs/op · -6.8x

# algorithm=sign
secp256k1                  4,217 ops/sec · 237 μs/op
p256                       4,116 ops/sec · 243 μs/op · ≈
ed25519                    3,536 ops/sec · 283 μs/op · -1.2x
p384                       1,992 ops/sec · 502 μs/op · -2.1x
ed448                      1,577 ops/sec · 634 μs/op · -2.7x
p521                       1,131 ops/sec · 884 μs/op · -3.7x
bls12_381 (short, G1 sig)  417 ops/sec · 2.39 ms/op · -10x
bls12_381 (long, G2 sig)   112 ops/sec · 8.88 ms/op · -37x

# algorithm=verify
ed25519                    1,504 ops/sec · 665 μs/op
secp256k1                  1,352 ops/sec · 739 μs/op · -1.1x
p256                       917 ops/sec · 1.09 ms/op · -1.6x
ed448                      546 ops/sec · 1.83 ms/op · -2.8x
p384                       381 ops/sec · 2.62 ms/op · -3.9x
p521                       187 ops/sec · 5.34 ms/op · -8x
bls12_381 (short, G1 sig)  100 ops/sec · 9.98 ms/op · -15x
bls12_381 (long, G2 sig)   77 ops/sec · 12.9 ms/op · -19x

# algorithm=getSharedSecret
ed25519                    1,695 ops/sec · 590 μs/op
secp256k1                  763 ops/sec · 1.31 ms/op · -2.2x
p256                       737 ops/sec · 1.36 ms/op · -2.3x
ed448                      599 ops/sec · 1.67 ms/op · -2.8x
p384                       326 ops/sec · 3.06 ms/op · -5.2x
p521                       176 ops/sec · 5.68 ms/op · -9.6x

アップグレード

サポートされている node.js バージョン:

  • v2 (2025-08): v20.19+ (ESM のみ)
  • v1 (2023-04): v14.21+ (ESM & CJS)

v1 から v2 へ

v2 は内部構造を大幅に簡素化し、セキュリティを向上させ、バンドルサイズを削減し、将来への道筋をつけます。 私たちは v2 を可能な限り後方互換に保つよう努めました。

アップグレードパス: まず curves v1.9.x にアップグレードしてください。非推奨の警告を修正してから、v2 に切り替えてください。

モジュール:

  • パッケージは ESM のみになりました。ESM はついに node v20.19+ の common.js から読み込めるようになりました
  • .js 拡張子が必須になりました: @noble/curves/ed25519 => @noble/curves/ed25519.js。 これによりトランスパイラなしでネイティブのブラウザ利用が可能になります
  • p256、p384、p521 は nist に移動しました; jubjub は misc に移動しました
  • pasta と bn254_weierstrass (ペアリングベースではない bn254) 曲線は削除されました

新機能:

  • webcrypto: 組み込み WebCrypto のための、noble ライクなフレンドリーなラッパー
  • oprf: RFC 9497 OPRF (oblivious pseudorandom functions)。 p256、p384、p521、ristretto255、decaf448 に対応
  • weierstrass、edwards: 新しい isValidSecretKey、isValidPublicKey メソッド
  • misc: Brainpool 曲線 brainpoolP256r1、brainpoolP384r1、brainpoolP512r1
  • 大幅に改善され、より説明的になったエラーメッセージ

破壊的変更:

  • ほとんどのメソッドは Uint8Array のみを受け付けるようになりました; 文字列の hex 入力は禁止されています。 これにより推論が簡素化され、セキュリティが向上し、可鍛性が低減されます。 Point.fromHex は文字列専用になりました: Uint8Array には Point.fromBytes を使用してください
  • ECDSA (secp256k1、p256、p384...) の署名と検証:
    • Prehashed メッセージ: メソッドは messageHash ではなく ハッシュ化されていないメッセージを期待するようになりました。以前の動作: {prehash: false}
    • デフォルトで lowS 署名。secp256k1 は影響を受けません: 最初から lowS を使用していました。以前の動作: {lowS: false}
    • デフォルトで Uint8Array 署名 (フォーマット: 'compact')
    • verify: der フォーマットは {format: 'der'} で明示的に指定する必要があります。 これにより可鍛性が低減されます
    • verify: Signature インスタンスは禁止されています: 先に signature.toBytes() を呼び出してください
  • BLS 署名 (bls12-381、bn254):
    • getPublicKey、sign、verify、signShortSignature などは 2 つの新しい名前空間に移動しました: longSignatures (G1 公開鍵、G2 署名) と shortSignatures (G1 署名、G2 公開鍵)
    • verifyBatch は入力の配列 {message: ..., publicKey: ...}[] を期待するようになりました
  • カスタム曲線:
    • 曲線の作成は大幅に簡素化され、点の作成と 署名生成器の作成に分割されました: weierstrass() + ecdsa() / 。 weierstrass / edwards は簡素化された曲線パラメータを期待します (Fp は p になりました); ecdsa / eddsa は Point クラスとハッシュを期待します

名前の変更 (curves v1.9 では古い名前が非推奨としてハイライトされます):

  • Points
    • ExtendedPoint、ProjectivePoint => Point
    • Point の座標 px/ex、py/ey、pz/ez、et => X、Y、Z、T
    • toRawBytes、fromRawBytes => toBytes、fromBytes
    • Point.normalizeZ、Point.msm => abstract/curve.js サブモジュール内の個別のメソッド
    • Point.fromPrivateKey(key) => Point.BASE.multiply(Point.Fn.fromBytes(key))
    • あらゆる種類のランダムなものを含む CURVE プロパティ => Point.CURVE()。 これは曲線パラメータのみを提供します
    • RistrettoPoint => ristretto255.Point、DecafPoint => decaf448.Point
  • ECDSA 署名
    • toCompactRawBytes、toDERRawBytes => toBytes('compact')、toBytes('der')
    • toCompactHex、toDERHex => toHex('compact')、toHex('der')
    • fromCompact、fromDER => fromBytes(bytes, format)、fromHex(hex, format)
  • utils
    • randomPrivateKey => randomSecretKey
    • normPrivateKeyToScalar => Point.Fn.fromBytes
    • utils.precompute、Point#_setWindowSize => Point#precompute
    • edwardsToMontgomery、edwardsToMontgomeryPriv => utils.toMontgomery、utils.toMontgomerySecret
  • 曲線固有の hash-to-curve メソッド => *curve*_hasher。 例: secp256k1.hashToCurve => secp256k1_hasher.hashToCurve()
  • 大規模な型の名前変更と改善

削除された機能: Point#multiplyAndAddUnsafe、Point#hasEvenY、Field.MASK

コントリビューションとテスト

npm install && npm run build && npm test でコードをビルドし、テストを実行します。

追加のスイートがあります: 低速な大スカラー / 大曲線テスト npm run test:slow、 および定数時間性ハーネス npm run benchmark:ct。

ライブラリに関連する有用なリソース、記事、 ドキュメント、デモについては paulmillr.com/noble を参照してください。

ライセンス

The MIT License (MIT)

Copyright (c) 2022 Paul Miller (https://paulmillr.com)

LICENSE ファイルを参照してください。

ツールをダウンロード
hash-to-curve
modular
poseidon
utils
weierstrass
_shortw_utils
secp256k1
  • この監査は Ryan Shea によって資金提供されました
  • edwards() + eddsa()
  • pippenger: 不要な Fn 引数を削除しました
  • Field#fromBytes() は要素が 0..order-1 の範囲にあることを検証するようになりました