sm-js-bc
Version:
SM2/SM3/SM4 implementation in TypeScript based on Bouncy Castle Java
1,908 lines (1,860 loc) • 83.1 kB
TypeScript
/**
* 字节打包和解包工具类
* 用于处理大端序(Big Endian)的整数和字节数组转换
*
* 参考: org.bouncycastle.util.Pack
*/
declare class Pack {
/**
* 将字节数组转换为 32 位整数(大端序)
*
* @param bytes 字节数组
* @param offset 起始偏移量
* @returns 32位整数
*/
static bigEndianToInt(bytes: Uint8Array, offset: number): number;
/**
* 将 32 位整数转换为字节数组(大端序)
*
* @param value 32位整数
* @param bytes 目标字节数组
* @param offset 起始偏移量
*/
static intToBigEndian(value: number, bytes: Uint8Array, offset: number): void;
/**
* 将字节数组转换为 64 位整数(大端序)
*
* @param bytes 字节数组
* @param offset 起始偏移量
* @returns 64位大整数
*/
static bigEndianToLong(bytes: Uint8Array, offset: number): bigint;
/**
* 将 64 位整数转换为字节数组(大端序)
*
* @param value 64位大整数
* @param bytes 目标字节数组
* @param offset 起始偏移量
*/
static longToBigEndian(value: bigint, bytes: Uint8Array, offset: number): void;
}
/**
* 数组操作工具类
*
* 参考: org.bouncycastle.util.Arrays
*/
declare class Arrays {
/**
* 连接多个字节数组
* @param arrays 要连接的字节数组
* @returns 连接后的字节数组
*/
static concatenate(...arrays: Uint8Array[]): Uint8Array;
/**
* 用指定值填充数组
* @param array 要填充的数组
* @param value 填充值
*/
static fill(array: Uint8Array, value: number): void;
/**
* 比较两个字节数组是否相等
* @param a 第一个数组
* @param b 第二个数组
* @returns 数组是否相等
*/
static areEqual(a: Uint8Array, b: Uint8Array): boolean;
/**
* 常时间比较两个字节数组是否相等(抗时序攻击)
* @param a 第一个数组
* @param b 第二个数组
* @returns 数组是否相等
*/
static constantTimeAreEqual(a: Uint8Array, b: Uint8Array): boolean;
/**
* 复制数组的指定范围
* @param source 源数组
* @param from 起始位置
* @param to 结束位置(不包含)
* @returns 新数组
*/
static copyOfRange(source: Uint8Array, from: number, to: number): Uint8Array;
}
/**
* 字节操作工具类
*
* 参考: org.bouncycastle.util.Bytes
*/
declare class Bytes {
/**
* 将源数组的指定长度与目标数组进行异或操作,结果存入目标数组
*
* @param length 要异或的字节数
* @param src 源数组
* @param srcOff 源数组起始偏移量
* @param dest 目标数组
* @param destOff 目标数组起始偏移量
*/
static xorTo(length: number, src: Uint8Array, srcOff: number, dest: Uint8Array, destOff: number): void;
}
/**
* 大整数工具类
*
* 参考: org.bouncycastle.util.BigIntegers
*/
declare class BigIntegers {
static readonly ZERO = 0n;
/**
* 将 BigInt 转换为无符号字节数组(大端序),指定长度
*
* @param length 字节数组长度
* @param value BigInt 值
* @returns 字节数组
*/
static asUnsignedByteArray(length: number, value: bigint): Uint8Array;
/**
* 将无符号字节数组转换为 BigInt(大端序)
*
* @param bytes 字节数组
* @returns BigInt 值
*/
static fromUnsignedByteArray(bytes: Uint8Array): bigint;
/**
* 创建指定位长度的随机 BigInt
*
* @param bitLength 位长度
* @param random 随机数生成器(提供 nextBytes 方法)
* @returns 随机 BigInt
*/
static createRandomBigInteger(bitLength: number, random: {
nextBytes(bytes: Uint8Array): void;
}): bigint;
/**
* 计算模逆(当模数为奇数时)
*
* @param mod 模数
* @param value 值
* @returns 模逆
*/
static modOddInverse(mod: bigint, value: bigint): bigint;
/**
* 计算模逆(通用方法)
*
* @param a 值
* @param m 模数
* @returns 模逆
*/
private static modInverse;
/**
* 计算模幂:(base^exponent) mod m
* 使用快速幂算法(二进制方法)
*
* @param base 底数
* @param exponent 指数
* @param m 模数
* @returns 模幂结果
*/
static modPow(base: bigint, exponent: bigint, m: bigint): bigint;
/**
* 获取 BigInt 的位长度(最高位1的位置+1)
*
* @param value BigInt 值
* @returns 位长度
*/
static bitLength(value: bigint): number;
/**
* 测试指定位是否为1
*
* @param value BigInt 值
* @param n 位索引(从0开始,0表示最低位)
* @returns 如果第n位为1返回true,否则返回false
*/
static testBit(value: bigint, n: number): boolean;
/**
* 计算 Legendre 符号 (a/p)
* 用于判断 a 是否为模 p 的二次剩余
*
* @param a 值
* @param p 奇素数
* @returns 1 如果 a 是二次剩余, -1 如果不是, 0 如果 a ≡ 0 (mod p)
*/
static legendreSymbol(a: bigint, p: bigint): number;
/**
* 获取 BigInt 的字节长度
*
* @param value BigInt 值
* @returns 字节长度
*/
static byteLength(value: bigint): number;
/**
* 设置指定位为1
*
* @param value BigInt 值
* @param n 位索引(从0开始)
* @returns 设置后的值
*/
static setBit(value: bigint, n: number): bigint;
/**
* 清除指定位为0
*
* @param value BigInt 值
* @param n 位索引(从0开始)
* @returns 清除后的值
*/
static clearBit(value: bigint, n: number): bigint;
/**
* 翻转指定位
*
* @param value BigInt 值
* @param n 位索引(从0开始)
* @returns 翻转后的值
*/
static flipBit(value: bigint, n: number): bigint;
/**
* 获取最低的n位
*
* @param value BigInt 值
* @param n 位数
* @returns 最低n位的值
*/
static getLowestBits(value: bigint, n: number): bigint;
}
/**
* Utility functions for integer operations.
* Provides bit manipulation and other integer utilities similar to Java's Integer class.
*/
declare class Integers {
/**
* Returns the number of zero bits preceding the highest-order ("leftmost")
* one-bit in the two's complement binary representation of the specified number.
* Returns 32 if the number is zero.
*
* @param i - the value whose number of leading zero bits to compute
* @returns the number of zero bits preceding the highest-order one-bit (0-32)
*/
static numberOfLeadingZeros(i: number): number;
/**
* Returns the number of one-bits in the two's complement binary representation
* of the specified number.
*
* @param i - the value whose bits to count
* @returns the number of one-bits
*/
static bitCount(i: number): number;
/**
* Returns the value obtained by rotating the two's complement binary representation
* of the specified number left by the specified number of bits.
*
* @param i - the value whose bits to rotate left
* @param distance - the number of bit positions to rotate by
* @returns the value obtained by rotating left
*/
static rotateLeft(i: number, distance: number): number;
/**
* Returns the value obtained by rotating the two's complement binary representation
* of the specified number right by the specified number of bits.
*
* @param i - the value whose bits to rotate right
* @param distance - the number of bit positions to rotate by
* @returns the value obtained by rotating right
*/
static rotateRight(i: number, distance: number): number;
/**
* Returns the number of zero bits following the lowest-order ("rightmost")
* one-bit in the two's complement binary representation of the specified number.
* Returns 32 if the number is zero.
*
* @param i - the value whose number of trailing zero bits to compute
* @returns the number of zero bits following the lowest-order one-bit (0-32)
*/
static numberOfTrailingZeros(i: number): number;
/**
* Returns the highest one bit of the specified number.
*
* @param i - the value whose highest one bit to compute
* @returns the highest one bit, or 0 if i is 0
*/
static highestOneBit(i: number): number;
/**
* Returns the lowest one bit of the specified number.
*
* @param i - the value whose lowest one bit to compute
* @returns the lowest one bit, or 0 if i is 0
*/
static lowestOneBit(i: number): number;
}
/**
* 安全随机数生成器
* 使用 Web Crypto API(浏览器和现代Node.js)
*
* 参考: java.security.SecureRandom
*/
declare class SecureRandom {
/**
* 生成随机字节填充到指定数组
* @param bytes 要填充的字节数组
*/
nextBytes(bytes: Uint8Array): void;
/**
* 生成指定长度的随机字节数组
* @param length 字节数
* @returns 随机字节数组
*/
generateSeed(length: number): Uint8Array;
}
/**
* 支持状态保存和恢复的可记忆对象接口
*
* 参考: org.bouncycastle.util.Memoable
*/
interface Memoable {
/**
* 生成当前对象的独立副本
* @returns 对象的副本
*/
copy(): Memoable;
/**
* 从另一个对象恢复状态
* @param other 要恢复状态的源对象
*/
resetFromMemoable(other: Memoable): void;
}
/**
* 消息摘要算法的基础接口
*
* 参考: org.bouncycastle.crypto.Digest
*/
interface Digest {
/**
* 获取算法名称
* @returns 算法名称
*/
getAlgorithmName(): string;
/**
* 获取摘要输出的字节长度
* @returns 摘要长度(字节)
*/
getDigestSize(): number;
/**
* 更新摘要,添加单个字节
* @param input 输入字节
*/
update(input: number): void;
/**
* 更新摘要,添加字节数组
* @param input 输入字节数组
* @param offset 起始偏移量
* @param length 数据长度
*/
updateArray(input: Uint8Array, offset: number, length: number): void;
/**
* 完成摘要计算,输出结果
* @param out 输出缓冲区
* @param outOffset 输出起始位置
* @returns 写入的字节数
*/
doFinal(out: Uint8Array, outOffset: number): number;
/**
* 重置摘要状态
*/
reset(): void;
}
/**
* 扩展的摘要接口,提供内部状态访问
*
* 参考: org.bouncycastle.crypto.ExtendedDigest
*/
interface ExtendedDigest extends Digest {
/**
* 获取内部块大小(字节)
* @returns 块大小
*/
getByteLength(): number;
}
/**
* 通用摘要算法的抽象基类
* 实现了输入缓冲、消息长度计数等通用逻辑
*
* 参考: org.bouncycastle.crypto.digests.GeneralDigest
*/
declare abstract class GeneralDigest implements ExtendedDigest, Memoable {
private static readonly BYTE_LENGTH;
protected xBuf: Uint8Array;
protected xBufOff: number;
protected byteCount: bigint;
/**
* 构造函数
* @param digest 可选的源摘要对象,用于复制状态
*/
protected constructor(digest?: GeneralDigest);
update(input: number): void;
updateArray(input: Uint8Array, offset: number, length: number): void;
finish(): void;
reset(): void;
getByteLength(): number;
/**
* 从另一个 GeneralDigest 复制状态(用于 Memoable)
*/
protected copyIn(digest: GeneralDigest): void;
/**
* 复制当前对象
*/
abstract copy(): Memoable;
/**
* 从另一个对象恢复状态
*/
abstract resetFromMemoable(other: Memoable): void;
/**
* 获取算法名称
*/
abstract getAlgorithmName(): string;
/**
* 获取摘要长度
*/
abstract getDigestSize(): number;
/**
* 完成摘要计算
*/
abstract doFinal(out: Uint8Array, outOffset: number): number;
/**
* 处理一个字(4字节)
*/
protected abstract processWord(input: Uint8Array, offset: number): void;
/**
* 处理消息长度
*/
protected abstract processLength(bitLength: bigint): void;
/**
* 处理一个完整的块
*/
protected abstract processBlock(): void;
/**
* 重置内部状态
*/
protected abstract resetState(): void;
}
/**
* SM3 密码杂凑算法实现
*
* 标准: GB/T 32905-2016
* 参考: org.bouncycastle.crypto.digests.SM3Digest
*/
declare class SM3Digest extends GeneralDigest {
private static readonly DIGEST_LENGTH;
private static readonly BLOCK_SIZE;
private static readonly IV;
private static readonly T;
private V;
private X;
private xOff;
constructor();
constructor(digest: SM3Digest);
getAlgorithmName(): string;
getDigestSize(): number;
getByteLength(): number;
doFinal(out: Uint8Array, outOffset: number): number;
reset(): void;
reset(other: Memoable): void;
protected resetState(): void;
protected processWord(input: Uint8Array, offset: number): void;
protected processLength(bitLength: bigint): void;
protected processBlock(): void;
private FF0;
private FF1;
private GG0;
private GG1;
private P0;
private P1;
private rotateLeft;
copy(): Memoable;
resetFromMemoable(other: Memoable): void;
private copyInSM3;
}
/**
* Common constants used in elliptic curve cryptography.
*
* Based on: org.bouncycastle.math.ec.ECConstants
*/
declare class ECConstants {
static readonly ZERO = 0n;
static readonly ONE = 1n;
static readonly TWO = 2n;
static readonly THREE = 3n;
static readonly FOUR = 4n;
static readonly EIGHT = 8n;
}
/**
* Abstract base class for finite field elements.
*
* Based on: org.bouncycastle.math.ec.ECFieldElement
*/
/**
* Abstract base class for all field elements.
*/
declare abstract class ECFieldElement {
/**
* Convert the field element to a BigInt.
*/
abstract toBigInteger(): bigint;
/**
* Get the name of the field (e.g., "Fp" for prime field).
*/
abstract getFieldName(): string;
/**
* Get the size of the field in bits.
*/
abstract getFieldSize(): number;
/**
* Add another field element: this + b
*/
abstract add(b: ECFieldElement): ECFieldElement;
/**
* Add one to this element: this + 1
*/
abstract addOne(): ECFieldElement;
/**
* Subtract another field element: this - b
*/
abstract subtract(b: ECFieldElement): ECFieldElement;
/**
* Multiply by another field element: this * b
*/
abstract multiply(b: ECFieldElement): ECFieldElement;
/**
* Divide by another field element: this / b
*/
abstract divide(b: ECFieldElement): ECFieldElement;
/**
* Negate this element: -this
*/
abstract negate(): ECFieldElement;
/**
* Square this element: this^2
*/
abstract square(): ECFieldElement;
/**
* Compute multiplicative inverse: this^(-1)
*/
abstract invert(): ECFieldElement;
/**
* Compute square root if it exists, null otherwise.
*/
abstract sqrt(): ECFieldElement | null;
/**
* Check if this element is zero.
*/
isZero(): boolean;
/**
* Check if this element is one.
*/
isOne(): boolean;
/**
* Test if the lowest bit is 1.
*/
testBitZero(): boolean;
/**
* Encode this field element to bytes.
*
* @returns byte array representation
*/
getEncoded(): Uint8Array;
/**
* Check equality with another field element.
*/
equals(other: ECFieldElement): boolean;
}
/**
* Field element for prime field Fp (integers modulo p).
*/
declare class ECFieldElementFp extends ECFieldElement {
readonly q: bigint;
readonly x: bigint;
constructor(q: bigint, x: bigint);
toBigInteger(): bigint;
getFieldName(): string;
getFieldSize(): number;
/**
* Get the prime modulus.
*/
getQ(): bigint;
add(b: ECFieldElement): ECFieldElement;
addOne(): ECFieldElement;
subtract(b: ECFieldElement): ECFieldElement;
multiply(b: ECFieldElement): ECFieldElement;
/**
* Compute this * b - x * y (optimized).
*/
multiplyMinusProduct(b: ECFieldElement, x: ECFieldElement, y: ECFieldElement): ECFieldElement;
/**
* Compute this * b + x * y (optimized).
*/
multiplyPlusProduct(b: ECFieldElement, x: ECFieldElement, y: ECFieldElement): ECFieldElement;
divide(b: ECFieldElement): ECFieldElement;
negate(): ECFieldElement;
square(): ECFieldElement;
/**
* Compute this^2 - x * y (optimized).
*/
squareMinusProduct(x: ECFieldElement, y: ECFieldElement): ECFieldElement;
/**
* Compute this^2 + x * y (optimized).
*/
squarePlusProduct(x: ECFieldElement, y: ECFieldElement): ECFieldElement;
invert(): ECFieldElement;
/**
* Compute square root using Tonelli-Shanks algorithm.
* Returns null if no square root exists.
*/
sqrt(): ECFieldElement | null;
/**
* Tonelli-Shanks algorithm for computing square root in Fp.
*/
private sqrtTonelliShanks;
/**
* Check if z is a square root of this element.
*/
private checkSqrt;
private modAdd;
private modSubtract;
private modMult;
private modReduce;
private modInverse;
equals(other: any): boolean;
hashCode(): number;
}
/**
* Base interface for precomputation data.
* Precomputation data is stored in ECPoint's preCompTable for caching.
*/
interface PreCompInfo {
}
/**
* Callback interface for lazy precomputation.
*/
interface PreCompCallback {
/**
* Compute or reuse precomputation data.
* @param existing Existing precomputation data (if any)
* @returns New or existing precomputation data
*/
precompute(existing: PreCompInfo | null): PreCompInfo;
}
/**
* Base class for points on elliptic curves.
*
* Based on: org.bouncycastle.math.ec.ECPoint
*/
/**
* Abstract base class for all elliptic curve points.
*/
declare abstract class ECPoint {
protected static readonly EMPTY_ZS: ECFieldElement[];
curve: ECCurve | null;
x: ECFieldElement | null;
y: ECFieldElement | null;
zs: ECFieldElement[];
/**
* Precomputation table for this point (lazy-initialized).
* Maps precomputation name to PreCompInfo.
*/
preCompTable: Map<string, PreCompInfo> | null;
constructor(curve: ECCurve | null, x: ECFieldElement | null, y: ECFieldElement | null, zs?: ECFieldElement[]);
/**
* Get initial z-coordinates based on curve coordinate system.
*/
protected static getInitialZCoords(curve: ECCurve | null): ECFieldElement[];
/**
* Check if this point satisfies the curve equation.
*/
protected abstract satisfiesCurveEquation(): boolean;
/**
* Get the detached point (normalized and detached from curve).
*/
getDetachedPoint(): ECPoint;
/**
* Get the curve.
*/
getCurve(): ECCurve;
/**
* Detach point from curve.
*/
protected abstract detach(): ECPoint;
/**
* Get curve coordinate system.
*/
protected getCurveCoordinateSystem(): CoordinateSystem;
/**
* Get affine x-coordinate (requires normalized point).
*/
getAffineXCoord(): ECFieldElement;
/**
* Get affine y-coordinate (requires normalized point).
*/
getAffineYCoord(): ECFieldElement;
/**
* Get x-coordinate (may be projective).
*/
getXCoord(): ECFieldElement;
/**
* Get y-coordinate (may be projective).
*/
getYCoord(): ECFieldElement;
/**
* Get z-coordinate at index.
*/
getZCoord(index: number): ECFieldElement;
/**
* Get all z-coordinates.
*/
getZCoords(): ECFieldElement[];
/**
* Get raw x-coordinate (without checking).
*/
getRawXCoord(): ECFieldElement | null;
/**
* Get raw y-coordinate (without checking).
*/
getRawYCoord(): ECFieldElement | null;
/**
* Get raw z-coordinates (without checking).
*/
protected getRawZCoords(): ECFieldElement[];
/**
* Check that point is normalized.
*/
protected checkNormalized(): void;
/**
* Check if point is normalized (affine or z=1).
*/
isNormalized(): boolean;
/**
* Normalize point to affine coordinates.
*/
normalize(): ECPoint;
/**
* Normalize with pre-computed z-inverse.
*/
normalizeWithZInv(zInv: ECFieldElement): ECPoint;
/**
* Create scaled point.
*/
protected createScaledPoint(sx: ECFieldElement, sy: ECFieldElement): ECPoint;
/**
* Check if this is the point at infinity.
*/
isInfinity(): boolean;
/**
* Check if point is valid (lies on curve and satisfies order).
*/
isValid(): boolean;
/**
* Get compression Y tilde (for compressed encoding).
*/
protected abstract getCompressionYTilde(): boolean;
/**
* Add another point.
*/
abstract add(b: ECPoint): ECPoint;
/**
* Negate this point.
*/
abstract negate(): ECPoint;
/**
* Subtract another point.
*/
subtract(b: ECPoint): ECPoint;
/**
* Double this point.
*/
abstract twice(): ECPoint;
/**
* Double this point e times.
*/
timesPow2(e: number): ECPoint;
/**
* Compute 2*this + b.
*/
twicePlus(b: ECPoint): ECPoint;
/**
* Compute 3*this.
*/
threeTimes(): ECPoint;
/**
* Multiply by scalar (will use curve's multiplier).
*/
multiply(k: bigint): ECPoint;
/**
* Simple double-and-add multiplication algorithm.
*/
private simpleMultiply;
/**
* Check equality.
*/
equals(other: ECPoint | null): boolean;
/**
* Get hash code.
*/
hashCode(): number;
/**
* Convert to string.
*/
toString(): string;
/**
* Get encoded point.
*/
getEncoded(compressed: boolean): Uint8Array;
}
/**
* Abstract base class for points over prime field Fp.
*/
declare abstract class ECPointAbstractFp extends ECPoint {
constructor(curve: ECCurve | null, x: ECFieldElement | null, y: ECFieldElement | null, zs?: ECFieldElement[]);
protected getCompressionYTilde(): boolean;
protected satisfiesCurveEquation(): boolean;
}
/**
* Elliptic curve point over prime field Fp.
*/
declare class ECPointFp extends ECPointAbstractFp {
constructor(curve: ECCurve | null, x: ECFieldElement | null, y: ECFieldElement | null, zs?: ECFieldElement[]);
protected detach(): ECPoint;
getZCoord(index: number): ECFieldElement;
/**
* Get Jacobian Modified W coordinate.
*/
private getJacobianModifiedW;
/**
* Calculate W coordinate for Jacobian Modified.
* W = a * Z^4 (but simplified to 'a' when Z=1)
*/
private calculateJacobianModifiedW;
add(b: ECPoint): ECPoint;
twice(): ECPoint;
/**
* Doubling in Jacobian Modified coordinates.
*/
private twiceJacobianModified;
negate(): ECPoint;
}
/**
* Abstract interface for EC point lookup tables.
* Used for efficient constant-time point multiplication.
*/
interface ECLookupTable {
/**
* Get the size of the lookup table.
*/
getSize(): number;
/**
* Look up a point by index (constant-time).
* @param index The index to lookup
*/
lookup(index: number): ECPoint;
/**
* Look up a point by index (variable-time, may be faster but not constant-time).
* @param index The index to lookup
*/
lookupVar(index: number): ECPoint;
}
/**
* Base class for elliptic curves.
*
* Based on: org.bouncycastle.math.ec.ECCurve
*/
/**
* Coordinate system constants.
*/
declare enum CoordinateSystem {
AFFINE = 0,
HOMOGENEOUS = 1,
JACOBIAN = 2,
JACOBIAN_CHUDNOVSKY = 3,
JACOBIAN_MODIFIED = 4,
LAMBDA_AFFINE = 5,
LAMBDA_PROJECTIVE = 6,
SKEWED = 7
}
/**
* Abstract base class for all elliptic curves.
*/
declare abstract class ECCurve {
protected a: ECFieldElement;
protected b: ECFieldElement;
protected order: bigint | null;
protected cofactor: bigint | null;
protected coord: CoordinateSystem;
constructor(order?: bigint | null, cofactor?: bigint | null);
/**
* Get the size of the field in bits.
*/
abstract getFieldSize(): number;
/**
* Create a field element from a BigInt.
*/
abstract fromBigInteger(x: bigint): ECFieldElement;
/**
* Check if a value is a valid field element.
*/
abstract isValidFieldElement(x: bigint): boolean;
/**
* Create a random field element.
*/
abstract randomFieldElement(r: SecureRandom): ECFieldElement;
/**
* Create a random non-zero field element (for multiplication).
*/
abstract randomFieldElementMult(r: SecureRandom): ECFieldElement;
/**
* Get the field element encoding length in bytes.
*/
getFieldElementEncodingLength(): number;
/**
* Get the affine point encoding length.
*/
getAffinePointEncodingLength(compressed: boolean): number;
/**
* Create a point and validate it lies on the curve.
*/
validatePoint(x: bigint, y: bigint): ECPoint;
/**
* Create a point on the curve.
*/
abstract createPoint(x: bigint, y: bigint): ECPoint;
/**
* Create a raw point (without validation).
*/
abstract createRawPoint(x: ECFieldElement, y: ECFieldElement): ECPoint;
/**
* Create a raw point with z-coordinates.
*/
abstract createRawPoint(x: ECFieldElement, y: ECFieldElement, zs: ECFieldElement[]): ECPoint;
/**
* Clone this curve.
*/
protected abstract cloneCurve(): ECCurve;
/**
* Check if a coordinate system is supported.
*/
supportsCoordinateSystem(coord: CoordinateSystem): boolean;
/**
* Get the coordinate system.
*/
getCoordinateSystem(): CoordinateSystem;
/**
* Import a point from another curve.
*/
importPoint(p: ECPoint): ECPoint;
/**
* Normalize all points in an array.
*/
normalizeAll(points: ECPoint[]): void;
/**
* Normalize a range of points with optional iso scaling.
*/
normalizeAllWithRange(points: ECPoint[], off: number, len: number, iso: ECFieldElement | null): void;
/**
* Precompute and cache data for a point.
* @param point The point to precompute for
* @param name The name of the precomputation (e.g., "bc_fixed_point")
* @param callback The callback that performs the actual precomputation
* @returns The precomputed data
*/
precompute(point: ECPoint, name: string, callback: PreCompCallback): PreCompInfo;
/**
* Create a cache-safe lookup table from an array of points.
* Points must already be normalized.
* @param points The array of points
* @param off The offset in the array
* @param len The number of points
*/
createCacheSafeLookupTable(points: ECPoint[], off: number, len: number): ECLookupTable;
/**
* Get the point at infinity.
*/
abstract getInfinity(): ECPoint;
/**
* Get the curve parameter a.
*/
getA(): ECFieldElement;
/**
* Get the curve parameter b.
*/
getB(): ECFieldElement;
/**
* Get the order of the curve.
*/
getOrder(): bigint | null;
/**
* Get the cofactor of the curve.
*/
getCofactor(): bigint | null;
/**
* Decode a point from bytes.
*/
abstract decodePoint(encoded: Uint8Array): ECPoint;
/**
* Check a single point.
*/
protected checkPoint(point: ECPoint): void;
/**
* Check an array of points.
*/
protected checkPoints(points: ECPoint[], off?: number, len?: number): void;
/**
* Check equality with another curve.
*/
equals(other: ECCurve): boolean;
/**
* Get hash code.
*/
hashCode(): number;
}
/**
* Abstract base class for curves over prime fields Fp.
*/
declare abstract class ECCurveAbstractFp extends ECCurve {
protected q: bigint;
constructor(q: bigint, order?: bigint | null, cofactor?: bigint | null);
/**
* Get the prime modulus.
*/
getQ(): bigint;
getFieldSize(): number;
isValidFieldElement(x: bigint): boolean;
randomFieldElement(r: SecureRandom): ECFieldElement;
randomFieldElementMult(r: SecureRandom): ECFieldElement;
/**
* Decompress a point from compressed format.
*/
protected decompressPoint(yTilde: number, X1: bigint): ECPoint;
private implRandomFieldElement;
private implRandomFieldElementMult;
}
/**
* Elliptic curve over prime field Fp: y^2 = x^3 + ax + b (mod p)
*/
declare class ECCurveFp extends ECCurveAbstractFp {
private static readonly FP_DEFAULT_COORDS;
private r;
private _infinity;
/**
* Constructor for Fp curve.
*
* @param q - The prime modulus
* @param a - Curve parameter a
* @param b - Curve parameter b
* @param order - Order of the base point (optional)
* @param cofactor - Cofactor (optional)
*/
constructor(q: bigint, a: bigint, b: bigint, order?: bigint | null, cofactor?: bigint | null);
/**
* Lazy getter for infinity point to avoid circular dependency.
*/
private get infinity();
/**
* Setter for infinity point (used in createInternal).
*/
private set infinity(value);
/**
* Internal constructor with pre-computed values.
*/
private static createInternal;
/**
* Calculate residue for Montgomery reduction optimization.
*/
private calculateResidue;
protected cloneCurve(): ECCurve;
supportsCoordinateSystem(coord: CoordinateSystem): boolean;
getQ(): bigint;
getFieldSize(): number;
fromBigInteger(x: bigint): ECFieldElement;
createRawPoint(x: ECFieldElement, y: ECFieldElement, zs?: ECFieldElement[]): ECPoint;
createPoint(x: bigint, y: bigint): ECPoint;
/**
* Import a point, with optimization for Jacobian coordinates.
*/
importPoint(p: ECPoint): ECPoint;
getInfinity(): ECPoint;
/**
* Set the infinity point (called after ECPoint is implemented).
*/
setInfinity(infinity: ECPoint): void;
/**
* Decode a point from byte array.
*
* Format:
* - 0x00: Point at infinity
* - 0x02/0x03: Compressed point (x-coordinate + sign bit)
* - 0x04: Uncompressed point (x-coordinate + y-coordinate)
* - 0x06/0x07: Hybrid format (uncompressed + sign bit)
*/
decodePoint(encoded: Uint8Array): ECPoint;
}
/**
* Point multiplier interfaces and implementations.
*
* Based on: org.bouncycastle.math.ec.ECMultiplier
*/
/**
* Interface for point multiplication algorithms.
*/
interface ECMultiplier {
/**
* Multiply point p by scalar k.
*
* @param p - The point to multiply
* @param k - The scalar multiplier
* @returns k * p
*/
multiply(p: ECPoint, k: bigint): ECPoint;
}
/**
* Abstract base class for EC multipliers.
*/
declare abstract class AbstractECMultiplier implements ECMultiplier {
multiply(p: ECPoint, k: bigint): ECPoint;
/**
* Multiply by positive scalar.
*/
protected abstract multiplyPositive(p: ECPoint, k: bigint): ECPoint;
/**
* Check result validity.
*/
protected checkResult(p: ECPoint): ECPoint;
}
/**
* Fixed-point comb multiplier for efficient multiplication.
* Uses precomputed lookup tables for fast scalar multiplication.
* Based on: org.bouncycastle.math.ec.FixedPointCombMultiplier
*/
declare class FixedPointCombMultiplier extends AbstractECMultiplier {
protected multiplyPositive(p: ECPoint, k: bigint): ECPoint;
}
/**
* Simple double-and-add multiplier (for reference).
*/
declare class SimpleECMultiplier extends AbstractECMultiplier {
protected multiplyPositive(p: ECPoint, k: bigint): ECPoint;
}
/**
* Base interface for cipher parameters.
*
* Based on: org.bouncycastle.crypto.CipherParameters
*/
/**
* Marker interface for all cipher parameters.
*/
interface CipherParameters$1 {
}
/**
* Base class for asymmetric key parameters.
*
* Based on: org.bouncycastle.crypto.params.AsymmetricKeyParameter
*/
declare abstract class AsymmetricKeyParameter implements CipherParameters$1 {
private readonly privateKey;
constructor(privateKey: boolean);
isPrivate(): boolean;
}
/**
* Elliptic curve domain parameters.
*
* Based on: org.bouncycastle.crypto.params.ECDomainParameters
*/
declare class ECDomainParameters {
private readonly curve;
private readonly G;
private readonly n;
private readonly h;
private readonly seed;
constructor(curve: ECCurve, G: ECPoint, n: bigint, h?: bigint, seed?: Uint8Array | null);
getCurve(): ECCurve;
getG(): ECPoint;
getN(): bigint;
getH(): bigint;
getSeed(): Uint8Array | null;
equals(other: any): boolean;
hashCode(): number;
}
/**
* Base class for EC key parameters.
*
* Based on: org.bouncycastle.crypto.params.ECKeyParameters
*/
declare abstract class ECKeyParameters extends AsymmetricKeyParameter {
private readonly parameters;
constructor(privateKey: boolean, parameters: ECDomainParameters);
getParameters(): ECDomainParameters;
}
/**
* EC public key parameters.
*
* Based on: org.bouncycastle.crypto.params.ECPublicKeyParameters
*/
declare class ECPublicKeyParameters extends ECKeyParameters {
private readonly Q;
constructor(Q: ECPoint, parameters: ECDomainParameters);
getQ(): ECPoint;
}
/**
* EC private key parameters.
*
* Based on: org.bouncycastle.crypto.params.ECPrivateKeyParameters
*/
declare class ECPrivateKeyParameters extends ECKeyParameters {
private readonly d;
constructor(d: bigint, parameters: ECDomainParameters);
getD(): bigint;
}
/**
* Wraps cipher parameters with random source.
*
* Based on: org.bouncycastle.crypto.params.ParametersWithRandom
*/
declare class ParametersWithRandom implements CipherParameters$1 {
private readonly parameters;
private readonly random;
constructor(parameters: CipherParameters$1, random?: SecureRandom);
getParameters(): CipherParameters$1;
getRandom(): SecureRandom;
}
/**
* Parameters wrapper that includes a user ID.
*
* This class wraps cipher parameters and associates them with a user ID,
* which is commonly used in SM2 signatures for calculating the Z_A value.
*
* Based on: Bouncy Castle pattern for parameter wrapping
*/
/**
* Cipher parameters with associated user ID.
*/
declare class ParametersWithID implements CipherParameters$1 {
private readonly parameters;
private readonly id;
/**
* Create parameters with user ID.
*
* @param parameters - the underlying cipher parameters
* @param id - user ID bytes
*/
constructor(parameters: CipherParameters$1, id: Uint8Array);
/**
* Get the underlying parameters.
*/
getParameters(): CipherParameters$1;
/**
* Get the user ID.
*/
getID(): Uint8Array;
}
/**
* Key Derivation Function based on SM3.
*
* Based on: org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator
*/
declare class KDF {
private readonly digest;
constructor();
/**
* Derive key material from shared secret.
*
* @param Z - Shared secret (x || y coordinates)
* @param klen - Required key length in bytes
* @returns Derived key material
*/
deriveKey(Z: Uint8Array, klen: number): Uint8Array;
/**
* Check if all bytes are zero (used in decryption).
*/
static isZero(data: Uint8Array): boolean;
}
/**
* SM2 curve and domain parameters.
*
* Based on GM/T 0003-2012 and GMNamedCurves.java
*/
/**
* SM2 elliptic curve parameters (SM2P256V1).
*/
declare class SM2 {
private static readonly p;
private static readonly a;
private static readonly b;
private static readonly n;
private static readonly h;
private static readonly Gx;
private static readonly Gy;
private static domainParams;
/**
* Get SM2 domain parameters.
*/
static getParameters(): ECDomainParameters;
/**
* Get curve.
*/
static getCurve(): ECCurveFp;
/**
* Get base point G.
*/
static getG(): ECPoint;
/**
* Get order n.
*/
static getN(): bigint;
/**
* Get cofactor h.
*/
static getH(): bigint;
/**
* Validate public key point.
*/
static validatePublicKey(Q: ECPoint): boolean;
/**
* Validate private key.
*/
static validatePrivateKey(d: bigint): boolean;
/**
* Generate SM2 key pair.
* @returns Object containing private key (BigInt) and public key coordinates {x, y}
*/
static generateKeyPair(): {
privateKey: bigint;
publicKey: {
x: bigint;
y: bigint;
};
};
/**
* Encrypt plaintext using SM2 public key.
* @param message - Message to encrypt (string or Uint8Array)
* @param publicKey - Public key object with x and y coordinates, or separate x, y coordinates
* @param publicKeyY - Public key Y coordinate (if first parameter is not an object)
* @returns Encrypted ciphertext as Uint8Array
*/
static encrypt(message: string | Uint8Array, publicKey: {
x: bigint;
y: bigint;
} | bigint, publicKeyY?: bigint): Uint8Array;
/**
* Decrypt ciphertext using SM2 private key.
* @param ciphertext - Ciphertext to decrypt
* @param privateKey - Private key
* @returns Decrypted plaintext as Uint8Array
*/
static decrypt(ciphertext: Uint8Array, privateKey: bigint): Uint8Array;
/**
* Sign a message using SM2 private key.
* @param message - Message to sign (string or Uint8Array)
* @param privateKey - Private key for signing
* @returns Signature as Uint8Array
*/
static sign(message: string | Uint8Array, privateKey: bigint): Uint8Array;
/**
* Verify a signature using SM2 public key.
* @param message - Original message (string or Uint8Array)
* @param signature - Signature to verify
* @param publicKey - Public key object with x and y coordinates, or separate x, y coordinates
* @param publicKeyY - Public key Y coordinate (if first parameter is not an object)
* @returns true if signature is valid, false otherwise
*/
static verify(message: string | Uint8Array, signature: Uint8Array, publicKey: {
x: bigint;
y: bigint;
} | bigint, publicKeyY?: bigint): boolean;
}
/**
* SM4 高级 API - 提供便捷的加密/解密接口
*
* SM4 是一个 128 位分组密码算法,使用 128 位密钥
*
* 标准: GB/T 32907-2016
*
* @example
* ```typescript
* // 生成密钥
* const key = SM4.generateKey();
*
* // 加密数据(ECB模式)
* const plaintext = new TextEncoder().encode('Hello, SM4!');
* const ciphertext = SM4.encrypt(plaintext, key);
*
* // 解密数据
* const decrypted = SM4.decrypt(ciphertext, key);
* const message = new TextDecoder().decode(decrypted);
* ```
*/
declare class SM4 {
private static readonly KEY_SIZE;
private static readonly BLOCK_SIZE;
/**
* 生成随机的 SM4 密钥(128位)
*
* @returns 16字节的随机密钥
*/
static generateKey(): Uint8Array;
/**
* 加密数据(ECB模式,PKCS7填充)
*
* 注意:ECB模式不安全,仅用于演示和兼容性测试。
* 生产环境请使用 CBC、CTR 或 GCM 模式。
*
* @param plaintext - 明文数据
* @param key - 128位密钥
* @returns 密文数据(包含填充)
*/
static encrypt(plaintext: Uint8Array, key: Uint8Array): Uint8Array;
/**
* 解密数据(ECB模式,PKCS7填充)
*
* @param ciphertext - 密文数据
* @param key - 128位密钥
* @returns 明文数据(已移除填充)
*/
static decrypt(ciphertext: Uint8Array, key: Uint8Array): Uint8Array;
/**
* 加密单个块(无填充)
*
* 适用于需要直接控制加密过程的场景。
* 输入数据必须正好是 16 字节。
*
* @param block - 16字节的数据块
* @param key - 128位密钥
* @returns 16字节的加密块
*/
static encryptBlock(block: Uint8Array, key: Uint8Array): Uint8Array;
/**
* 解密单个块(无填充)
*
* @param block - 16字节的加密块
* @param key - 128位密钥
* @returns 16字节的明文块
*/
static decryptBlock(block: Uint8Array, key: Uint8Array): Uint8Array;
/**
* PKCS7 填充
*
* @param data - 原始数据
* @param blockSize - 块大小
* @returns 填充后的数据
*/
private static pkcs7Padding;
/**
* 移除 PKCS7 填充
*
* @param data - 填充后的数据
* @returns 原始数据
*/
private static pkcs7Unpadding;
}
/**
* All parameter classes implement this interface.
*
* 参考: org.bouncycastle.crypto.CipherParameters
*/
interface CipherParameters {
}
/**
* Block cipher engines are expected to conform to this interface.
*
* 参考: org.bouncycastle.crypto.BlockCipher
*/
interface BlockCipher {
/**
* Initialize the cipher.
*
* @param forEncryption - if true the cipher is initialized for encryption,
* if false for decryption.
* @param params - the key and other data required by the cipher.
* @throws Error if the params argument is inappropriate.
*/
init(forEncryption: boolean, params: CipherParameters): void;
/**
* Return the name of the algorithm the cipher implements.
*
* @returns the name of the algorithm the cipher implements.
*/
getAlgorithmName(): string;
/**
* Return the block size for this cipher (in bytes).
*
* @returns the block size for this cipher in bytes.
*/
getBlockSize(): number;
/**
* Process one block of input from the array in and write it to
* the out array.
*
* @param input - the array containing the input data.
* @param inOff - offset into the in array the data starts at.
* @param output - the array the output data will be copied into.
* @param outOff - the offset into the out array the output will start at.
* @returns the number of bytes processed and produced.
* @throws DataLengthException if there isn't enough data in input, or
* space in output.
* @throws Error if the cipher isn't initialized.
*/
processBlock(input: Uint8Array, inOff: number, output: Uint8Array, outOff: number): number;
/**
* Reset the cipher. After resetting the cipher is in the same state
* as it was after the last init (if there was one).
*/
reset(): void;
}
/**
* SM4 Block Cipher - SM4 is a 128 bit block cipher with a 128 bit key.
*
* The implementation here is based on the document https://eprint.iacr.org/2008/329.pdf
* by Whitfield Diffie and George Ledin, which is a translation of Prof. LU Shu-wang's original standard.
*
* 标准: GB/T 32907-2016
* 参考: org.bouncycastle.crypto.engines.SM4Engine
*/
declare class SM4Engine implements BlockCipher {
private static readonly BLOCK_SIZE;
private static readonly Sbox;
private static readonly CK;
private static readonly FK;
private readonly X;
private rk;
/**
* Initialize the cipher.
*
* @param forEncryption - true for encryption, false for decryption
* @param params - the key parameter
*/
init(forEncryption: boolean, params: CipherParameters): void;
/**
* Return the algorithm name.
*
* @returns "SM4"
*/
getAlgorithmName(): string;
/**
* Return the block size (16 bytes).
*
* @returns 16
*/
getBlockSize(): number;
/**
* Process one block of data.
*
* @param input - input data
* @param inOff - offset in input
* @param output - output buffer
* @param outOff - offset in output
* @returns number of bytes processed (16)
*/
processBlock(input: Uint8Array, inOff: number, output: Uint8Array, outOff: number): number;
/**
* Reset the cipher.
*/
reset(): void;
/**
* 循环左移
*
* @param x - 要移位的值
* @param bits - 移位位数
* @returns 移位后的值
*/
private rotateLeft;
/**
* 非线性变换 τ (tau)
* S盒替换
*
* @param A - 输入值
* @returns 变换后的值
*/
private tau;
/**
* 线性变换 L' (用于密钥扩展)
*
* @param B - 输入值
* @returns 变换后的值
*/
private L_ap;
/**
* 合成置换 T' (用于密钥扩展)
* T'(Z) = L'(τ(Z))
*
* @param Z - 输入值
* @returns 变换后的值
*/
private T_ap;
/**
* 密钥扩展算法
*
* @param forEncryption - true for encryption, false for decryption
* @param key - 128位密钥
* @returns 32个轮密钥
*/
private expandKey;
/**
* 线性变换 L (用于加密轮函数)
*
* @param B - 输入值
* @returns 变换后的值
*/
private L;
/**
* 合成置换 T (用于加密轮函数)
* T(Z) = L(τ(Z))
*
* @param Z - 输入值
* @returns 变换后的值
*/
private T;
/**
* 轮函数 F0
*
* @param X - 状态数组
* @param rk - 轮密钥
* @returns 新的 X[0]
*/
private F0;
/**
* 轮函数 F1
*
* @param X - 状态数组
* @param rk - 轮密钥
* @returns 新的 X[1]
*/
private F1;
/**
* 轮函数 F2
*
* @param X - 状态数组
* @param rk - 轮密钥
* @returns 新的 X[2]
*/
private F2;
/**
* 轮函数 F3
*
* @param X - 状态数组
* @param rk - 轮密钥
* @returns 新的 X[3]
*/
private F3;
}
/**
* KeyParameter class for holding a symmetric key.
*
* 参考: org.bouncycastle.crypto.params.KeyParameter
*/
declare class KeyParameter implements CipherParameters {
private readonly key;
/**
* Create a KeyParameter from a byte array.
*
* @param key - the key data
*/
constructor(key: Uint8Array);
/**
* Return the key data.
*
* @returns the key bytes
*/
getKey(): Uint8Array;
}
/**
* Cipher parameters with an initialization vector.
*
* 参考: org.bouncycastle.crypto.params.ParametersWithIV
*/
declare class ParametersWithIV implements CipherParameters {
private readonly parameters;
private readonly iv;
/**
* Create parameters with IV.
*
* @param parameters - the underlying parameters
* @param iv - the initialization vector
*/
constructor(parameters: CipherParameters, iv: Uint8Array);
/**
* Get the initialization vector.
*
* @returns the IV
*/
getIV(): Uint8Array;
/**
* Get the underlying parameters.
*
* @returns the parameters
*/
getParameters(): CipherParameters;
}
/**
* Parameters for AEAD (Authenticated Encryption with Associated Data) modes.
* Used with modes like GCM that provide both encryption and authentication.
*
* @see BouncyCastle AEADParameters.java
*/
declare class AEADParameters implements CipherParameters {
private key;
private nonce;
private macSize;
private associatedText;
/**
* Create AEAD parameters.
*
* @param key - The cipher key
* @param macSize - The MAC/tag size in bits (must be multiple of 8)
* @param nonce - The nonce/IV
* @param associatedText - Optional additional authenticated data (AAD)
*/
constructor(key: KeyParameter, macSize: number, nonce: Uint8Array, associatedText?: Uint8Array | null);
/**
* Get the cipher key.
*/
getKey(): KeyParameter;
/**
* Get the MAC size in bits.
*/
getMacSize(): number;
/**
* Get the nonce/IV.
*/
getNonce(): Uint8Array;
/**
* Get the associated text (additional authenticated data).
*/
getAssociatedText(): Uint8Array | null;
}
/**
* ECB (Electronic Codebook) 模式实现
*
* 警告:ECB 模式不安全,不应在生产环境中使用。
* 相同的明文块总是加密为相同的密文块,这会泄露信息模式。
*
* 此实现仅用于:
* - 与旧系统的兼容性
* - 测试和教学目的
*
* 参考: org.bouncycastle.crypto.modes.ECBBlockCipher
*/
declare class ECBBlockCipher implements BlockCipher {
private cipher;
private blockSize;
constructor(cipher: BlockCipher);
/**
* 返回底层密码
*/
getUnderlyingCipher(): BlockCipher;
/**
* 初始化密码
*
* @param encrypting - true 表示加密,false 表示解密
* @param params - 密码参数
*/
init(encrypting: boolean, params: CipherParameters$1): void;
/**
* 返回算法名称
*/
getAlgorithmName(): string;
/**
* 返回块大小(字节)
*/
getBlockSize(): number;
/**
* 处理一个数据块
*
* @param input - 输入数据
* @param inOff - 输入偏移量
* @param output - 输出缓冲区
* @param outOff - 输出偏移量
* @returns 处理的字节数
*/
processBlock(input: Uint8Array, inOff: number, output: Uint8Array, outOff: number): number;
/**
* 重置密码到初始状态
*/
reset(): void;
}
/**
* Cipher Block Chaining (CBC) mode.
*
* 参考: org.bouncycastle.crypto.modes.CBCBlockCipher
*/
declare class CBCBlockCipher implements BlockCipher {
private readonly cipher;
private readonly blockSize;
private IV;
private cbcV;
private cbcNextV;
private encrypting;
/**
* Basic constructor.
*
* @param cipher - the block cipher to be used as the basis of chaining
*/
constructor(cipher: BlockCipher);
/**
* Return the underlying block cipher that we are wrapping.
*
* @returns the underlying block cipher
*/
getUnderlyingCipher(): BlockCipher;
/**
* Initialize the cipher and, possibly, the initialization vector (IV).
* If an IV isn't passed as part of the parameter, the IV will be all zeros.
*
* @param forEncryption - true for encryption, false for decryption
* @param params - the key and other data required by the cipher
*/
init(forEncryption: boolean, params: CipherParameters): void;
/**
* Return the algorithm name and mode.
*
* @returns the name of the underlying algorithm followed by "/CBC"
*/
getAlgorithmName(): string;
/**
* Return the block size of the underlying cipher.
*
* @returns the block size
*/
getBlockSize(): number;
/**
* Process one block of input from the array in and write it to the out array.
*
* @param input - the array containing the input data
* @param inOff - offset into the in array the data starts at
* @param output - the array the output data will be copied into
* @param outOff - the offset into the out array the output will start at
* @returns the number of bytes processed and produced
*/
processBlock(input: Uint8Array, inOff: number, output: Uint8Array, outOff: number): number;
/**
* Reset the chaining vector back to the IV and reset the underlying cipher.
*/
reset(): void;
/**
* Do the appropriate chaining step for CBC mode encryption.
*
* @param input - the array containing the data to be encrypted
* @param inOff - offset into the in array the data starts at
* @param output - the array the encrypted data will be copied into
* @param outOff - the offset into the out array the output will start at
* @returns the number of bytes processed and produced
*/
private encryptBlock;
/**
* Do the appropriate chaining step for CBC mode decryption.
*
* @param input - the array containing the data to be decrypted
* @param inOff - offset into the in array the data starts at
* @param output - the array the decrypted data will be copied into
* @param outOff - the offset into the out array the output will start at
* @returns the number of bytes processed and produced
*/
private decryptBlock;
}
/**
* Segmented Integer Counter (SIC) mode, also known as CTR mode.
*
* 参考: org.bouncycastle.crypto.modes.SICBlockCipher
*/
declare class SICBlockCipher implements BlockCipher {
private readonly cipher;
private re