11 #11

Merged
pamj3bxuk merged 4 commits from branc_yz into main 1 year ago

@ -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 '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' y: ' + this.y.fromRed().toString(16, 2) +
' z: ' + this.z.fromRed().toString(16, 2) + '>';
// 从 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(); // 计算 BA 的平方
// 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,

Loading…
Cancel
Save