diff --git a/node_modules/elliptic/lib/elliptic/curve/edwards.js b/node_modules/elliptic/lib/elliptic/curve/edwards.js index 6e757c6..8e2ede5 100644 --- a/node_modules/elliptic/lib/elliptic/curve/edwards.js +++ b/node_modules/elliptic/lib/elliptic/curve/edwards.js @@ -1,394 +1,455 @@ 'use strict'; -var utils = require('../utils'); -var BN = require('bn.js'); -var inherits = require('inherits'); -var Base = require('./base'); +var utils = require('../utils'); // 引入工具模块 +var BN = require('bn.js'); // 引入大数库 +var inherits = require('inherits'); // 引入继承库 +var Base = require('./base'); // 引入基类 -var assert = utils.assert; +var assert = utils.assert; // 引入断言工具 +// 定义 EdwardsCurve 类 function EdwardsCurve(conf) { - // NOTE: Important as we are creating point in Base.call() + // 检查曲线是否是扭曲的 this.twisted = (conf.a | 0) !== 1; - this.mOneA = this.twisted && (conf.a | 0) === -1; - this.extended = this.mOneA; + this.mOneA = this.twisted && (conf.a | 0) === -1; // 检查参数 a 是否为 -1 + this.extended = this.mOneA; // 是否使用扩展形式 - Base.call(this, 'edwards', conf); + Base.call(this, 'edwards', conf); // 调用基类构造函数 - this.a = new BN(conf.a, 16).umod(this.red.m); - this.a = this.a.toRed(this.red); - this.c = new BN(conf.c, 16).toRed(this.red); - this.c2 = this.c.redSqr(); - this.d = new BN(conf.d, 16).toRed(this.red); - this.dd = this.d.redAdd(this.d); + // 初始化曲线参数 + this.a = new BN(conf.a, 16).umod(this.red.m); // 将 a 转换为大数并取模 + this.a = this.a.toRed(this.red); // 转换为红色形式 + this.c = new BN(conf.c, 16).toRed(this.red); // 转换 c + this.c2 = this.c.redSqr(); // 计算 c 的平方 + this.d = new BN(conf.d, 16).toRed(this.red); // 转换 d + this.dd = this.d.redAdd(this.d); // 计算 2d + // 断言确保曲线参数的合法性 assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); - this.oneC = (conf.c | 0) === 1; + this.oneC = (conf.c | 0) === 1; // 检查 c 是否为 1 } -inherits(EdwardsCurve, Base); -module.exports = EdwardsCurve; +inherits(EdwardsCurve, Base); // 继承 Base 类 +module.exports = EdwardsCurve; // 导出 EdwardsCurve 类 +// 计算 a 与 num 的乘积 EdwardsCurve.prototype._mulA = function _mulA(num) { if (this.mOneA) - return num.redNeg(); + return num.redNeg(); // 如果 mOneA 为 true,返回 num 的相反数 else - return this.a.redMul(num); + return this.a.redMul(num); // 否则返回 a 与 num 的乘积 }; +// 计算 c 与 num 的乘积 EdwardsCurve.prototype._mulC = function _mulC(num) { if (this.oneC) - return num; + return num; // 如果 c 为 1,返回 num else - return this.c.redMul(num); + return this.c.redMul(num); // 否则返回 c 与 num 的乘积 }; -// Just for compatibility with Short curve +// 为了与短曲线兼容,返回点 EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { - return this.point(x, y, z, t); + return this.point(x, y, z, t); // 返回点 }; +// 从 x 坐标生成点 EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { - x = new BN(x, 16); + x = new BN(x, 16); // 将 x 转换为大数 if (!x.red) - x = x.toRed(this.red); + x = x.toRed(this.red); // 转换为红色形式 - var x2 = x.redSqr(); - var rhs = this.c2.redSub(this.a.redMul(x2)); - var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); + var x2 = x.redSqr(); // 计算 x 的平方 + var rhs = this.c2.redSub(this.a.redMul(x2)); // 计算右侧值 + var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); // 计算左侧值 - var y2 = rhs.redMul(lhs.redInvm()); - var y = y2.redSqrt(); + var y2 = rhs.redMul(lhs.redInvm()); // 计算 y^2 + var y = y2.redSqrt(); // 计算 y + + // 验证 y 是否有效 if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) - throw new Error('invalid point'); + throw new Error('invalid point'); // 如果无效,抛出错误 - var isOdd = y.fromRed().isOdd(); + var isOdd = y.fromRed().isOdd(); // 检查 y 是否为奇数 if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); + y = y.redNeg(); // 根据 odd 参数调整 y 的符号 - return this.point(x, y); + return this.point(x, y); // 返回生成的点 }; +// 从 y 坐标生成点 EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { - y = new BN(y, 16); + y = new BN(y, 16); // 将 y 转换为大数 if (!y.red) - y = y.toRed(this.red); + y = y.toRed(this.red); // 转换为红色形式 - // x^2 = (y^2 - c^2) / (c^2 d y^2 - a) + // 计算 x^2 var y2 = y.redSqr(); - var lhs = y2.redSub(this.c2); - var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a); - var x2 = lhs.redMul(rhs.redInvm()); + var lhs = y2.redSub(this.c2); // 计算左侧 + var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a); // 计算右侧 + var x2 = lhs.redMul(rhs.redInvm()); // 计算 x^2 + // 处理特殊情况 if (x2.cmp(this.zero) === 0) { if (odd) - throw new Error('invalid point'); + throw new Error('invalid point'); // 如果 odd 为真,抛出错误 else - return this.point(this.zero, y); + return this.point(this.zero, y); // 返回 (0, y) } - var x = x2.redSqrt(); + var x = x2.redSqrt(); // 计算 x if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) - throw new Error('invalid point'); + throw new Error('invalid point'); // 验证 x 是否有效 + // 根据 odd 参数调整 x 的符号 if (x.fromRed().isOdd() !== odd) x = x.redNeg(); - return this.point(x, y); + return this.point(x, y); // 返回生成的点 }; +// 验证点的有效性 EdwardsCurve.prototype.validate = function validate(point) { if (point.isInfinity()) - return true; + return true; // 如果点是无穷大,返回 true - // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) - point.normalize(); + point.normalize(); // 规范化点 - var x2 = point.x.redSqr(); - var y2 = point.y.redSqr(); - var lhs = x2.redMul(this.a).redAdd(y2); - var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); + // 曲线方程: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) + var x2 = point.x.redSqr(); // 计算 x^2 + var y2 = point.y.redSqr(); // 计算 y^2 + var lhs = x2.redMul(this.a).redAdd(y2); // 计算左侧 + var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); // 计算右侧 - return lhs.cmp(rhs) === 0; + return lhs.cmp(rhs) === 0; // 比较左右两侧是否相等 }; -function Point(curve, x, y, z, t) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && y === null && z === null) { - this.x = this.curve.zero; - this.y = this.curve.one; - this.z = this.curve.one; - this.t = this.curve.zero; - this.zOne = true; - } else { - this.x = new BN(x, 16); - this.y = new BN(y, 16); - this.z = z ? new BN(z, 16) : this.curve.one; - this.t = t && new BN(t, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - if (this.t && !this.t.red) - this.t = this.t.toRed(this.curve.red); - this.zOne = this.z === this.curve.one; - - // Use extended coordinates - if (this.curve.extended && !this.t) { - this.t = this.x.redMul(this.y); - if (!this.zOne) - this.t = this.t.redMul(this.z.redInvm()); - } - } + +'use strict'; + +var utils = require('../utils'); // 引入工具模块 +var BN = require('bn.js'); // 引入大数库 +var inherits = require('inherits'); // 引入继承库 +var Base = require('./base'); // 引入基类 + +var assert = utils.assert; // 引入断言工具 + +// 定义 EdwardsCurve 类 +function EdwardsCurve(conf) { + // 检查曲线是否是扭曲的 + this.twisted = (conf.a | 0) !== 1; + this.mOneA = this.twisted && (conf.a | 0) === -1; // 检查参数 a 是否为 -1 + this.extended = this.mOneA; // 是否使用扩展形式 + + Base.call(this, 'edwards', conf); // 调用基类构造函数 + + // 初始化曲线参数 + this.a = new BN(conf.a, 16).umod(this.red.m); // 将 a 转换为大数并取模 + this.a = this.a.toRed(this.red); // 转换为红色形式 + this.c = new BN(conf.c, 16).toRed(this.red); // 转换 c + this.c2 = this.c.redSqr(); // 计算 c 的平方 + this.d = new BN(conf.d, 16).toRed(this.red); // 转换 d + this.dd = this.d.redAdd(this.d); // 计算 2d + + // 断言确保曲线参数的合法性 + assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); + this.oneC = (conf.c | 0) === 1; // 检查 c 是否为 1 } -inherits(Point, Base.BasePoint); +inherits(EdwardsCurve, Base); // 继承 Base 类 +module.exports = EdwardsCurve; // 导出 EdwardsCurve 类 -EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); +// 计算 a 与 num 的乘积 +EdwardsCurve.prototype._mulA = function _mulA(num) { + if (this.mOneA) + return num.redNeg(); // 如果 mOneA 为 true,返回 num 的相反数 + else + return this.a.redMul(num); // 否则返回 a 与 num 的乘积 }; -EdwardsCurve.prototype.point = function point(x, y, z, t) { - return new Point(this, x, y, z, t); +// 计算 c 与 num 的乘积 +EdwardsCurve.prototype._mulC = function _mulC(num) { + if (this.oneC) + return num; // 如果 c 为 1,返回 num + else + return this.c.redMul(num); // 否则返回 c 与 num 的乘积 }; -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1], obj[2]); +// 为了与短曲线兼容,返回点 +EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { + return this.point(x, y, z, t); // 返回点 }; -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; +// 从 x 坐标生成点 +EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { + x = new BN(x, 16); // 将 x 转换为大数 + if (!x.red) + x = x.toRed(this.red); // 转换为红色形式 + + var x2 = x.redSqr(); // 计算 x 的平方 + var rhs = this.c2.redSub(this.a.redMul(x2)); // 计算右侧值 + var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); // 计算左侧值 + + var y2 = rhs.redMul(lhs.redInvm()); // 计算 y^2 + var y = y2.redSqrt(); // 计算 y + + // 验证 y 是否有效 + if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) + throw new Error('invalid point'); // 如果无效,抛出错误 + + var isOdd = y.fromRed().isOdd(); // 检查 y 是否为奇数 + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); // 根据 odd 参数调整 y 的符号 + + return this.point(x, y); // 返回生成的点 }; -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.x.cmpn(0) === 0 && - (this.y.cmp(this.z) === 0 || - (this.zOne && this.y.cmp(this.curve.c) === 0)); +// 从 y 坐标生成点 +EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { + y = new BN(y, 16); // 将 y 转换为大数 + if (!y.red) + y = y.toRed(this.red); // 转换为红色形式 + + // 计算 x^2 + var y2 = y.redSqr(); + var lhs = y2.redSub(this.c2); // 计算左侧 + var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a); // 计算右侧 + var x2 = lhs.redMul(rhs.redInvm()); // 计算 x^2 + + // 处理特殊情况 + if (x2.cmp(this.zero) === 0) { + if (odd) + throw new Error('invalid point'); // 如果 odd 为真,抛出错误 + else + return this.point(this.zero, y); // 返回 (0, y) + } + + var x = x2.redSqrt(); // 计算 x + if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) + throw new Error('invalid point'); // 验证 x 是否有效 + + // 根据 odd 参数调整 x 的符号 + if (x.fromRed().isOdd() !== odd) + x = x.redNeg(); + + return this.point(x, y); // 返回生成的点 }; -Point.prototype._extDbl = function _extDbl() { - // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html - // #doubling-dbl-2008-hwcd - // 4M + 4S - - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = 2 * Z1^2 - var c = this.z.redSqr(); - c = c.redIAdd(c); - // D = a * A - var d = this.curve._mulA(a); - // E = (X1 + Y1)^2 - A - B - var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); - // G = D + B - var g = d.redAdd(b); - // F = G - C - var f = g.redSub(c); - // H = D - B - var h = d.redSub(b); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); +// 验证点的有效性 +EdwardsCurve.prototype.validate = function validate(point) { + if (point.isInfinity()) + return true; // 如果点是无穷大,返回 true + + point.normalize(); // 规范化点 + + // 曲线方程: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) + var x2 = point.x.redSqr(); // 计算 x^2 + var y2 = point.y.redSqr(); // 计算 y^2 + var lhs = x2.redMul(this.a).redAdd(y2); // 计算左侧 + var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); // 计算右侧 + + return lhs.cmp(rhs) === 0; // 比较左右两侧是否相等 }; +// 在投影坐标系中执行点的倍增 Point.prototype._projDbl = function _projDbl() { - // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // 参考文献: hyperelliptic.org/EFD/g1p/auto-twisted-projective.html // #doubling-dbl-2008-bbjlp // #doubling-dbl-2007-bl - // and others - // Generally 3M + 4S or 2M + 4S + // 一般需要 3M + 4S 或 2M + 4S 的运算 // B = (X1 + Y1)^2 - var b = this.x.redAdd(this.y).redSqr(); + var b = this.x.redAdd(this.y).redSqr(); // 计算 B // C = X1^2 - var c = this.x.redSqr(); + var c = this.x.redSqr(); // 计算 C // D = Y1^2 - var d = this.y.redSqr(); - - var nx; - var ny; - var nz; - var e; - var h; - var j; - if (this.curve.twisted) { + var d = this.y.redSqr(); // 计算 D + + var nx; // 新点的 x 坐标 + var ny; // 新点的 y 坐标 + var nz; // 新点的 z 坐标 + var e; // 中间变量 + var h; // 中间变量 + var j; // 中间变量 + + if (this.curve.twisted) { // 如果曲线是扭曲的 // E = a * C - e = this.curve._mulA(c); + e = this.curve._mulA(c); // 计算 E // F = E + D - var f = e.redAdd(d); - if (this.zOne) { + var f = e.redAdd(d); // 计算 F + if (this.zOne) { // 如果 z 坐标为 1 // X3 = (B - C - D) * (F - 2) - nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); + nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); // 计算新点的 x 坐标 // Y3 = F * (E - D) - ny = f.redMul(e.redSub(d)); + ny = f.redMul(e.redSub(d)); // 计算新点的 y 坐标 // Z3 = F^2 - 2 * F - nz = f.redSqr().redSub(f).redSub(f); + nz = f.redSqr().redSub(f).redSub(f); // 计算新点的 z 坐标 } else { // H = Z1^2 - h = this.z.redSqr(); + h = this.z.redSqr(); // 计算 H // J = F - 2 * H - j = f.redSub(h).redISub(h); + j = f.redSub(h).redISub(h); // 计算 J // X3 = (B-C-D)*J - nx = b.redSub(c).redISub(d).redMul(j); + nx = b.redSub(c).redISub(d).redMul(j); // 计算新点的 x 坐标 // Y3 = F * (E - D) - ny = f.redMul(e.redSub(d)); + ny = f.redMul(e.redSub(d)); // 计算新点的 y 坐标 // Z3 = F * J - nz = f.redMul(j); + nz = f.redMul(j); // 计算新点的 z 坐标 } - } else { + } else { // 如果曲线不是扭曲的 // E = C + D - e = c.redAdd(d); + e = c.redAdd(d); // 计算 E // H = (c * Z1)^2 - h = this.curve._mulC(this.z).redSqr(); + h = this.curve._mulC(this.z).redSqr(); // 计算 H // J = E - 2 * H - j = e.redSub(h).redSub(h); + j = e.redSub(h).redSub(h); // 计算 J // X3 = c * (B - E) * J - nx = this.curve._mulC(b.redISub(e)).redMul(j); + nx = this.curve._mulC(b.redISub(e)).redMul(j); // 计算新点的 x 坐标 // Y3 = c * E * (C - D) - ny = this.curve._mulC(e).redMul(c.redISub(d)); + ny = this.curve._mulC(e).redMul(c.redISub(d)); // 计算新点的 y 坐标 // Z3 = E * J - nz = e.redMul(j); + nz = e.redMul(j); // 计算新点的 z 坐标 } - return this.curve.point(nx, ny, nz); + return this.curve.point(nx, ny, nz); // 返回新计算的点 }; +// 点的倍增方法 Point.prototype.dbl = function dbl() { - if (this.isInfinity()) + if (this.isInfinity()) // 如果点是无穷大,直接返回 return this; - // Double in extended coordinates + // 在扩展坐标下倍增 if (this.curve.extended) - return this._extDbl(); + return this._extDbl(); // 调用扩展坐标倍增方法 else - return this._projDbl(); + return this._projDbl(); // 调用投影坐标倍增方法 }; +// 在扩展坐标系中执行点的加法 Point.prototype._extAdd = function _extAdd(p) { - // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // 参考文献: hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html // #addition-add-2008-hwcd-3 - // 8M + // 需要 8M 的运算 // A = (Y1 - X1) * (Y2 - X2) - var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); + var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); // 计算 A // B = (Y1 + X1) * (Y2 + X2) - var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); + var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); // 计算 B // C = T1 * k * T2 - var c = this.t.redMul(this.curve.dd).redMul(p.t); + var c = this.t.redMul(this.curve.dd).redMul(p.t); // 计算 C // D = Z1 * 2 * Z2 - var d = this.z.redMul(p.z.redAdd(p.z)); + var d = this.z.redMul(p.z.redAdd(p.z)); // 计算 D // E = B - A - var e = b.redSub(a); + var e = b.redSub(a); // 计算 E // F = D - C - var f = d.redSub(c); + var f = d.redSub(c); // 计算 F // G = D + C - var g = d.redAdd(c); + var g = d.redAdd(c); // 计算 G // H = B + A - var h = b.redAdd(a); + var h = b.redAdd(a); // 计算 H // X3 = E * F - var nx = e.redMul(f); + var nx = e.redMul(f); // 计算新点的 x 坐标 // Y3 = G * H - var ny = g.redMul(h); + var ny = g.redMul(h); // 计算新点的 y 坐标 // T3 = E * H - var nt = e.redMul(h); + var nt = e.redMul(h); // 计算新点的 t 坐标 // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); + var nz = f.redMul(g); // 计算新点的 z 坐标 + return this.curve.point(nx, ny, nz, nt); // 返回新计算的点 }; + +// 在投影坐标系中执行点的加法 Point.prototype._projAdd = function _projAdd(p) { - // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // 参考文献: hyperelliptic.org/EFD/g1p/auto-twisted-projective.html // #addition-add-2008-bbjlp // #addition-add-2007-bl - // 10M + 1S + // 计算复杂度: 10M + 1S // A = Z1 * Z2 - var a = this.z.redMul(p.z); + var a = this.z.redMul(p.z); // 计算 A,两个点的 z 坐标的乘积 // B = A^2 - var b = a.redSqr(); + var b = a.redSqr(); // 计算 B,A 的平方 // C = X1 * X2 - var c = this.x.redMul(p.x); + var c = this.x.redMul(p.x); // 计算 C,两个点的 x 坐标的乘积 // D = Y1 * Y2 - var d = this.y.redMul(p.y); + var d = this.y.redMul(p.y); // 计算 D,两个点的 y 坐标的乘积 // E = d * C * D - var e = this.curve.d.redMul(c).redMul(d); + var e = this.curve.d.redMul(c).redMul(d); // 计算 E,涉及曲线参数 d // F = B - E - var f = b.redSub(e); + var f = b.redSub(e); // 计算 F // G = B + E - var g = b.redAdd(e); + var g = b.redAdd(e); // 计算 G // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) - var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); - var nx = a.redMul(f).redMul(tmp); - var ny; - var nz; - if (this.curve.twisted) { + var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d; // 计算 tmp + var nx = a.redMul(f).redMul(tmp); // 计算新点的 x 坐标 + var ny; // 新点的 y 坐标 + var nz; // 新点的 z 坐标 + + if (this.curve.twisted) { // 如果曲线是扭曲的 // Y3 = A * G * (D - a * C) - ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); + ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); // 计算新点的 y 坐标 // Z3 = F * G - nz = f.redMul(g); - } else { + nz = f.redMul(g); // 计算新点的 z 坐标 + } else { // 如果曲线不是扭曲的 // Y3 = A * G * (D - C) - ny = a.redMul(g).redMul(d.redSub(c)); + ny = a.redMul(g).redMul(d.redSub(c)); // 计算新点的 y 坐标 // Z3 = c * F * G - nz = this.curve._mulC(f).redMul(g); + nz = this.curve._mulC(f).redMul(g); // 计算新点的 z 坐标 } - return this.curve.point(nx, ny, nz); + + return this.curve.point(nx, ny, nz); // 返回新计算的点 }; +// 点的加法方法 Point.prototype.add = function add(p) { - if (this.isInfinity()) + if (this.isInfinity()) // 如果当前点是无穷大,返回 p return p; - if (p.isInfinity()) + if (p.isInfinity()) // 如果 p 是无穷大,返回当前点 return this; + // 根据曲线的坐标系统调用相应的加法方法 if (this.curve.extended) - return this._extAdd(p); + return this._extAdd(p); // 调用扩展坐标加法方法 else - return this._projAdd(p); + return this._projAdd(p); // 调用投影坐标加法方法 }; +// 点的倍乘方法 Point.prototype.mul = function mul(k) { + // 如果 k 有重复的倍增操作,使用固定的 NAF 乘法 if (this._hasDoubles(k)) return this.curve._fixedNafMul(this, k); - else + else // 否则使用 WNAF 乘法 return this.curve._wnafMul(this, k); }; +// 进行加法的倍乘方法 Point.prototype.mulAdd = function mulAdd(k1, p, k2) { + // 使用 WNAF 乘法加法,返回结果 return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false); }; +// 在 Jacobian 坐标系下进行加法的倍乘方法 Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) { + // 使用 WNAF 乘法加法,返回结果 return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true); }; +// 归一化点的坐标 Point.prototype.normalize = function normalize() { - if (this.zOne) + if (this.zOne) // 如果 z 坐标为 1,直接返回当前点 return this; - // Normalize coordinates + // 计算 z 的逆 var zi = this.z.redInvm(); - this.x = this.x.redMul(zi); - this.y = this.y.redMul(zi); - if (this.t) - this.t = this.t.redMul(zi); - this.z = this.curve.one; - this.zOne = true; - return this; + this.x = this.x.redMul(zi); // 归一化 x 坐标 + this.y = this.y.redMul(zi); // 归一化 y 坐标 + if (this.t) // 如果有 t 坐标 + this.t = this.t.redMul(zi); // 归一化 t 坐标 + this.z = this.curve.one; // 将 z 坐标设为 1 + this.zOne = true; // 设置标志为 true + return this; // 返回归一化后的点 }; - + Point.prototype.neg = function neg() { return this.curve.point(this.x.redNeg(), this.y,