From e7b099f828eb7eea6f9e745de7e92cc4403d31a8 Mon Sep 17 00:00:00 2001 From: yangzhen <3104844212@qq.com> Date: Tue, 17 Dec 2024 12:18:35 +0800 Subject: [PATCH 1/2] 11 --- node_modules/depd/index.js | 272 ++++++++++++++++++++++++---------- node_modules/destroy/index.js | 151 ++++++++++--------- 2 files changed, 275 insertions(+), 148 deletions(-) diff --git a/node_modules/depd/index.js b/node_modules/depd/index.js index 97c7fc3..f206647 100644 --- a/node_modules/depd/index.js +++ b/node_modules/depd/index.js @@ -365,137 +365,249 @@ function getStack() { * Capture call site stack from v8. */ -function prepareObjectStackTrace (obj, stack) { - return stack +/** + * 准备堆栈跟踪,返回传入的堆栈。 + * @param {Object} obj - 捕获堆栈的对象。 + * @param {Array} stack - 堆栈数组。 + * @returns {Array} - 返回原始堆栈数组。 + */ +function prepareObjectStackTrace(obj, stack) { + return stack; // 直接返回传入的堆栈数组 } /** - * Return a wrapped function in a deprecation message. + * 返回一个包装的函数,并添加弃用消息。 + * @param {Function} fn - 要包装的函数。 + * @param {string} message - 弃用消息。 + * @returns {Function} - 包装后的函数。 */ - -function wrapfunction (fn, message) { +function wrapfunction(fn, message) { + // 检查传入的参数是否为函数 if (typeof fn !== 'function') { - throw new TypeError('argument fn must be a function') + throw new TypeError('argument fn must be a function'); // 如果不是,抛出类型错误 } - var args = createArgumentsString(fn.length) - var stack = getStack() - var site = callSiteLocation(stack[1]) + var args = createArgumentsString(fn.length); // 创建函数参数字符串 + var stack = getStack(); // 获取当前堆栈 + var site = callSiteLocation(stack[1]); // 获取调用位置 - site.name = fn.name + site.name = fn.name; // 设置调用位置的名称为函数名 + // 使用新函数创建一个包装函数 // eslint-disable-next-line no-new-func var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site', - '"use strict"\n' + - 'return function (' + args + ') {' + - 'log.call(deprecate, message, site)\n' + - 'return fn.apply(this, arguments)\n' + - '}')(fn, log, this, message, site) + '"use strict"\n' + + 'return function (' + args + ') {' + + 'log.call(deprecate, message, site)\n' + // 调用日志记录弃用消息 + 'return fn.apply(this, arguments)\n' + // 调用原始函数并传递参数 + '}')(fn, log, this, message, site); // 立即调用新函数并传入参数 - return deprecatedfn + return deprecatedfn; // 返回包装后的函数 } /** - * Wrap property in a deprecation message. + * 在属性上添加弃用消息的包装。 + * @param {Object} obj - 拥有属性的对象。 + * @param {string} prop - 属性名称。 + * @param {string} message - 弃用消息。 */ - -function wrapproperty (obj, prop, message) { +function wrapproperty(obj, prop, message) { + // 检查传入的对象是否有效 if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { - throw new TypeError('argument obj must be object') + throw new TypeError('argument obj must be object'); // 如果无效,抛出类型错误 } - var descriptor = Object.getOwnPropertyDescriptor(obj, prop) + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); // 获取属性描述符 + // 检查属性是否存在 if (!descriptor) { - throw new TypeError('must call property on owner object') + throw new TypeError('must call property on owner object'); // 如果不存在,抛出类型错误 } + // 检查属性是否可配置 if (!descriptor.configurable) { - throw new TypeError('property must be configurable') + throw new TypeError('property must be configurable'); // 如果不可配置,抛出类型错误 } - var deprecate = this - var stack = getStack() - var site = callSiteLocation(stack[1]) + var deprecate = this; // 保存当前上下文 + var stack = getStack(); // 获取当前堆栈 + var site = callSiteLocation(stack[1]); // 获取调用位置 - // set site name - site.name = prop + // 设置调用位置的名称为属性名称 + site.name = prop; - // convert data descriptor + // 如果是数据描述符,则转换为访问器描述符 if ('value' in descriptor) { - descriptor = convertDataDescriptorToAccessor(obj, prop, message) + descriptor = convertDataDescriptorToAccessor(obj, prop, message); } - var get = descriptor.get - var set = descriptor.set + var get = descriptor.get; // 获取 getter + var set = descriptor.set; // 获取 setter - // wrap getter + // 包装 getter if (typeof get === 'function') { - descriptor.get = function getter () { - log.call(deprecate, message, site) - return get.apply(this, arguments) - } + descriptor.get = function getter() { + log.call(deprecate, message, site); // 调用日志记录弃用消息 + return get.apply(this, arguments); // 调用原始 getter + }; } - // wrap setter + // 包装 setter if (typeof set === 'function') { - descriptor.set = function setter () { - log.call(deprecate, message, site) - return set.apply(this, arguments) - } + descriptor.set = function setter() { + log.call(deprecate, message, site); // 调用日志记录弃用消息 + return set.apply(this, arguments); // 调用原始 setter + }; } - Object.defineProperty(obj, prop, descriptor) + // 重新定义属性,应用新的描述符 + Object.defineProperty(obj, prop, descriptor); } /** - * Create DeprecationError for deprecation + * 创建一个弃用错误对象。 + * @param {string} namespace - 命名空间。 + * @param {string} message - 弃用消息。 + * @param {Array} stack - 堆栈数组。 */ +function DeprecationError(namespace, message, stack) { + var error = new Error(); // 创建一个新的错误对象 + var stackString; -function DeprecationError (namespace, message, stack) { - var error = new Error() - var stackString - + // 定义构造函数属性 Object.defineProperty(error, 'constructor', { - value: DeprecationError - }) + value: DeprecationError, + }); + // 定义消息属性 Object.defineProperty(error, 'message', { configurable: true, enumerable: false, - value: message, - writable: true - }) + value: message, // 设置错误消息 + writable: true, + }); +} - Object.defineProperty(error, 'name', { - enumerable: false, - configurable: true, - value: 'DeprecationError', - writable: true - }) - Object.defineProperty(error, 'namespace', { - configurable: true, - enumerable: false, - value: namespace, - writable: true - }) +/** + * 准备堆栈跟踪,返回传入的堆栈。 + * @param {Object} obj - 捕获堆栈的对象。 + * @param {Array} stack - 堆栈数组。 + * @returns {Array} - 返回原始堆栈数组。 + */ +function prepareObjectStackTrace(obj, stack) { + return stack; // 直接返回传入的堆栈数组 +} - Object.defineProperty(error, 'stack', { +/** + * 返回一个包装的函数,并添加弃用消息。 + * @param {Function} fn - 要包装的函数。 + * @param {string} message - 弃用消息。 + * @returns {Function} - 包装后的函数。 + */ +function wrapfunction(fn, message) { + // 检查传入的参数是否为函数 + if (typeof fn !== 'function') { + throw new TypeError('argument fn must be a function'); // 如果不是,抛出类型错误 + } + + var args = createArgumentsString(fn.length); // 创建函数参数字符串 + var stack = getStack(); // 获取当前堆栈 + var site = callSiteLocation(stack[1]); // 获取调用位置 + + site.name = fn.name; // 设置调用位置的名称为函数名 + + // 使用新函数创建一个包装函数 + // eslint-disable-next-line no-new-func + var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site', + '"use strict"\n' + + 'return function (' + args + ') {' + + 'log.call(deprecate, message, site)\n' + // 调用日志记录弃用消息 + 'return fn.apply(this, arguments)\n' + // 调用原始函数并传递参数 + '}')(fn, log, this, message, site); // 立即调用新函数并传入参数 + + return deprecatedfn; // 返回包装后的函数 +} + +/** + * 在属性上添加弃用消息的包装。 + * @param {Object} obj - 拥有属性的对象。 + * @param {string} prop - 属性名称。 + * @param {string} message - 弃用消息。 + */ +function wrapproperty(obj, prop, message) { + // 检查传入的对象是否有效 + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { + throw new TypeError('argument obj must be object'); // 如果无效,抛出类型错误 + } + + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); // 获取属性描述符 + + // 检查属性是否存在 + if (!descriptor) { + throw new TypeError('must call property on owner object'); // 如果不存在,抛出类型错误 + } + + // 检查属性是否可配置 + if (!descriptor.configurable) { + throw new TypeError('property must be configurable'); // 如果不可配置,抛出类型错误 + } + + var deprecate = this; // 保存当前上下文 + var stack = getStack(); // 获取当前堆栈 + var site = callSiteLocation(stack[1]); // 获取调用位置 + + // 设置调用位置的名称为属性名称 + site.name = prop; + + // 如果是数据描述符,则转换为访问器描述符 + if ('value' in descriptor) { + descriptor = convertDataDescriptorToAccessor(obj, prop, message); + } + + var get = descriptor.get; // 获取 getter + var set = descriptor.set; // 获取 setter + + // 包装 getter + if (typeof get === 'function') { + descriptor.get = function getter() { + log.call(deprecate, message, site); // 调用日志记录弃用消息 + return get.apply(this, arguments); // 调用原始 getter + }; + } + + // 包装 setter + if (typeof set === 'function') { + descriptor.set = function setter() { + log.call(deprecate, message, site); // 调用日志记录弃用消息 + return set.apply(this, arguments); // 调用原始 setter + }; + } + + // 重新定义属性,应用新的描述符 + Object.defineProperty(obj, prop, descriptor); +} + +/** + * 创建一个弃用错误对象。 + * @param {string} namespace - 命名空间。 + * @param {string} message - 弃用消息。 + * @param {Array} stack - 堆栈数组。 + */ +function DeprecationError(namespace, message, stack) { + var error = new Error(); // 创建一个新的错误对象 + var stackString; + + // 定义构造函数属性 + Object.defineProperty(error, 'constructor', { + value: DeprecationError, + }); + + // 定义消息属性 + Object.defineProperty(error, 'message', { configurable: true, enumerable: false, - get: function () { - if (stackString !== undefined) { - return stackString - } - - // prepare stack trace - return (stackString = createStackString.call(this, stack)) - }, - set: function setter (val) { - stackString = val - } - }) - - return error + value: message, // 设置错误消息 + writable: true, + }); } diff --git a/node_modules/destroy/index.js b/node_modules/destroy/index.js index 7fd5c09..2a4579d 100644 --- a/node_modules/destroy/index.js +++ b/node_modules/destroy/index.js @@ -5,88 +5,93 @@ * MIT Licensed */ -'use strict' +'use strict'; // 启用严格模式 /** - * Module dependencies. + * 模块依赖项。 * @private */ -var EventEmitter = require('events').EventEmitter -var ReadStream = require('fs').ReadStream -var Stream = require('stream') -var Zlib = require('zlib') +var EventEmitter = require('events').EventEmitter; // 引入 EventEmitter 类 +var ReadStream = require('fs').ReadStream; // 引入文件读取流 +var Stream = require('stream'); // 引入流模块 +var Zlib = require('zlib'); // 引入 zlib 模块,用于压缩和解压缩流 /** - * Module exports. + * 模块导出。 * @public */ -module.exports = destroy +module.exports = destroy; // 导出 destroy 函数 /** - * Destroy the given stream, and optionally suppress any future `error` events. + * 销毁给定的流,并可选择抑制未来的 `error` 事件。 * - * @param {object} stream - * @param {boolean} suppress + * @param {object} stream - 要销毁的流对象。 + * @param {boolean} suppress - 是否抑制错误事件。 * @public */ -function destroy (stream, suppress) { +function destroy(stream, suppress) { + // 判断流的类型并调用相应的销毁函数 if (isFsReadStream(stream)) { - destroyReadStream(stream) + destroyReadStream(stream); // 如果是文件读取流,调用销毁文件读取流的函数 } else if (isZlibStream(stream)) { - destroyZlibStream(stream) + destroyZlibStream(stream); // 如果是 zlib 流,调用销毁 zlib 流的函数 } else if (hasDestroy(stream)) { - stream.destroy() + stream.destroy(); // 如果流具有 destroy 方法,则直接调用它 } + // 如果流是事件发射器并且 suppress 为 true,移除所有错误事件监听器 if (isEventEmitter(stream) && suppress) { - stream.removeAllListeners('error') - stream.addListener('error', noop) + stream.removeAllListeners('error'); // 移除所有 'error' 事件监听器 + stream.addListener('error', noop); // 添加一个空的错误处理函数 } - return stream + return stream; // 返回被销毁的流 } /** - * Destroy a ReadStream. + * 销毁 ReadStream。 * - * @param {object} stream + * @param {object} stream - 要销毁的 ReadStream 对象。 * @private */ -function destroyReadStream (stream) { - stream.destroy() +function destroyReadStream(stream) { + stream.destroy(); // 调用流的 destroy 方法 + // 如果流具有 close 方法,添加 'open' 事件的监听器 if (typeof stream.close === 'function') { - // node.js core bug work-around - stream.on('open', onOpenClose) + // node.js 核心 bug 的解决方法 + stream.on('open', onOpenClose); // 在流打开时调用 onOpenClose 函数 } } /** - * Close a Zlib stream. + * 关闭 Zlib 流。 * - * Zlib streams below Node.js 4.5.5 have a buggy implementation - * of .close() when zlib encountered an error. + * Zlib 流在 Node.js 4.5.5 之前的实现中, + * 当 zlib 遇到错误时,.close() 方法存在bug。 * - * @param {object} stream + * @param {object} stream - 要关闭的 Zlib 流对象。 * @private */ -function closeZlibStream (stream) { +function closeZlibStream(stream) { + // 如果流有错误,处理流的关闭 if (stream._hadError === true) { var prop = stream._binding === null - ? '_binding' - : '_handle' + ? '_binding' // 选择属性 + : '_handle'; + // 创建一个关闭函数,将属性设置为 null stream[prop] = { - close: function () { this[prop] = null } - } + close: function () { this[prop] = null; } + }; } - stream.close() + stream.close(); // 调用流的 close 方法 } /** @@ -105,78 +110,88 @@ function closeZlibStream (stream) { * @private */ -function destroyZlibStream (stream) { +/** + * 销毁 Zlib 流。 + * + * @param {object} stream - 要销毁的 Zlib 流对象。 + */ + +function destroyZlibStream(stream) { + // 检查流是否具有 destroy 方法 if (typeof stream.destroy === 'function') { - // node.js core bug work-around + // node.js 核心 bug 的解决方法 // istanbul ignore if: node.js 0.8 if (stream._binding) { - // node.js < 0.10.0 - stream.destroy() + // 处理 Node.js 版本小于 0.10.0 的情况 + stream.destroy(); // 调用流的 destroy 方法 + + // 如果流正在处理数据 if (stream._processing) { - stream._needDrain = true - stream.once('drain', onDrainClearBinding) + stream._needDrain = true; // 标记需要排空 + stream.once('drain', onDrainClearBinding); // 一旦排空,调用 onDrainClearBinding 函数 } else { - stream._binding.clear() + stream._binding.clear(); // 清除绑定 } } else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) { - // node.js >= 12, ^11.1.0, ^10.15.1 - stream.destroy() + // 处理 Node.js 版本大于等于 12,或 11.1.0,或 10.15.1 的情况 + stream.destroy(); // 调用流的 destroy 方法 } else if (stream._destroy && typeof stream.close === 'function') { - // node.js 7, 8 - stream.destroyed = true - stream.close() + // 处理 Node.js 版本为 7 或 8 的情况 + stream.destroyed = true; // 标记流为已销毁 + stream.close(); // 调用流的 close 方法 } else { - // fallback + // 备用方案 // istanbul ignore next - stream.destroy() + stream.destroy(); // 调用流的 destroy 方法 } } else if (typeof stream.close === 'function') { - // node.js < 8 fallback - closeZlibStream(stream) + // 处理 Node.js 版本小于 8 的备用方案 + closeZlibStream(stream); // 调用关闭 zlib 流的函数 } } /** - * Determine if stream has destroy. + * 确定流是否具有 destroy 方法。 * @private */ -function hasDestroy (stream) { - return stream instanceof Stream && - typeof stream.destroy === 'function' +function hasDestroy(stream) { + return stream instanceof Stream && // 检查流是否是 Stream 的实例 + typeof stream.destroy === 'function'; // 检查流是否具有 destroy 方法 } /** - * Determine if val is EventEmitter. + * 确定 val 是否是 EventEmitter。 * @private */ -function isEventEmitter (val) { - return val instanceof EventEmitter +function isEventEmitter(val) { + return val instanceof EventEmitter; // 检查 val 是否是 EventEmitter 的实例 } /** - * Determine if stream is fs.ReadStream stream. + * 确定流是否是 fs.ReadStream 流。 * @private */ -function isFsReadStream (stream) { - return stream instanceof ReadStream +function isFsReadStream(stream) { + return stream instanceof ReadStream; // 检查流是否是 ReadStream 的实例 } /** - * Determine if stream is Zlib stream. + * 确定流是否是 Zlib 流。 * @private */ -function isZlibStream (stream) { +function isZlibStream(stream) { + // 检查流是否是 Zlib 的不同类型的实例 return stream instanceof Zlib.Gzip || - stream instanceof Zlib.Gunzip || - stream instanceof Zlib.Deflate || - stream instanceof Zlib.DeflateRaw || - stream instanceof Zlib.Inflate || - stream instanceof Zlib.InflateRaw || - stream instanceof Zlib.Unzip + stream instanceof Zlib.Gunzip || + stream instanceof Zlib.Deflate || + stream instanceof Zlib.DeflateRaw || + stream instanceof Zlib.Inflate || + stream instanceof Zlib.InflateRaw || + stream instanceof Zlib.Unzip; } /** -- 2.34.1 From d29f773de9d0d5829fa26627caee11d01463d227 Mon Sep 17 00:00:00 2001 From: yangzhen <3104844212@qq.com> Date: Tue, 17 Dec 2024 12:39:00 +0800 Subject: [PATCH 2/2] 11 --- node_modules/destroy/index.js | 82 +++- node_modules/dom-walk/index.js | 39 +- node_modules/ecc-jsbn/index.js | 95 ++-- node_modules/ee-first/index.js | 78 +-- .../elliptic/lib/elliptic/curve/base.js | 459 ++++++++++-------- node_modules/elliptic/lib/elliptic/curves.js | 52 +- node_modules/elliptic/lib/elliptic/utils.js | 63 ++- 7 files changed, 538 insertions(+), 330 deletions(-) diff --git a/node_modules/destroy/index.js b/node_modules/destroy/index.js index 2a4579d..15bed82 100644 --- a/node_modules/destroy/index.js +++ b/node_modules/destroy/index.js @@ -199,26 +199,86 @@ function isZlibStream(stream) { * @private */ -function noop () {} +/** + * 销毁 Zlib 流。 + * + * @param {object} stream - 要销毁的 Zlib 流对象。 + */ + +function destroyZlibStream(stream) { + // 检查流是否具有 destroy 方法 + if (typeof stream.destroy === 'function') { + // node.js 核心 bug 的解决方法 + // istanbul ignore if: node.js 0.8 + if (stream._binding) { + // 处理 Node.js 版本小于 0.10.0 的情况 + stream.destroy(); // 调用流的 destroy 方法 + + // 如果流正在处理数据 + if (stream._processing) { + stream._needDrain = true; // 标记需要排空 + stream.once('drain', onDrainClearBinding); // 一旦排空,调用 onDrainClearBinding 函数 + } else { + stream._binding.clear(); // 清除绑定 + } + } else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) { + // 处理 Node.js 版本大于等于 12,或 11.1.0,或 10.15.1 的情况 + stream.destroy(); // 调用流的 destroy 方法 + } else if (stream._destroy && typeof stream.close === 'function') { + // 处理 Node.js 版本为 7 或 8 的情况 + stream.destroyed = true; // 标记流为已销毁 + stream.close(); // 调用流的 close 方法 + } else { + // 备用方案 + // istanbul ignore next + stream.destroy(); // 调用流的 destroy 方法 + } + } else if (typeof stream.close === 'function') { + // 处理 Node.js 版本小于 8 的备用方案 + closeZlibStream(stream); // 调用关闭 zlib 流的函数 + } +} /** - * On drain handler to clear binding. + * 确定流是否具有 destroy 方法。 * @private */ -// istanbul ignore next: node.js 0.8 -function onDrainClearBinding () { - this._binding.clear() +function hasDestroy(stream) { + return stream instanceof Stream && // 检查流是否是 Stream 的实例 + typeof stream.destroy === 'function'; // 检查流是否具有 destroy 方法 } /** - * On open handler to close stream. + * 确定 val 是否是 EventEmitter。 * @private */ -function onOpenClose () { - if (typeof this.fd === 'number') { - // actually close down the fd - this.close() - } +function isEventEmitter(val) { + return val instanceof EventEmitter; // 检查 val 是否是 EventEmitter 的实例 +} + +/** + * 确定流是否是 fs.ReadStream 流。 + * @private + */ + +function isFsReadStream(stream) { + return stream instanceof ReadStream; // 检查流是否是 ReadStream 的实例 +} + +/** + * 确定流是否是 Zlib 流。 + * @private + */ + +function isZlibStream(stream) { + // 检查流是否是 Zlib 的不同类型的实例 + return stream instanceof Zlib.Gzip || + stream instanceof Zlib.Gunzip || + stream instanceof Zlib.Deflate || + stream instanceof Zlib.DeflateRaw || + stream instanceof Zlib.Inflate || + stream instanceof Zlib.InflateRaw || + stream instanceof Zlib.Unzip; } diff --git a/node_modules/dom-walk/index.js b/node_modules/dom-walk/index.js index 9c2402d..229df65 100644 --- a/node_modules/dom-walk/index.js +++ b/node_modules/dom-walk/index.js @@ -1,24 +1,29 @@ -var slice = Array.prototype.slice +/** + * 空函数,通常用于占位或作为默认回调。 + * @private + */ -module.exports = iterativelyWalk +function noop() {} -function iterativelyWalk(nodes, cb) { - if (!('length' in nodes)) { - nodes = [nodes] - } - - nodes = slice.call(nodes) +/** + * 排空处理程序,用于清除绑定。 + * @private + */ - while(nodes.length) { - var node = nodes.shift(), - ret = cb(node) +// istanbul ignore next: node.js 0.8 +function onDrainClearBinding() { + this._binding.clear(); // 调用绑定的清除方法 +} - if (ret) { - return ret - } +/** + * 打开处理程序,用于关闭流。 + * @private + */ - if (node.childNodes && node.childNodes.length) { - nodes = slice.call(node.childNodes).concat(nodes) - } +function onOpenClose() { + // 检查文件描述符 (fd) 是否为数字 + if (typeof this.fd === 'number') { + // 实际关闭文件描述符 + this.close(); // 调用流的 close 方法 } } diff --git a/node_modules/ecc-jsbn/index.js b/node_modules/ecc-jsbn/index.js index fb19a1d..a124e17 100644 --- a/node_modules/ecc-jsbn/index.js +++ b/node_modules/ecc-jsbn/index.js @@ -1,58 +1,61 @@ -var crypto = require("crypto"); -var BigInteger = require("jsbn").BigInteger; -var ECPointFp = require("./lib/ec.js").ECPointFp; -var Buffer = require("safer-buffer").Buffer; -exports.ECCurves = require("./lib/sec.js"); +// 引入所需的模块 +var crypto = require("crypto"); // 用于加密和随机数生成 +var BigInteger = require("jsbn").BigInteger; // 大整数库 +var ECPointFp = require("./lib/ec.js").ECPointFp; // 引入椭圆曲线点类 +var Buffer = require("safer-buffer").Buffer; // 安全的 Buffer 实现 +exports.ECCurves = require("./lib/sec.js"); // 导出椭圆曲线库 -// zero prepad -function unstupid(hex,len) -{ - return (hex.length >= len) ? hex : unstupid("0"+hex,len); +// 零填充函数 +function unstupid(hex, len) { + // 如果 hex 长度大于或等于 len,返回 hex;否则递归调用自身,前面加一个 "0" + return (hex.length >= len) ? hex : unstupid("0" + hex, len); } -exports.ECKey = function(curve, key, isPublic) -{ - var priv; - var c = curve(); - var n = c.getN(); - var bytes = Math.floor(n.bitLength()/8); +// 导出 ECKey 构造函数 +exports.ECKey = function(curve, key, isPublic) { + var priv; // 私钥 + var c = curve(); // 获取曲线 + var n = c.getN(); // 获取曲线的阶 + var bytes = Math.floor(n.bitLength() / 8); // 计算字节数 - if(key) - { - if(isPublic) - { + // 如果提供了密钥 + if (key) { + if (isPublic) { var curve = c.getCurve(); -// var x = key.slice(1,bytes+1); // skip the 04 for uncompressed format -// var y = key.slice(bytes+1); -// this.P = new ECPointFp(curve, -// curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), -// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); + // 解码公钥 this.P = curve.decodePointHex(key.toString("hex")); - }else{ - if(key.length != bytes) return false; - priv = new BigInteger(key.toString("hex"), 16); + } else { + // 如果密钥长度不等于字节数,则返回 false + if (key.length != bytes) return false; + // 将密钥转换为大整数 + priv = new BigInteger(key.toString("hex"), 16); } - }else{ - var n1 = n.subtract(BigInteger.ONE); - var r = new BigInteger(crypto.randomBytes(n.bitLength())); - priv = r.mod(n1).add(BigInteger.ONE); - this.P = c.getG().multiply(priv); + } else { + // 生成随机私钥 + var n1 = n.subtract(BigInteger.ONE); // n - 1 + var r = new BigInteger(crypto.randomBytes(n.bitLength())); // 生成随机数 + priv = r.mod(n1).add(BigInteger.ONE); // 确保私钥在 [1, n-1] 范围内 + this.P = c.getG().multiply(priv); // 计算公钥 P = G * priv } - if(this.P) - { -// var pubhex = unstupid(this.P.getX().toBigInteger().toString(16),bytes*2)+unstupid(this.P.getY().toBigInteger().toString(16),bytes*2); -// this.PublicKey = Buffer.from("04"+pubhex,"hex"); - this.PublicKey = Buffer.from(c.getCurve().encodeCompressedPointHex(this.P),"hex"); + + // 如果公钥 P 存在 + if (this.P) { + // 将公钥编码为压缩格式并转换为 Buffer + this.PublicKey = Buffer.from(c.getCurve().encodeCompressedPointHex(this.P), "hex"); } - if(priv) - { - this.PrivateKey = Buffer.from(unstupid(priv.toString(16),bytes*2),"hex"); - this.deriveSharedSecret = function(key) - { - if(!key || !key.P) return false; + + // 如果私钥存在 + if (priv) { + // 将私钥转换为 Buffer + this.PrivateKey = Buffer.from(unstupid(priv.toString(16), bytes * 2), "hex"); + // 定义派生共享密钥的方法 + this.deriveSharedSecret = function(key) { + // 检查传入的密钥是否有效 + if (!key || !key.P) return false; + // 计算共享密钥 S = key.P * priv var S = key.P.multiply(priv); - return Buffer.from(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); - } + // 返回共享密钥的 X 坐标,转换为 Buffer + return Buffer.from(unstupid(S.getX().toBigInteger().toString(16), bytes * 2), "hex"); + } } } - diff --git a/node_modules/ee-first/index.js b/node_modules/ee-first/index.js index 501287c..b45e3be 100644 --- a/node_modules/ee-first/index.js +++ b/node_modules/ee-first/index.js @@ -4,92 +4,94 @@ * MIT Licensed */ -'use strict' +'use strict'; // 使用严格模式 /** - * Module exports. + * 模块导出 * @public */ - -module.exports = first +module.exports = first; /** - * Get the first event in a set of event emitters and event pairs. + * 获取一组事件发射器和事件对中的第一个事件。 * - * @param {array} stuff - * @param {function} done + * @param {array} stuff - 包含事件发射器和事件的数组 + * @param {function} done - 当事件触发时调用的回调函数 * @public */ - function first(stuff, done) { + // 检查 stuff 是否为数组 if (!Array.isArray(stuff)) - throw new TypeError('arg must be an array of [ee, events...] arrays') + throw new TypeError('arg must be an array of [ee, events...] arrays'); - var cleanups = [] + var cleanups = []; // 用于存储清理函数的数组 + // 遍历传入的 stuff 数组 for (var i = 0; i < stuff.length; i++) { - var arr = stuff[i] + var arr = stuff[i]; + // 检查每个元素是否为数组,且长度至少为 2 if (!Array.isArray(arr) || arr.length < 2) - throw new TypeError('each array member must be [ee, events...]') + throw new TypeError('each array member must be [ee, events...]'); - var ee = arr[0] + var ee = arr[0]; // 获取事件发射器 + // 遍历事件数组 for (var j = 1; j < arr.length; j++) { - var event = arr[j] - var fn = listener(event, callback) + var event = arr[j]; + var fn = listener(event, callback); // 创建事件监听器 - // listen to the event - ee.on(event, fn) - // push this listener to the list of cleanups + // 监听事件 + ee.on(event, fn); + // 将此监听器推入清理列表 cleanups.push({ ee: ee, event: event, fn: fn, - }) + }); } } + // 事件触发时的回调函数 function callback() { - cleanup() - done.apply(null, arguments) + cleanup(); // 清理所有监听器 + done.apply(null, arguments); // 调用传入的 done 函数 } + // 清理函数,移除所有监听器 function cleanup() { - var x + var x; for (var i = 0; i < cleanups.length; i++) { - x = cleanups[i] - x.ee.removeListener(x.event, x.fn) + x = cleanups[i]; + x.ee.removeListener(x.event, x.fn); // 移除监听器 } } + // 返回一个 thunk 函数 function thunk(fn) { - done = fn + done = fn; // 更新 done 函数 } - thunk.cancel = cleanup + thunk.cancel = cleanup; // 将清理函数附加到 thunk 上 - return thunk + return thunk; // 返回 thunk 函数 } /** - * Create the event listener. + * 创建事件监听器。 * @private */ - function listener(event, done) { return function onevent(arg1) { - var args = new Array(arguments.length) - var ee = this - var err = event === 'error' - ? arg1 - : null + var args = new Array(arguments.length); // 创建一个新数组来存储参数 + var ee = this; // 获取事件发射器的上下文 + var err = event === 'error' ? arg1 : null; // 如果是 'error' 事件,设置错误参数 - // copy args to prevent arguments escaping scope + // 复制参数以防止 arguments 逃逸作用域 for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] + args[i] = arguments[i]; } - done(err, ee, event, args) - } + done(err, ee, event, args); // 调用 done 函数,传入错误、事件发射器、事件和参数 + }; } diff --git a/node_modules/elliptic/lib/elliptic/curve/base.js b/node_modules/elliptic/lib/elliptic/curve/base.js index 8543fa8..63dda22 100644 --- a/node_modules/elliptic/lib/elliptic/curve/base.js +++ b/node_modules/elliptic/lib/elliptic/curve/base.js @@ -1,36 +1,52 @@ 'use strict'; +// 引入 `bn.js` 库,用于处理大整数相关操作 var BN = require('bn.js'); +// 引入自定义的 `utils` 模块,其中包含了一些工具函数 var utils = require('../utils'); +// 从 `utils` 模块中获取 `getNAF` 函数,用于将整数转换为某种非相邻形式(Non-Adjacent Form,NAF)表示 var getNAF = utils.getNAF; +// 从 `utils` 模块中获取 `getJSF` 函数,其功能可能与特定的数学表示形式转换相关(从函数名推测可能是联合稀疏形式相关操作) var getJSF = utils.getJSF; +// 从 `utils` 模块中获取 `assert` 函数,通常用于进行条件判断并在不满足条件时抛出异常 var assert = utils.assert; +// `BaseCurve` 构造函数,用于创建曲线相关的基础对象,不同类型的曲线可能继承自这个基础类来扩展各自的特性 function BaseCurve(type, conf) { + // 记录曲线的类型 this.type = type; + // 将配置中以十六进制字符串表示的素数 `p` 转换为 `BN` 类型的大整数,并存储起来,这个 `p` 可能与曲线所在的有限域相关 this.p = new BN(conf.p, 16); - // Use Montgomery, when there is no fast reduction for the prime - this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p); + // 判断配置中是否有 `prime` 属性,如果有则使用 `BN.red` 方法进行某种与素数相关的初始化(可能是蒙哥马利(Montgomery)相关设置), + // 如果没有则针对当前曲线的素数 `p` 使用 `BN.mont` 方法进行蒙哥马利初始化,`red` 可能用于后续的快速模运算等操作 + this.red = conf.prime? BN.red(conf.prime) : BN.mont(this.p); - // Useful for many curves + // 创建表示数字 0 的蒙哥马利形式,存储在 `this.zero` 中,方便后续在蒙哥马利域下进行运算时使用 this.zero = new BN(0).toRed(this.red); + // 创建表示数字 1 的蒙哥马利形式,存储在 `this.one` 中,同样用于蒙哥马利域运算 this.one = new BN(1).toRed(this.red); + // 创建表示数字 2 的蒙哥马利形式,存储在 `this.two` 中 this.two = new BN(2).toRed(this.red); - // Curve configuration, optional + // 如果配置中有 `n` 属性(可能表示曲线的阶数),则将其转换为 `BN` 类型的大整数并存储,否则 `this.n` 为 `undefined` this.n = conf.n && new BN(conf.n, 16); + // 如果配置中有 `g` 属性(可能表示曲线的基点,生成元),则调用 `pointFromJSON` 方法(此方法需在子类中实现,这里是抽象的调用)将其转换为相应的点对象并存储, + // 同时根据 `gRed` 属性进行相关设置(具体取决于 `pointFromJSON` 方法的实现),如果没有 `g` 属性则 `this.g` 为 `undefined` this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); - // Temporary arrays + // 创建一些临时数组,用于后续计算过程中的临时数据存储,数组长度都初始化为 4,具体用途会在相关计算方法中体现 this._wnafT1 = new Array(4); this._wnafT2 = new Array(4); this._wnafT3 = new Array(4); this._wnafT4 = new Array(4); - this._bitLength = this.n ? this.n.bitLength() : 0; + // 如果 `this.n` 存在(即曲线阶数已定义),则获取其位数并存储在 `this._bitLength` 中,否则 `this._bitLength` 为 0 + this._bitLength = this.n? this.n.bitLength() : 0; - // Generalized Greg Maxwell's trick + // 进行广义的 Greg Maxwell's trick 相关操作(一种优化技巧,可能与曲线运算性能相关) + // 计算 `this.p` 除以 `this.n` 的结果,如果不存在 `this.n` 或者除法结果大于 100,则将 `this.redN` 设置为 `null`, + // 否则设置 `this._maxwellTrick` 为 `true`,并将 `this.n` 转换为蒙哥马利形式存储在 `this.redN` 中 var adjustCount = this.n && this.p.div(this.n); if (!adjustCount || adjustCount.cmpn(100) > 0) { this.redN = null; @@ -39,25 +55,35 @@ function BaseCurve(type, conf) { this.redN = this.n.toRed(this.red); } } +// 将 `BaseCurve` 函数暴露出去,方便其他模块使用这个基础曲线类 module.exports = BaseCurve; +// 在 `BaseCurve` 的原型上定义 `point` 方法,此方法在 `BaseCurve` 类中是抽象的,需要在子类中具体实现, +// 这里直接抛出一个错误表示未实现,调用者应该在子类中重写这个方法来返回相应的曲线点对象 BaseCurve.prototype.point = function point() { throw new Error('Not implemented'); }; +// 在 `BaseCurve` 的原型上定义 `validate` 方法,同样是抽象方法,用于验证曲线相关的一些条件是否满足, +// 在子类中需要重写这个方法来实现具体的验证逻辑,这里直接抛出错误表示未实现 BaseCurve.prototype.validate = function validate() { throw new Error('Not implemented'); }; +// `_fixedNafMul` 方法,用于基于固定宽度的非相邻形式(NAF)进行乘法相关运算(可能是点乘之类的操作,具体取决于上下文和 `p`、`k` 的含义) BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { + // 断言 `p` 对象有 `precomputed` 属性(可能表示 `p` 相关的预计算数据已准备好,具体取决于对象结构和应用场景),如果不满足则抛出异常 assert(p.precomputed); + // 获取 `p` 对象的 `_getDoubles` 方法返回的结果,这个方法应该返回与双倍相关的数据(比如预计算的双倍点等信息,具体取决于实现) var doubles = p._getDoubles(); + // 使用 `getNAF` 函数将整数 `k` 转换为宽度为 1 的非相邻形式表示,传入曲线的位数 `this._bitLength` 用于控制相关计算范围等 var naf = getNAF(k, 1, this._bitLength); - var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); + // 计算一个与双倍相关的参数 `I`,具体计算逻辑根据给定的表达式,可能与双倍点的步长等信息有关,用于后续的计算转换 + var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0? 2 : 1); I /= 3; - // Translate into more windowed form + // 将 `naf` 表示转换为更适合窗口形式的表示形式,存储在 `repr` 数组中,具体转换逻辑通过循环遍历 `naf` 并按一定规则合并位来实现 var repr = []; var j; var nafW; @@ -68,89 +94,111 @@ BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { repr.push(nafW); } + // 创建两个曲线点对象 `a` 和 `b`,初始化为 `null`(这里的 `jpoint` 方法应该是创建特定类型曲线点的方法,具体功能取决于实现) var a = this.jpoint(null, null, null); var b = this.jpoint(null, null, null); + // 外层循环,根据 `I` 的值进行迭代,可能与计算次数等相关 for (var i = I; i > 0; i--) { + // 内层循环,遍历 `repr` 数组中的每个元素(即窗口化后的 `naf` 表示形式) for (j = 0; j < repr.length; j++) { nafW = repr[j]; + // 如果当前元素等于 `i`,则调用 `b` 的 `mixedAdd` 方法(可能是混合加法操作,具体取决于曲线点对象的实现)将对应的双倍点加到 `b` 上 if (nafW === i) b = b.mixedAdd(doubles.points[j]); + // 如果当前元素等于 `-i`,则调用 `b` 的 `mixedAdd` 方法将对应的双倍点的相反数加到 `b` 上 else if (nafW === -i) b = b.mixedAdd(doubles.points[j].neg()); } + // 将 `b` 的结果累加到 `a` 上,通过调用 `a` 的 `add` 方法(点加法操作) a = a.add(b); } + // 根据 `p` 的类型,如果是 `affine` 类型(仿射坐标类型,一种表示曲线点的方式),则调用 `toP` 方法(可能是转换为某种特定格式的点表示)将 `a` 转换后返回,否则直接返回 `a` return a.toP(); }; +// `_wnafMul` 方法,用于基于窗口宽度为 4 的非相邻形式(w-NAF)进行乘法相关运算(同样可能是点乘操作等) BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { + // 设置窗口宽度为 4,这个宽度会影响后续非相邻形式的计算和相关预计算等操作 var w = 4; - // Precompute window + // 调用 `p` 对象的 `_getNAFPoints` 方法(应该是获取与非相邻形式相关的预计算点信息),传入窗口宽度 `w`,获取预计算的点相关信息并存储在 `nafPoints` 中, + // 同时更新 `w` 为实际获取到的窗口宽度(可能在 `_getNAFPoints` 方法中根据实际情况进行了调整),获取预计算的点数组存储在 `wnd` 中 var nafPoints = p._getNAFPoints(w); w = nafPoints.wnd; var wnd = nafPoints.points; - // Get NAF form + // 使用 `getNAF` 函数将整数 `k` 转换为宽度为 `w` 的非相邻形式表示,传入曲线的位数 `this._bitLength` 用于控制相关计算范围等 var naf = getNAF(k, w, this._bitLength); - // Add `this`*(N+1) for every w-NAF index + // 创建一个曲线点对象 `acc`,初始化为 `null`(同样通过 `jpoint` 方法创建,具体功能取决于实现),用于累加计算结果 var acc = this.jpoint(null, null, null); + // 从 `naf` 数组的末尾开始向前遍历(反向遍历,可能与计算顺序相关) for (var i = naf.length - 1; i >= 0; i--) { - // Count zeroes + // 统计连续的 0 的个数,通过循环递减 `i` 直到遇到非 0 值或者 `i` 小于 0 for (var l = 0; i >= 0 && naf[i] === 0; i--) l++; if (i >= 0) l++; + // 根据连续 0 的个数对 `acc` 进行双倍操作(`dblp` 方法可能是点的双倍运算,具体取决于曲线点对象的实现) acc = acc.dblp(l); if (i < 0) break; var z = naf[i]; - assert(z !== 0); + // 断言 `z` 不为 0,如果为 0 则抛出异常(这里可能是基于算法逻辑要求非相邻形式表示中不应出现连续多个 0 的情况等) + assert(z!== 0); if (p.type === 'affine') { - // J +- P + // 如果 `p` 的类型是 `affine`(仿射坐标类型),根据 `z` 的正负情况,调用 `acc` 的 `mixedAdd` 方法将对应的预计算点或其相反数加到 `acc` 上(`J +- P` 表示的可能是某种点加法逻辑) if (z > 0) acc = acc.mixedAdd(wnd[(z - 1) >> 1]); else acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); } else { - // J +- J + // 如果 `p` 不是 `affine` 类型,同样根据 `z` 的正负情况,调用 `acc` 的 `add` 方法将对应的预计算点或其相反数加到 `acc` 上(`J +- J` 表示的可能是另一种点加法逻辑) if (z > 0) acc = acc.add(wnd[(z - 1) >> 1]); else acc = acc.add(wnd[(-z - 1) >> 1].neg()); } } - return p.type === 'affine' ? acc.toP() : acc; + // 根据 `p` 的类型,如果是 `affine` 类型则调用 `toP` 方法将 `acc` 转换后返回,否则直接返回 `acc` + return p.type === 'affine'? acc.toP() : acc; }; +// `_wnafMulAdd` 方法,用于基于窗口非相邻形式(w-NAF)进行乘法和加法相关的混合运算,传入了多个参数用于控制计算过程 BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, - points, - coeffs, - len, - jacobianResult) { + points, + coeffs, + len, + jacobianResult) { + // 获取临时数组 `this._wnafT1`,用于存储窗口宽度相关信息(从变量名推测),可能在后续计算中用于记录每个点对应的窗口宽度等 var wndWidth = this._wnafT1; + // 获取临时数组 `this._wnafT2`,用于存储预计算的点相关信息(同样从变量名推测),可能是每个点对应的窗口非相邻形式的预计算点数组等 var wnd = this._wnafT2; + // 获取临时数组 `this._wnafT3`,用于存储非相邻形式(NAF)表示的数据(推测),可能是每个系数对应的非相邻形式表示等 var naf = this._wnafT3; - // Fill all arrays + // 初始化一个变量 `max` 为 0,用于记录后续计算中出现的最大长度(可能是 NAF 表示的长度等) var max = 0; var i; var j; var p; + // 循环遍历传入的点数组 `points`,填充相关的临时数组 `wndWidth` 和 `wnd` for (i = 0; i < len; i++) { p = points[i]; + // 调用每个点 `p` 的 `_getNAFPoints` 方法(获取与非相邻形式相关的预计算点信息),传入默认窗口宽度 `defW`,获取并存储窗口宽度和预计算点信息到相应的临时数组中 var nafPoints = p._getNAFPoints(defW); wndWidth[i] = nafPoints.wnd; wnd[i] = nafPoints.points; } - // Comb small window NAFs + // 从后往前每隔 2 个元素进行循环(可能是对相邻的点和系数进行组合操作,具体取决于算法逻辑),用于组合小窗口的非相邻形式(NAF)表示 for (i = len - 1; i >= 1; i -= 2) { var a = i - 1; var b = i; - if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { + // 如果两个相邻点对应的窗口宽度不为 1,则分别调用 `getNAF` 函数将对应的系数转换为非相邻形式表示, + // 并更新 `max` 为当前两个非相邻形式表示长度中的最大值,然后继续下一轮循环 + if (wndWidth[a]!== 1 || wndWidth[b]!== 1) { naf[a] = getNAF(coeffs[a], wndWidth[a], this._bitLength); naf[b] = getNAF(coeffs[b], wndWidth[b], this._bitLength); max = Math.max(naf[a].length, max); @@ -158,6 +206,8 @@ BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, continue; } + // 创建一个包含 4 个元素的数组 `comb`,用于存储一些点的组合情况,初始值部分设置为 `points[a]` 和 `null`, + // 具体含义和后续用途取决于下面的条件判断和赋值逻辑,这里可能是在尝试通过点的组合来优化计算等 var comb = [ points[a], /* 1 */ null, /* 3 */ @@ -165,18 +215,9 @@ BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, points[b], /* 7 */ ]; - // Try to avoid Projective points, if possible - if (points[a].y.cmp(points[b].y) === 0) { - comb[1] = points[a].add(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].add(points[b].neg()); - } else { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } - + // 尝试避免使用射影坐标(Projective points,一种曲线点的表示方式),根据两个点的 `y` 坐标的比较情况进行不同的点组合操作, + // 如果两个点的 `y` 坐标相等,则进行特定的点加法操作并赋值给 `comb` 数组中的相应位置, + // 如果两个点的 `y` 坐标互为相反数(通过 `redNeg` 方法判断,可能是蒙哥马利域下的取相反数操作),则进行另 var index = [ -3, /* -1 -1 */ -1, /* -1 0 */ @@ -189,193 +230,229 @@ BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, 3, /* 1 1 */ ]; - var jsf = getJSF(coeffs[a], coeffs[b]); - max = Math.max(jsf[0].length, max); - naf[a] = new Array(max); - naf[b] = new Array(max); + // 从给定的系数中获取 JSF(Jacobian Scalar Form) + var jsf = getJSF(coeffs[a], coeffs[b]); // 获取系数 a 和 b 的 Jacobian 标量形式 + max = Math.max(jsf[0].length, max); // 更新最大长度 + naf[a] = new Array(max); // 为 naf 数组的 a 分配最大长度 + naf[b] = new Array(max); // 为 naf 数组的 b 分配最大长度 + +// 遍历最大长度 for (j = 0; j < max; j++) { - var ja = jsf[0][j] | 0; - var jb = jsf[1][j] | 0; + var ja = jsf[0][j] | 0; // 获取 jsf 的第一个部分的值并转为整数 + var jb = jsf[1][j] | 0; // 获取 jsf 的第二个部分的值并转为整数 - naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; - naf[b][j] = 0; - wnd[a] = comb; + // 根据 ja 和 jb 的值更新 naf 数组 + naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; // 使用 index 数组计算 naf[a][j] + naf[b][j] = 0; // 将 naf[b][j] 设置为 0 + wnd[a] = comb; // 将 wnd[a] 设置为 comb(组合预计算值) } - } - var acc = this.jpoint(null, null, null); - var tmp = this._wnafT4; - for (i = max; i >= 0; i--) { - var k = 0; +// 初始化一个新的 Jacobian 点 + var acc = this.jpoint(null, null, null); // 创建一个新的 Jacobian 点 + var tmp = this._wnafT4; // 获取临时数组,用于存储 WNAF(宽度非负数表示法)值 + +// 从最大长度开始逆向迭代 + for (i = max; i >= 0; i--) { + var k = 0; // 初始化 k,用于记录零的数量 + + // 检查当前索引 i 的 WNAF 值 + while (i >= 0) { + var zero = true; // 假设当前为零 + for (j = 0; j < len; j++) { + tmp[j] = naf[j][i] | 0; // 将 naf[j][i] 的值存入临时数组并转为整数 + if (tmp[j] !== 0) // 如果值不为零 + zero = false; // 标记为非零 + } + if (!zero) // 如果有非零值 + break; // 退出循环 + k++; // 计数零的数量 + i--; // 减少 i 值 + } + if (i >= 0) // 如果 i 仍然有效 + k++; // 增加 k + + acc = acc.dblp(k); // 对累加器进行 k 次双倍操作 + if (i < 0) // 如果 i 小于 0,退出循环 + break; - while (i >= 0) { - var zero = true; + // 遍历所有的 len for (j = 0; j < len; j++) { - tmp[j] = naf[j][i] | 0; - if (tmp[j] !== 0) - zero = false; + var z = tmp[j]; // 获取临时数组的当前值 + p; // 声明变量 p + if (z === 0) // 如果 z 为零 + continue; // 跳过 + else if (z > 0) // 如果 z 为正 + p = wnd[j][(z - 1) >> 1]; // 获取正值的预计算点 + else if (z < 0) // 如果 z 为负 + p = wnd[j][(-z - 1) >> 1].neg(); // 获取负值的预计算点并取反 + + // 根据 p 的类型选择不同的加法方式 + if (p.type === 'affine') // 如果 p 是仿射点 + acc = acc.mixedAdd(p); // 使用混合加法 + else // 如果 p 是 Jacobian 点 + acc = acc.add(p); // 使用普通加法 } - if (!zero) - break; - k++; - i--; } - if (i >= 0) - k++; - acc = acc.dblp(k); - if (i < 0) - break; - for (j = 0; j < len; j++) { - var z = tmp[j]; - p; - if (z === 0) - continue; - else if (z > 0) - p = wnd[j][(z - 1) >> 1]; - else if (z < 0) - p = wnd[j][(-z - 1) >> 1].neg(); - - if (p.type === 'affine') - acc = acc.mixedAdd(p); - else - acc = acc.add(p); - } - } - // Zeroify references - for (i = 0; i < len; i++) - wnd[i] = null; - - if (jacobianResult) - return acc; - else - return acc.toP(); -}; +// 清理引用,将 wnd 数组的每个元素设置为 null + for (i = 0; i < len; i++) + wnd[i] = null; // 清除 wnd 数组中的引用 -function BasePoint(curve, type) { - this.curve = curve; - this.type = type; - this.precomputed = null; -} -BaseCurve.BasePoint = BasePoint; +// 根据 jacobianResult 的值决定返回值 + if (jacobianResult) + return acc; // 如果需要 Jacobian 结果,则返回 acc + else + return acc.toP(); // 否则返回转换为仿射坐标的 acc + }; -BasePoint.prototype.eq = function eq(/*other*/) { - throw new Error('Not implemented'); -}; +// 定义 BasePoint 构造函数 + function BasePoint(curve, type) { + this.curve = curve; // 保存曲线对象 + this.type = type; // 保存类型 + this.precomputed = null; // 初始化预计算值为 null + } -BasePoint.prototype.validate = function validate() { - return this.curve.validate(this); -}; + // 将 BasePoint 赋值给 BaseCurve 的 BasePoint 属性 + BaseCurve.BasePoint = BasePoint; -BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { - bytes = utils.toArray(bytes, enc); +// 定义点的相等性比较方法,当前未实现 + BasePoint.prototype.eq = function eq(/*other*/) { + throw new Error('Not implemented'); // 抛出未实现的错误 + }; - var len = this.p.byteLength(); +// 验证当前点是否在曲线上 + BasePoint.prototype.validate = function validate() { + return this.curve.validate(this); // 调用曲线的验证方法 + }; - // uncompressed, hybrid-odd, hybrid-even - if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && - bytes.length - 1 === 2 * len) { - if (bytes[0] === 0x06) - assert(bytes[bytes.length - 1] % 2 === 0); - else if (bytes[0] === 0x07) - assert(bytes[bytes.length - 1] % 2 === 1); +// 解码点的字节表示 + BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { + // 将字节转换为数组 + bytes = utils.toArray(bytes, enc); + + var len = this.p.byteLength(); // 获取曲线的参数长度 + + // 处理未压缩、混合奇偶形式的点 + if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && + bytes.length - 1 === 2 * len) { + if (bytes[0] === 0x06) + assert(bytes[bytes.length - 1] % 2 === 0); // 校验最后一个字节为偶数 + else if (bytes[0] === 0x07) + assert(bytes[bytes.length - 1] % 2 === 1); // 校验最后一个字节为奇数 + + // 创建点对象并返回 + var res = this.point(bytes.slice(1, 1 + len), + bytes.slice(1 + len, 1 + 2 * len)); + + return res; // 返回解码后的点 + } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && + bytes.length - 1 === len) { + // 处理压缩形式的点 + return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); + } + throw new Error('Unknown point format'); // 抛出未知格式的错误 + }; - var res = this.point(bytes.slice(1, 1 + len), - bytes.slice(1 + len, 1 + 2 * len)); +// 压缩编码点 + BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { + return this.encode(enc, true); // 调用 encode 方法,设置为压缩格式 + }; - return res; - } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && - bytes.length - 1 === len) { - return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); - } - throw new Error('Unknown point format'); -}; +// 编码点为字节数组 + BasePoint.prototype._encode = function _encode(compact) { + var len = this.curve.p.byteLength(); // 获取曲线参数长度 + var x = this.getX().toArray('be', len); // 获取 x 坐标并转换为字节数组 -BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { - return this.encode(enc, true); -}; + if (compact) + return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); // 返回压缩格式 -BasePoint.prototype._encode = function _encode(compact) { - var len = this.curve.p.byteLength(); - var x = this.getX().toArray('be', len); + return [ 0x04 ].concat(x, this.getY().toArray('be', len)); // 返回未压缩格式 + }; - if (compact) - return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); +// 编码点为指定格式 + BasePoint.prototype.encode = function encode(enc, compact) { + return utils.encode(this._encode(compact), enc); // 调用 utils.encode 进行编码 + }; - return [ 0x04 ].concat(x, this.getY().toArray('be', len)); -}; +// 预计算点的倍数 + BasePoint.prototype.precompute = function precompute(power) { + if (this.precomputed) + return this; // 如果已经预计算,直接返回 + + var precomputed = { + doubles: null, // 存储倍点 + naf: null, // 存储 NAF 点 + beta: null, // 存储 beta + }; + precomputed.naf = this._getNAFPoints(8); // 获取 NAF 点 + precomputed.doubles = this._getDoubles(4, power); // 获取倍点 + precomputed.beta = this._getBeta(); // 获取 beta + this.precomputed = precomputed; // 存储预计算结果 + + return this; // 返回当前点 + }; -BasePoint.prototype.encode = function encode(enc, compact) { - return utils.encode(this._encode(compact), enc); -}; +// 检查是否有足够的倍点 + BasePoint.prototype._hasDoubles = function _hasDoubles(k) { + if (!this.precomputed) + return false; // 如果没有预计算,返回 false -BasePoint.prototype.precompute = function precompute(power) { - if (this.precomputed) - return this; + var doubles = this.precomputed.doubles; // 获取倍点 + if (!doubles) + return false; // 如果没有倍点,返回 false - var precomputed = { - doubles: null, - naf: null, - beta: null, + // 检查倍点数量是否足够 + return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); }; - precomputed.naf = this._getNAFPoints(8); - precomputed.doubles = this._getDoubles(4, power); - precomputed.beta = this._getBeta(); - this.precomputed = precomputed; - return this; -}; +// 获取倍点的函数 + BasePoint.prototype._getDoubles = function _getDoubles(step, power) { + if (this.precomputed && this.precomputed.doubles) + return this.precomputed.doubles; // 如果已经预计算,直接返回 + + var doubles = [ this ]; // 初始化倍点数组 + var acc = this; // 记录当前点 + for (var i = 0; i < power; i += step) { + for (var j = 0; j < step; j++) + acc = acc.dbl(); // 计算倍点 + doubles.push(acc); // 添加倍点到数组 + } + return { + step: step, + points: doubles, // 返回倍点和步长 + }; + }; -BasePoint.prototype._hasDoubles = function _hasDoubles(k) { - if (!this.precomputed) - return false; - var doubles = this.precomputed.doubles; - if (!doubles) - return false; +// 获取 NAF 点的函数 + BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { + // 如果已经预计算过 NAF 点,直接返回 + if (this.precomputed && this.precomputed.naf) + return this.precomputed.naf; - return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); -}; + var res = [ this ]; // 初始化结果数组,包含当前点 + var max = (1 << wnd) - 1; // 计算最大值,wnd 为窗口大小 + var dbl = max === 1 ? null : this.dbl(); // 如果最大值为 1,则不需要计算倍点 -BasePoint.prototype._getDoubles = function _getDoubles(step, power) { - if (this.precomputed && this.precomputed.doubles) - return this.precomputed.doubles; + // 生成 NAF 点 + for (var i = 1; i < max; i++) + res[i] = res[i - 1].add(dbl); // 当前点加上倍点,得到下一个点 - var doubles = [ this ]; - var acc = this; - for (var i = 0; i < power; i += step) { - for (var j = 0; j < step; j++) - acc = acc.dbl(); - doubles.push(acc); - } - return { - step: step, - points: doubles, + return { + wnd: wnd, // 返回窗口大小 + points: res, // 返回 NAF 点数组 + }; }; -}; -BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { - if (this.precomputed && this.precomputed.naf) - return this.precomputed.naf; - - var res = [ this ]; - var max = (1 << wnd) - 1; - var dbl = max === 1 ? null : this.dbl(); - for (var i = 1; i < max; i++) - res[i] = res[i - 1].add(dbl); - return { - wnd: wnd, - points: res, +// 获取 beta 值的函数,当前未实现 + BasePoint.prototype._getBeta = function _getBeta() { + return null; // 返回 null,表示未实现 }; -}; - -BasePoint.prototype._getBeta = function _getBeta() { - return null; -}; -BasePoint.prototype.dblp = function dblp(k) { - var r = this; - for (var i = 0; i < k; i++) - r = r.dbl(); - return r; -}; +// 点的倍增操作,倍增 k 次 + BasePoint.prototype.dblp = function dblp(k) { + var r = this; // 初始化结果为当前点 + for (var i = 0; i < k; i++) + r = r.dbl(); // 重复倍增操作 + return r; // 返回 k 倍的点 + }; diff --git a/node_modules/elliptic/lib/elliptic/curves.js b/node_modules/elliptic/lib/elliptic/curves.js index 6c36e03..5d25d1b 100644 --- a/node_modules/elliptic/lib/elliptic/curves.js +++ b/node_modules/elliptic/lib/elliptic/curves.js @@ -1,14 +1,19 @@ 'use strict'; +// 导出的对象 var curves = exports; +// 引入所需的模块 var hash = require('hash.js'); var curve = require('./curve'); var utils = require('./utils'); +// 引入断言函数 var assert = utils.assert; +// PresetCurve 构造函数 function PresetCurve(options) { + // 根据 options 的类型创建不同类型的曲线对象 if (options.type === 'short') this.curve = new curve.short(options); else if (options.type === 'edwards') @@ -19,16 +24,20 @@ function PresetCurve(options) { this.n = this.curve.n; this.hash = options.hash; + // 进行曲线的有效性断言 assert(this.g.validate(), 'Invalid curve'); - assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); + assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N!= O'); } +// 将 PresetCurve 函数添加到 curves 对象中 curves.PresetCurve = PresetCurve; +// 定义曲线的函数 function defineCurve(name, options) { Object.defineProperty(curves, name, { configurable: true, enumerable: true, get: function() { + // 创建 PresetCurve 实例 var curve = new PresetCurve(options); Object.defineProperty(curves, name, { configurable: true, @@ -40,6 +49,7 @@ function defineCurve(name, options) { }); } +// 定义 p192 曲线 defineCurve('p192', { type: 'short', prime: 'p192', @@ -55,11 +65,12 @@ defineCurve('p192', { ], }); +// 定义 p224 曲线 defineCurve('p224', { type: 'short', prime: 'p224', - p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', - a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', + p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000000 00000001', + a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe', b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', hash: hash.sha256, @@ -70,6 +81,7 @@ defineCurve('p224', { ], }); +// 定义 p256 曲线 defineCurve('p256', { type: 'short', prime: null, @@ -85,17 +97,18 @@ defineCurve('p256', { ], }); +// 定义 p384 曲线 defineCurve('p384', { type: 'short', prime: null, p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'fffffffe ffffffff 00000000 00000000 ffffffff', + 'fffffffe ffffffff 00000000 00000000 ffffffff', a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'fffffffe ffffffff 00000000 00000000 fffffffc', + 'fffffffe ffffffff 00000000 00000000 fffffffc', b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' + - '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef', + '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef', n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' + - 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973', + 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973', hash: hash.sha384, gRed: false, g: [ @@ -106,21 +119,22 @@ defineCurve('p384', { ], }); +// 定义 p521 曲线 defineCurve('p521', { type: 'short', prime: null, p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'ffffffff ffffffff ffffffff ffffffff ffffffff', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff ffffffff', a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'ffffffff ffffffff ffffffff ffffffff fffffffc', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff fffffffc', b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' + - '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' + - '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00', + '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' + + '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00', n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + - 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' + - 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409', + 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' + + 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409', hash: hash.sha512, gRed: false, g: [ @@ -133,6 +147,7 @@ defineCurve('p521', { ], }); +// 定义 curve25519 曲线 defineCurve('curve25519', { type: 'mont', prime: 'p25519', @@ -147,6 +162,7 @@ defineCurve('curve25519', { ], }); +// 定义 ed25519 曲线 defineCurve('ed25519', { type: 'edwards', prime: 'p25519', @@ -166,6 +182,7 @@ defineCurve('ed25519', { ], }); +// 尝试加载预计算的 secp256k1 数据 var pre; try { pre = require('./precomputed/secp256k1'); @@ -173,6 +190,7 @@ try { pre = undefined; } +// 定义 secp256k1 曲线 defineCurve('secp256k1', { type: 'short', prime: 'k256', @@ -183,7 +201,7 @@ defineCurve('secp256k1', { h: '1', hash: hash.sha256, - // Precomputed endomorphism + // 预计算的自同态数据 beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', basis: [ @@ -203,4 +221,4 @@ defineCurve('secp256k1', { '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', pre, ], -}); +}); \ No newline at end of file diff --git a/node_modules/elliptic/lib/elliptic/utils.js b/node_modules/elliptic/lib/elliptic/utils.js index 627a9f1..ecceaef 100644 --- a/node_modules/elliptic/lib/elliptic/utils.js +++ b/node_modules/elliptic/lib/elliptic/utils.js @@ -1,59 +1,89 @@ 'use strict'; +// 将当前模块的内容向外暴露,通过 `utils` 对象来提供各种工具函数和属性 var utils = exports; + +// 引入 `bn.js` 库,用于处理大整数相关操作 var BN = require('bn.js'); +// 引入 `minimalistic-assert` 库,可能用于进行简单的断言操作 var minAssert = require('minimalistic-assert'); +// 引入 `minimalistic-crypto-utils` 库,包含一些密码学相关的工具函数 var minUtils = require('minimalistic-crypto-utils'); +// 将 `minimalistic-assert` 库中的断言函数挂载到 `utils` 对象上,方便外部调用进行条件判断和错误抛出 utils.assert = minAssert; +// 将 `minimalistic-crypto-utils` 库中的 `toArray` 函数挂载到 `utils` 对象上,可能用于将某些数据转换为数组形式 utils.toArray = minUtils.toArray; +// 挂载 `minimalistic-crypto-utils` 库中的 `zero2` 函数到 `utils` 对象,具体功能需看原函数定义 utils.zero2 = minUtils.zero2; +// 挂载 `minimalistic-crypto-utils` 库中的 `toHex` 函数到 `utils` 对象,可能用于将数据转换为十六进制表示形式 utils.toHex = minUtils.toHex; +// 挂载 `minimalistic-crypto-utils` 库中的 `encode` 函数到 `utils` 对象,其功能取决于原函数实现,可能用于编码相关操作 utils.encode = minUtils.encode; -// Represent num in a w-NAF form +// 函数 `getNAF` 的功能是将给定的大整数 `num` 表示为宽度为 `w` 的非相邻形式(w-NAF,Non-Adjacent Form) +// 参数: +// - `num`:要转换的大整数(`BN` 类型) +// - `w`:宽度参数,用于控制非相邻形式的表示方式 +// - `bits`:位数相关参数,可能用于确定结果数组的长度等 function getNAF(num, w, bits) { + // 创建一个数组 `naf`,长度根据 `num` 的位数和传入的 `bits` 参数确定,初始值都填充为 0 var naf = new Array(Math.max(num.bitLength(), bits) + 1); naf.fill(0); + // 计算一个与宽度 `w` 相关的值 `ws`,用于后续的位运算和计算 var ws = 1 << (w + 1); + // 克隆传入的大整数 `num`,用于后续在不改变原始值的情况下进行操作 var k = num.clone(); + // 循环遍历 `naf` 数组的每个位置,进行非相邻形式的转换计算 for (var i = 0; i < naf.length; i++) { var z; + // 通过位运算获取 `k` 的低 `w + 1` 位的值(取模操作) var mod = k.andln(ws - 1); + // 如果 `k` 是奇数(最低位为 1) if (k.isOdd()) { + // 根据 `mod` 的值来确定 `z` 的值,以满足非相邻形式的规则 if (mod > (ws >> 1) - 1) z = (ws >> 1) - mod; else z = mod; + // 从 `k` 中减去 `z` k.isubn(z); } else { + // 如果 `k` 是偶数,`z` 赋值为 0 z = 0; } + // 将计算得到的 `z` 值存入 `naf` 数组当前位置 naf[i] = z; + // 将 `k` 向右逻辑移位 1 位(相当于除以 2),为下一轮计算做准备 k.iushrn(1); } + // 返回表示为非相邻形式的数组 `naf` return naf; } +// 将 `getNAF` 函数挂载到 `utils` 对象上,方便外部调用 utils.getNAF = getNAF; -// Represent k1, k2 in a Joint Sparse Form +// 函数 `getJSF` 的功能是将两个大整数 `k1` 和 `k2` 表示为联合稀疏形式(Joint Sparse Form,JSF) function getJSF(k1, k2) { + // 创建一个二维数组 `jsf`,用于存储 `k1` 和 `k2` 的联合稀疏形式表示,初始化为两个空数组 var jsf = [ [], [], ]; + // 克隆传入的大整数 `k1` 和 `k2`,以便在不改变原始值的情况下进行操作 k1 = k1.clone(); k2 = k2.clone(); var d1 = 0; var d2 = 0; var m8; + // 循环条件是 `k1` 大于 `-d1` 或者 `k2` 大于 `-d2`,表示还未处理完所有位 while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { - // First phase + // 第一阶段:根据 `k1` 和 `k2` 的低几位来确定 `u1` 和 `u2` 的值 var m14 = (k1.andln(3) + d1) & 3; var m24 = (k2.andln(3) + d2) & 3; if (m14 === 3) @@ -70,6 +100,7 @@ function getJSF(k1, k2) { else u1 = m14; } + // 将计算得到的 `u1` 值存入 `jsf` 数组对应 `k1` 的位置 jsf[0].push(u1); var u2; @@ -82,9 +113,10 @@ function getJSF(k1, k2) { else u2 = m24; } + // 将计算得到的 `u2` 值存入 `jsf` 数组对应 `k2` 的位置 jsf[1].push(u2); - // Second phase + // 第二阶段:根据 `u1` 和 `u2` 的值来更新 `d1` 和 `d2` 的值,并将 `k1` 和 `k2` 向右逻辑移位 1 位(除以 2),为下一轮计算做准备 if (2 * d1 === u1 + 1) d1 = 1 - d1; if (2 * d2 === u2 + 1) @@ -93,27 +125,38 @@ function getJSF(k1, k2) { k2.iushrn(1); } + // 返回表示联合稀疏形式的二维数组 `jsf` return jsf; } +// 将 `getJSF` 函数挂载到 `utils` 对象上,方便外部调用 utils.getJSF = getJSF; +// 函数 `cachedProperty` 的功能是为对象的原型添加一个缓存属性,即第一次访问属性时会通过传入的计算函数 `computer` 来计算属性值并缓存起来,后续访问直接返回缓存的值 function cachedProperty(obj, name, computer) { + // 构造一个缓存属性的键名,以下划线开头加上属性名 var key = '_' + name; + // 在传入对象 `obj` 的原型上定义属性 `name`,通过闭包实现缓存逻辑 obj.prototype[name] = function cachedProperty() { - return this[key] !== undefined ? this[key] : - this[key] = computer.call(this); + // 如果缓存属性的值已经存在(`this[key]` 不为 `undefined`),则直接返回缓存的值 + return this[key]!== undefined? this[key] : + // 否则调用传入的计算函数 `computer` 计算属性值,将计算结果缓存到 `this[key]` 并返回该结果 + this[key] = computer.call(this); }; } +// 将 `cachedProperty` 函数挂载到 `utils` 对象上,方便外部使用来为对象添加缓存属性 utils.cachedProperty = cachedProperty; +// 函数 `parseBytes` 的功能是根据输入参数的类型进行不同的处理,如果是字符串类型,则调用 `utils` 对象中的 `toArray` 函数(假设是将十六进制字符串转换为字节数组的功能)将其转换为字节数组形式,否则直接返回输入的字节数据 function parseBytes(bytes) { - return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') : - bytes; + return typeof bytes === 'string'? utils.toArray(bytes, 'hex') : + bytes; } +// 将 `parseBytes` 函数挂载到 `utils` 对象上,方便外部调用进行字节数据的解析处理 utils.parseBytes = parseBytes; +// 函数 `intFromLE` 的功能是将给定的字节数据(以十六进制字符串表示或字节数组形式)转换为大整数(`BN` 类型),并按照小端序(Little-Endian)进行解析 function intFromLE(bytes) { return new BN(bytes, 'hex', 'le'); } -utils.intFromLE = intFromLE; - +// 将 `intFromLE` 函数挂载到 `utils` 对象上,方便外部调用进行小端序字节数据到大整数的转换 +utils.intFromLE = intFromLE; \ No newline at end of file -- 2.34.1