密码工具
一套现代密码学工具,为plebian开发商所建.
- 所有工具都用打字符写出并使用简便.
- 方法返回a 巴夫( Buff) 在格式之间快速转换的对象.
- 库在节点和浏览器中都工作.
- 使用经过审计的 @ noble/ 曲线 用于快速 ecc 操作的库.
import {
ecdh, // Basic methods for using the Elliptic-Curve Diffe-Hellman protocol.
hash, // Includes sha256, sha512, hmac, ripemd, tagged hashing, and more.
hd, // BIP-0032 based key derivation tool, with support for non-numeric paths.
keys, // A suite of tools for generating and tweaking secp256k1 key pairs.
math, // Bigint-based ecc math library, with added field and point arithmetic.
signer, // BIP-0340 'schnorr' based signing library with an extensive API.
tree, // A basic suite of tools for creating merkle trees and validating proofs.
Field, // A feature-rich uint8 array class with built-in math operations.
Point // A secp2561 point object with built-in math operations.
} from '@cmdcode/crypto-tools'
很快会有更多文件!
如何导入
这个库旨在支持在节点和浏览器环境中的经典和现代无害环境管理进口.
通过国家预防机制或纱线安装的实例:
npm install @cmdcode/crypto-tools || yarn add @cmdcode/crypto-tools
经典导入到节点项目 :
const { Field, Point } = require('@cmdcode/crypto-tools')
现代导入到节点项目 :
import { Field, Point } from '@cmdcode/crypto-tools'
经典导入到基于浏览器的项目 :
<script src="https://unpkg.com/@cmdcode/crypto-tools"></script>
<script>
const { Field, Point } = window.crypto_tools
</script>
现代导入到基于浏览器的项目 :
<script type="module">
import { Field, Point } from "https://unpkg.com/@cmdcode/crypto-tools/dist/module.mjs"
</script>
如何使用
这个套房由个人工具组成.
每个工具都可以从主库中拆出,或者直接导入并拆出.
// Import tool from main library, then unpack methods.
import { signer } from '@cmdcode/crypto-tools'
const { sign_msg, verify_sig } = signer
// Import methods from the tool directly.
import { sign_msg, verify_sig } from '@cmdcode/crypto-tools/signer'
许多方法将接受 Bytes 值类型,返回 a Buff 对象。 这个 Bytes 类型覆盖任何可以被转换成原始字节的数据类型.
type Bytes = string | number | bigint | Uint8Array | Buff
Buff 取代标准的工作 Uint8Array 并提供若干快速转换方法.
const seckey = get_seckey('deadbeef'.repeat(4))
console.log('secret raw :', seckey)
console.log('secret hex :', seckey.hex)
console.log('secret big :', seckey.big)
你可以读更多关于 Buff API 密码 这里。 。 。 .
ECDH 工具
使用椭圆形-Curve Dife-Hellman协议,从两个密钥之间获取一个共享的秘密.
import {
get_shared_key // Get the shared secret for a given secret / public key pairing.
get_shared_code // Use the derived secret to sign a message with HMAC-512.
} from '@cmdcode/crypto-tools/ecdh'
散列工具
用于执行SHA-256,SHA-512,HMAC-256,HMAC-512等有用的散开方法.
import {
sha256, // Uses standard SHA-256 algorithm.
sha512, // Uses standard SHA-512 algorithm.
ripe160, // Uses RIPEMD-160 algorithm.
hash160, // A double-hash algorithm used in bitcoin.
hash256, // A double-hash algorithm used in bitcoin.
hmac256, // Hash and sign a message using HMAC and SHA-256.
hmac512, // Hash and sign a message using HMAC and SHA-512.
taghash, // Creates a BIP-0340 standard 'tag' hash.
hash340, // Hashes an array of data using BIP-0340 standards.
} from '@cmdcode/crypto-tools/hash'
实例:
// Each hash tool can accept many byte-compatible values.
const hash = sha256('fda0', 1024n, new Uint8Array(0), 42)
// Use the taghash tool to create a BIP-0340 standard hash commitment.
const challenge = hash340('BIP0340/challenge', sig, pubkey, msg)
HD 工具
从 BIP-0032 样式衍生路径生成一对密钥 .
import {
derive_key, // Derive a key-pair using a BIP-0032* path of deterministic key tweaks.
parse_tweaks, // Helper method to convert a derivation path into an array of tweaks.
generate_code, // Generator method used to create the hash-chain.
encode_extkey // Export a derived key-pair as a base58-encoded extended key.
parse_extkey // Parse a base58-encoded extended key into its keys and meta-data.
derive_extkey // Parse an extended key, then use a path to derive a child key-pair.
} from '@cmdcode/crypto-tools/hd'
说明: 衍生工具还支持在衍生路径中使用非数字字符.
实例:
import { derive_key, encode_extkey } from '@cmdcode/crypto-tools/hd'
// Define some sample data.
const seed = 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542'
const path = "m/0/2147483647'/1/2147483646'/2"
// Derive the key using the seed and derivation path.
const key_data = derive_key(path, seed)
// Resulting key data:
console.log('link:', key_data)
link: {
seckey : 'bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23',
pubkey : '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c',
code : '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271',
path : "m/0/2147483647'/1/2147483646'/2",
prev : '02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0'
}
// You can convert the key data into a base58 extended key.
const extkey = encode_extkey(keylink)
// Resulting extkey:
'extkey : xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j'
密钥对等工具
二相256k1曲线上与密钥对配合的方法.
import {
get_seckey, // Convert a number or byte value into a secp256k1 secret key.
get_pubkey, // Generate a secp256k1 public key for a given secret key.
tweak_seckey, // Apply an array of additional tweaks to a secret key.
tweak_pubkey, // Apply an array of additional tweaks to a public key.
gen_seckey, // Generate a random secret key (using Web Crypto API).
negate_seckey, // Perform a field negation operation on a secret key.
gen_keypair, // Generate a secp256k1 secret and public key pair.
get_keypair, // Convert a number or byte value into a secp256k1 key pair.
convert_32b, // Convert any public key into a 32-byte x-only key.
convert_33b, // Convert any public key into a 33-byte compressed key.
} from '@cmdcode/crypto-tools/keys'
实例:
import { gen_seckey, get_pubkey } from '../src/keys.js'
// Configure a demo keypair and message.
const seckey = gen_seckey()
const pubkey = get_pubkey(seckey, true)
console.log('seckey:', seckey.hex)
console.log('pubkey:', pubkey.hex)
数学库
用于进行算术和场/点操作的大写数学库.
import {
fd, // Perform various modulo arithmetic using secp256k1 field order N.
pt, // Perform various point operations using secp256k1 field order P.
mod, // Apply a modulo for a bigint value.
mod_n, // Apply modulo N for a bigint value.
mod_p, // Apply modulo P for a bigint value.
pow, // Raise a number to a given power.
pow2, // Raise a number 2x to a given power.
pow_n, // Raise a number to a given power, modulo N.
sqrt_n, // Perform a square root operation on a bigint value, modulo N.
sqrt_p, // Perfrom a aquare root operation on a bigint value, modulo P.
invert, // Invert / negate a bigint field value.
mod_bytes, // Perform a modulo operation on a byte value.
in_field, // Check if a number is within the secp256k1 field order N.
on_curve // Check if a number is within the secp256k1 curve order P.
} from '@cmdcode/crypto-tools/math'
证明工具
一个简化了的数据验证系统,兼容诺斯特NIP-01所签名的事件.
import {
create_proof, // Create a compact signature proof.
parse_proof, // Parse a compact proof into JSON.
validate_proof, // Validate the schema of a proof.
verify_proof, // Verify the hash and signature of a proof.
create_event, // Convert a proof into a NIP-01 nostr note.
parse_config // Parse the proof configuration from params.
} from '@cmdcode/crypto-tools/proof'
实例:
// Setup a demo keypair and message.
const [ seckey, pubkey ] = gen_keypair()
// Create a proof.
const data = { name : 'bob', key : 'abcd' }
const stamp = Math.floor(Date.now() / 1000)
const params = [[ 'kind', 10000 ], [ 'stamp', stamp ]]
const proof = create_proof(seckey, data, params)
console.log(proof)
`e403621bae6dffd75c76b282cc3525da14bf55a4ee3c396279f35f766b4ad079749b45be02446dc32e4eab02be026eef1592a23c209eb8b571f4f78ac6a762405cc802eae19177096334c0d4e53add9c97dc200e3f2e5700bd17aee14beb01e983456c5cb3461f20c8f3d59e8386a0d8ad4c3d6f58cacb9fc85eef514b8fc1007c476558535de220aebc916b0974e8b76dd584ba14b479d947f9ee52c40333c8?kind=10000&stamp=1694095593`
// Verify a proof
const is_valid = verify_proof(proof, data)
console.log('is_valid:', is_valid)
`is_valid : true`
// Parse a proof into a ProofData object
const proof_data = parse_proof(proof)
console.log('proof data:', proof_data)
proof data: {
ref: 'e403621bae6dffd75c76b282cc3525da14bf55a4ee3c396279f35f766b4ad079',
pub: '749b45be02446dc32e4eab02be026eef1592a23c209eb8b571f4f78ac6a76240',
pid: '5cc802eae19177096334c0d4e53add9c97dc200e3f2e5700bd17aee14beb01e9',
sig: '83456c5cb3461f20c8f3d59e8386a0d8ad4c3d6f58cacb9fc85eef514b8fc1007c476558535de220aebc916b0974e8b76dd584ba14b479d947f9ee52c40333c8',
params: [ [ 'kind', '10000' ], [ 'stamp', '1694095593' ] ]
}
// Convert a proof into a nostr note.
const event = create_event(proof, data)
console.log('event:', event)
event: {
kind: 10000,
content: '{"name":"bob","key":"abcd"}',
tags: [],
pubkey: '749b45be02446dc32e4eab02be026eef1592a23c209eb8b571f4f78ac6a76240',
id: '5cc802eae19177096334c0d4e53add9c97dc200e3f2e5700bd17aee14beb01e9',
sig: '83456c5cb3461f20c8f3d59e8386a0d8ad4c3d6f58cacb9fc85eef514b8fc1007c476558535de220aebc916b0974e8b76dd584ba14b479d947f9ee52c40333c8',
created_at: 1694095593
}
签名工具
与基于BIP-0340"schnor"的数字签名合作的基本签名工具.
import {
sign_msg, // Sign a message using BIP-0340 standard.
verify_sig, // Verify a BIP-0340 signature, key and, message.
gen_nonce, // Generate a nonce for a given message.
recover_key // Recover the secret key from a signature using ECDH recovery.
} from '@cmdcode/crypto-tools/signer'
这个 sign_msg, (中文(简体) ), verify_msg,以及 gen_nonce 通过选项对象可配置方法:
export interface SignConfig {
// Specify the aux data to use as a seed. Default is random.
aux ?: Bytes | null
// Apply an adaptor tweak to the nonce value.
adaptors ?: Bytes[]
// Apply tweaks to the nonce value during generation.
nonce_tweaks ?: Bytes[]
// Specify a public key to be used in ECDH key recovery.
recovery_key ?: Bytes
// Apply tweaks to the signature value during signing.
key_tweaks ?: Bytes[]
// If validation fails, throw an error instead of returning false.
throws : boolean
// If keys used during the signing operation should be negated for even-ness.
xonly : boolean
}
实例:
import { gen_keypair } from '../src/keys.js'
import { sign_msg, verify_sig } from '../src/sig.js'
// Configure a demo keypair and message.
const [ seckey, pubkey ] = gen_keypair(true)
const message = 'abcd1234'.repeat(4)
// Sign the message, then validate the signature.
const sig = sign_msg(message, seckey)
const is_valid = verify_sig(sig, message, pubkey)
// Check the console output.
console.log('signature:', sig.hex)
console.log('is_valid:', is_valid)
密钥回收允许您使用 ECDH 指定另一个可以从签名中取回私人密钥的密钥.
// Configure two pairs of keys and a test message.
const [ hot_sec, hot_pub ] = gen_keypair(true)
const [ cold_sec, cold_pub ] = gen_keypair(true)
const message = 'feedcab123'
// Sign a message with the 'cold' pubkey as an ECDH recovery key.
const sig = sign_msg(message, hot_sec, { recovery_key: cold_pub })
在引擎盖下,密钥回收会修改非ce生成,从而使用ECDH共享的密钥而不是您的私钥.
// Normal BIP-0340 nonce generation.
let sec_nonce = taghash('BIP0340/nonce', seckey, pubkey, message)
// Modified nonce generation for ECDH key recovery:
let shared_key = ecdh.get_shared_key(seckey, rec_pubkey)
sec_nonce = hash340('BIP0340/nonce', shared_key, pubkey, message)
这样可以让"cold" sockey来计算共享的密钥,从而从签名中取出"hot" sockey.
// Use the signature and 'cold' seckey to recovery the secret key.
const rec_key = recover_key(sig, message, hot_pub, cold_sec)
// The recovered 'hot' seckey will be negated, so we will also negate
// the original key in order to compare it with the recovered key.
console.log('recovered key :', rec_key.hex)
`recovered key : c18d25e25c1b229d14bd97e0daf3e4453765c2e007d9023698458573517ccd55`
console.log('hot secret key :', get_seckey(hot_sec, true).hex)
`hot secret key : c18d25e25c1b229d14bd97e0daf3e4453765c2e007d9023698458573517ccd55`
通过ECDH找到密钥的公式共享了秘密签名:
R_value = sig.slice(0, 32)
s_value = sig.slice(32, 64)
sec_nonce = hash340('BIP0340/nonce', shared_key, pubkey, message)
challenge = hash340('BIP0340/challenge', R_value, pubkey, message)
sec_key = (s_value - sec_nonce) / challenge
外地
这个 Field 类将在秒256k1曲线下将键值或整数值转换为字段值。 此字段值包括一个内置的API,用于以简单可读的方式进行数学操作.
每个 Field 对象被存储为原始字节,它们可直接用作 Uint8Array。 。 。 .
示例
import { Field } from '@cmdcode/crypto-tools/ecc'
const seed = 'dead'.repeat(16)
const tweak = 'beef'.repeat(16)
const secret = Field.mod(seed)
const pubkey = secret.point
const twk_sec = secret.add(tweak)
const twk_pub = twk_sec.point
console.log('original seckey :', secret.hex)
console.log('original pubkey :', pubkey.hex)
console.log('tweaked seckey :', twk_sec.hex)
console.log('tweaked pubkey :', twk_pub.hex)
联合国文件 Field API : (英语)
// Fields can be created from a variety of types (strings are treated as hex).
type FieldValue = string | number | bigint | Uint8Array | Field
// The Field class is an extension of the uint8 data type.
class Field extends Uint8Array {
// Prime N reference.
static N: bigint
// Converts a value under secp256k1 field order N. Same as new Field(x).
static mod(x: bigint, n?: bigint): bigint
// Normalize input values into bytes.
static normalize(num: FieldValue): Uint8Array
// Checks if value is within the secp256k1 field order N.
static is_valid(num: bigint): boolean
// Convert into a variety of formats.
get buff : Buff
get raw : Uint8Array
get big : bigint
get hex : string
// Return point object.
get point : Point
// Checks if the point value of the field has an odd y coordinate.
get hasOddY : boolean
// Auto-negates the field value if it has an odd y coordiante.
get negated : Field
// All basic operations are available.
gt (big: FieldValue) : boolean
lt (big: FieldValue) : boolean
eq (big: FieldValue) : boolean
ne (big: FieldValue) : boolean
add (big: FieldValue) : Field
sub (big: FieldValue) : Field
mul (big: FieldValue) : Field
pow (big: FieldValue) : Field
div (big: FieldValue) : Field
negate() : Field
generate() : Point
}
点
这个 Point 类将在秒256k1曲线下将键值或整数值转换为点值。 这个点值包括一个内置的API,用于以简单可读的方式进行数学操作.
每个 Point 对象包含一个 x 协和a y 坐标,以比值存储 .
示例
import { Point } from '@cmdcode/crypto-tools/ecc'
const _pubkey = Point.from_x(secret.point.raw)
const _twk_pub = pubkey.add(tweak)
console.log('imported point :', _pubkey)
console.log('imported pubkey :', _pubkey.hex)
console.log('tweaked pubkey :', _twk_pub.hex)
联合国文件 Point API : (英语)
// Points can be created from a variety of types (strings are treated as hex).
type PointValue = string | number | bigint | Uint8Array | Point
// The Point class stores the x / y coordinates of a point on the secp256k1 curve.
class Point {
// Prime N reference.
static P : bigint
static G : Point
// Create a point from an existing compressed key.
static from_x(x: PointValue, xonly ?: boolean) : Point
// Generate a point from a field (scalar) value.
static generate(value: FieldValue) : Point
// Helper method for importing points from Noble library.
static import(point: Point | ECPoint) : Point
// Accepts a varity of x-only and compressed key inputs.
// Will also accept coordinate data (as bigint).
constructor (x: PointValue, y?: bigint)
// Convert into a variety of formats.
get x : Buff // Return a buff object.
get y : Buff // Return a buff object.
get buff : Buff // Returns compressed key as bytes.
get hex : string // Returns compressed key as hex.
get hasEvenY : boolean
get hasOddY : boolean
// Auto-negates the point value if it has an odd y coordiante.
get negated : Point
// Basic math operations available.
eq (value: PointValue) : boolean
add (x: PointValue) : Point
sub (x: PointValue) : Point
mul (value: PointValue) : Point
negate(): Point;
}
A 类 Point 也可以从一个 Field 对象,允许您主要使用 Field 课.
以下是使用BIP-0340数字签字的签字和核查的简化例子 Field 类 :
import { Field } from '@cmdcode/crypto-tools/ecc'
import { digest } from '@cmdcode/crypto-tools/hash'
// Generate some hex strings to use as a secret key and message.
const message = 'dead'.repeat(16)
const secret = 'beef'.repeat(16)
// Compute the pubkey, nonce, and challenge values.
const pubkey = Field.mod(secret).negated.point
const nonce = hash340('BIP0340/nonce', secret, pubkey.x, message)
const R_value = Field.mod(nonce).negated.point
const challenge = hash340('BIP0340/challenge', R_value.x, pubkey.x, message)
// Signature is composed of an R value and S value.
const s_value = Field.mod(secret).negated.mul(challenge).add(nonce)
const r_value = Field.mod(s_value).point.sub(pubkey.mul(challenge))
// Print the signature to console and report its validity.
console.log('signature :', R_value.x.hex + s_value.hex)
console.log('is valid :', R_value.hex === r_value.hex)
开发/测试
这个库使用纱线进行软件包管理,用磁带进行写作测试,并卷起跨平台发行. 下面是一些有利于发展的脚本.
## Performs a basic stress test for benchmarking performance.
yarn bench
## Compiles types and builds a new release in /dist folder.
yarn build
## Runs linting rules using ESLint and Typescript.
yarn lint
## Runs all TAP tests from the test/src folder.
yarn test
## Full script for generating a new release candidate.
yarn release
错误/ 问题
如果您遇到任何错误或有任何问题,请提交出票.
捐款
随意分叉作供养. 欢迎建议!
许可证
随便你用这个图书馆!