1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | 'use strict'
|
13 |
|
14 | import { Bn } from './bn'
|
15 | import elliptic from 'bitcoin-elliptic'
|
16 |
|
17 | const ec = elliptic.curves.secp256k1
|
18 | const _point = ec.curve.point()
|
19 | const _Point = _point.constructor
|
20 |
|
21 | class Point extends _Point {
|
22 | constructor (x, y, isRed) {
|
23 | super(ec.curve, x, y, isRed)
|
24 | }
|
25 |
|
26 | static fromX (isOdd, x) {
|
27 | const _point = ec.curve.pointFromX(x, isOdd)
|
28 | const point = Object.create(Point.prototype)
|
29 | return point.copyFrom(_point)
|
30 | }
|
31 |
|
32 | copyFrom (point) {
|
33 | if (!(point instanceof _Point)) {
|
34 | throw new Error('point should be an external point')
|
35 | }
|
36 | Object.keys(point).forEach(
|
37 | function (key) {
|
38 | this[key] = point[key]
|
39 | }.bind(this)
|
40 | )
|
41 | return this
|
42 | }
|
43 |
|
44 | add (p) {
|
45 | p = _Point.prototype.add.call(this, p)
|
46 | const point = Object.create(Point.prototype)
|
47 | return point.copyFrom(p)
|
48 | }
|
49 |
|
50 | mul (bn) {
|
51 | if (!bn.lt(Point.getN())) {
|
52 | throw new Error('point mul out of range')
|
53 | }
|
54 | const p = _Point.prototype.mul.call(this, bn)
|
55 | const point = Object.create(Point.prototype)
|
56 | return point.copyFrom(p)
|
57 | }
|
58 |
|
59 | mulAdd (bn1, point, bn2) {
|
60 | const p = _Point.prototype.mulAdd.call(this, bn1, point, bn2)
|
61 | point = Object.create(Point.prototype)
|
62 | return point.copyFrom(p)
|
63 | }
|
64 |
|
65 | getX () {
|
66 | const _x = _Point.prototype.getX.call(this)
|
67 | const x = Object.create(Bn.prototype)
|
68 | _x.copy(x)
|
69 | return x
|
70 | }
|
71 |
|
72 | getY () {
|
73 | const _y = _Point.prototype.getY.call(this)
|
74 | const y = Object.create(Bn.prototype)
|
75 | _y.copy(y)
|
76 | return y
|
77 | }
|
78 |
|
79 | fromX (isOdd, x) {
|
80 | const point = Point.fromX(isOdd, x)
|
81 | return this.copyFrom(point)
|
82 | }
|
83 |
|
84 | toJSON () {
|
85 | return {
|
86 | x: this.getX().toString(),
|
87 | y: this.getY().toString()
|
88 | }
|
89 | }
|
90 |
|
91 | fromJSON (json) {
|
92 | const x = new Bn().fromString(json.x)
|
93 | const y = new Bn().fromString(json.y)
|
94 | const point = new Point(x, y)
|
95 | return this.copyFrom(point)
|
96 | }
|
97 |
|
98 | toString () {
|
99 | return JSON.stringify(this.toJSON())
|
100 | }
|
101 |
|
102 | fromString (str) {
|
103 | const json = JSON.parse(str)
|
104 | const p = new Point().fromJSON(json)
|
105 | return this.copyFrom(p)
|
106 | }
|
107 |
|
108 | static getG () {
|
109 | const _g = ec.curve.g
|
110 | const g = Object.create(Point.prototype)
|
111 | return g.copyFrom(_g)
|
112 | }
|
113 |
|
114 | static getN () {
|
115 | return new Bn(ec.curve.n.toArray())
|
116 | }
|
117 |
|
118 |
|
119 | validate () {
|
120 | const p2 = Point.fromX(this.getY().isOdd(), this.getX())
|
121 | if (!(p2.getY().cmp(this.getY()) === 0)) {
|
122 | throw new Error('Invalid y value of public key')
|
123 | }
|
124 | if (
|
125 | !(this.getX().gt(-1) && this.getX().lt(Point.getN())) ||
|
126 | !(this.getY().gt(-1) && this.getY().lt(Point.getN()))
|
127 | ) {
|
128 | throw new Error('Point does not lie on the curve')
|
129 | }
|
130 | return this
|
131 | }
|
132 | }
|
133 |
|
134 | export { Point }
|