react / wstein / node_modules / browserify / node_modules / crypto-browserify / node_modules / browserify-sign / node_modules / elliptic / lib / elliptic / curve / mont.js
80621 views'use strict';12var curve = require('../curve');3var bn = require('bn.js');4var inherits = require('inherits');5var Base = curve.base;67function MontCurve(conf) {8Base.call(this, 'mont', conf);910this.a = new bn(conf.a, 16).toRed(this.red);11this.b = new bn(conf.b, 16).toRed(this.red);12this.i4 = new bn(4).toRed(this.red).redInvm();13this.two = new bn(2).toRed(this.red);14this.a24 = this.i4.redMul(this.a.redAdd(this.two));15}16inherits(MontCurve, Base);17module.exports = MontCurve;1819MontCurve.prototype.validate = function validate(point) {20var x = point.normalize().x;21var x2 = x.redSqr();22var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);23var y = rhs.redSqrt();2425return y.redSqr().cmp(rhs) === 0;26};2728function Point(curve, x, z) {29Base.BasePoint.call(this, curve, 'projective');30if (x === null && z === null) {31this.x = this.curve.one;32this.z = this.curve.zero;33} else {34this.x = new bn(x, 16);35this.z = new bn(z, 16);36if (!this.x.red)37this.x = this.x.toRed(this.curve.red);38if (!this.z.red)39this.z = this.z.toRed(this.curve.red);40}41}42inherits(Point, Base.BasePoint);4344MontCurve.prototype.point = function point(x, z) {45return new Point(this, x, z);46};4748MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {49return Point.fromJSON(this, obj);50};5152Point.prototype.precompute = function precompute() {53// No-op54};5556Point.fromJSON = function fromJSON(curve, obj) {57return new Point(curve, obj[0], obj[1] || curve.one);58};5960Point.prototype.inspect = function inspect() {61if (this.isInfinity())62return '<EC Point Infinity>';63return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +64' z: ' + this.z.fromRed().toString(16, 2) + '>';65};6667Point.prototype.isInfinity = function isInfinity() {68// XXX This code assumes that zero is always zero in red69return this.z.cmpn(0) === 0;70};7172Point.prototype.dbl = function dbl() {73// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-374// 2M + 2S + 4A7576// A = X1 + Z177var a = this.x.redAdd(this.z);78// AA = A^279var aa = a.redSqr();80// B = X1 - Z181var b = this.x.redSub(this.z);82// BB = B^283var bb = b.redSqr();84// C = AA - BB85var c = aa.redSub(bb);86// X3 = AA * BB87var nx = aa.redMul(bb);88// Z3 = C * (BB + A24 * C)89var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));90return this.curve.point(nx, nz);91};9293Point.prototype.add = function add() {94throw new Error('Not supported on Montgomery curve');95};9697Point.prototype.diffAdd = function diffAdd(p, diff) {98// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-399// 4M + 2S + 6A100101// A = X2 + Z2102var a = this.x.redAdd(this.z);103// B = X2 - Z2104var b = this.x.redSub(this.z);105// C = X3 + Z3106var c = p.x.redAdd(p.z);107// D = X3 - Z3108var d = p.x.redSub(p.z);109// DA = D * A110var da = d.redMul(a);111// CB = C * B112var cb = c.redMul(b);113// X5 = Z1 * (DA + CB)^2114var nx = diff.z.redMul(da.redAdd(cb).redSqr());115// Z5 = X1 * (DA - CB)^2116var nz = diff.x.redMul(da.redISub(cb).redSqr());117return this.curve.point(nx, nz);118};119120Point.prototype.mul = function mul(k) {121var t = k.clone();122var a = this; // (N / 2) * Q + Q123var b = this.curve.point(null, null); // (N / 2) * Q124var c = this; // Q125126for (var bits = []; t.cmpn(0) !== 0; t.ishrn(1))127bits.push(t.andln(1));128129for (var i = bits.length - 1; i >= 0; i--) {130if (bits[i] === 0) {131// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q132a = a.diffAdd(b, c);133// N * Q = 2 * ((N / 2) * Q + Q))134b = b.dbl();135} else {136// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)137b = a.diffAdd(b, c);138// N * Q + Q = 2 * ((N / 2) * Q + Q)139a = a.dbl();140}141}142return b;143};144145Point.prototype.mulAdd = function mulAdd() {146throw new Error('Not supported on Montgomery curve');147};148149Point.prototype.normalize = function normalize() {150this.x = this.x.redMul(this.z.redInvm());151this.z = this.curve.one;152return this;153};154155Point.prototype.getX = function getX() {156// Normalize coordinates157this.normalize();158159return this.x.fromRed();160};161162163