1 | 'use strict';
|
2 |
|
3 | var BN = require('bn.js');
|
4 | var $ = require('../util/preconditions');
|
5 | var _ = require('lodash');
|
6 |
|
7 | var reversebuf = function(buf) {
|
8 | var buf2 = Buffer.alloc(buf.length);
|
9 | for (var i = 0; i < buf.length; i++) {
|
10 | buf2[i] = buf[buf.length - 1 - i];
|
11 | }
|
12 | return buf2;
|
13 | };
|
14 |
|
15 | BN.Zero = new BN(0);
|
16 | BN.One = new BN(1);
|
17 | BN.Minus1 = new BN(-1);
|
18 |
|
19 | BN.fromNumber = function(n) {
|
20 | $.checkArgument(_.isNumber(n));
|
21 | return new BN(n);
|
22 | };
|
23 |
|
24 | BN.fromString = function(str, base) {
|
25 | $.checkArgument(_.isString(str));
|
26 | return new BN(str, base);
|
27 | };
|
28 |
|
29 | BN.fromBuffer = function(buf, opts) {
|
30 | if (typeof opts !== 'undefined' && opts.endian === 'little') {
|
31 | buf = reversebuf(buf);
|
32 | }
|
33 | var hex = buf.toString('hex');
|
34 | var bn = new BN(hex, 16);
|
35 | return bn;
|
36 | };
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | BN.fromSM = function(buf, opts) {
|
43 | var ret;
|
44 | if (buf.length === 0) {
|
45 | return BN.fromBuffer(Buffer.from([0]));
|
46 | }
|
47 |
|
48 | var endian = 'big';
|
49 | if (opts) {
|
50 | endian = opts.endian;
|
51 | }
|
52 | if (endian === 'little') {
|
53 | buf = reversebuf(buf);
|
54 | }
|
55 |
|
56 | if (buf[0] & 0x80) {
|
57 | buf[0] = buf[0] & 0x7f;
|
58 | ret = BN.fromBuffer(buf);
|
59 | ret.neg().copy(ret);
|
60 | } else {
|
61 | ret = BN.fromBuffer(buf);
|
62 | }
|
63 | return ret;
|
64 | };
|
65 |
|
66 |
|
67 | BN.prototype.toNumber = function() {
|
68 | return parseInt(this.toString(10), 10);
|
69 | };
|
70 |
|
71 | BN.prototype.toBuffer = function(opts) {
|
72 | var buf, hex;
|
73 | if (opts && opts.size) {
|
74 | hex = this.toString(16, 2);
|
75 | var natlen = hex.length / 2;
|
76 | buf = Buffer.from(hex, 'hex');
|
77 |
|
78 | if (natlen === opts.size) {
|
79 | buf = buf;
|
80 | } else if (natlen > opts.size) {
|
81 | buf = BN.trim(buf, natlen);
|
82 | } else if (natlen < opts.size) {
|
83 | buf = BN.pad(buf, natlen, opts.size);
|
84 | }
|
85 | } else {
|
86 | hex = this.toString(16, 2);
|
87 | buf = Buffer.from(hex, 'hex');
|
88 | }
|
89 |
|
90 | if (typeof opts !== 'undefined' && opts.endian === 'little') {
|
91 | buf = reversebuf(buf);
|
92 | }
|
93 |
|
94 | return buf;
|
95 | };
|
96 |
|
97 | BN.prototype.toSMBigEndian = function() {
|
98 | var buf;
|
99 | if (this.cmp(BN.Zero) === -1) {
|
100 | buf = this.neg().toBuffer();
|
101 | if (buf[0] & 0x80) {
|
102 | buf = Buffer.concat([Buffer.from([0x80]), buf]);
|
103 | } else {
|
104 | buf[0] = buf[0] | 0x80;
|
105 | }
|
106 | } else {
|
107 | buf = this.toBuffer();
|
108 | if (buf[0] & 0x80) {
|
109 | buf = Buffer.concat([Buffer.from([0x00]), buf]);
|
110 | }
|
111 | }
|
112 |
|
113 | if (buf.length === 1 & buf[0] === 0) {
|
114 | buf = Buffer.from([]);
|
115 | }
|
116 | return buf;
|
117 | };
|
118 |
|
119 | BN.prototype.toSM = function(opts) {
|
120 | var endian = opts ? opts.endian : 'big';
|
121 | var buf = this.toSMBigEndian();
|
122 |
|
123 | if (endian === 'little') {
|
124 | buf = reversebuf(buf);
|
125 | }
|
126 | return buf;
|
127 | };
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | BN.fromScriptNumBuffer = function(buf, fRequireMinimal, size) {
|
138 | var nMaxNumSize = size || 4;
|
139 | $.checkArgument(buf.length <= nMaxNumSize, new Error('script number overflow'));
|
140 | if (fRequireMinimal && buf.length > 0) {
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 | if ((buf[buf.length - 1] & 0x7f) === 0) {
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
|
154 | throw new Error('non-minimally encoded script number');
|
155 | }
|
156 | }
|
157 | }
|
158 | return BN.fromSM(buf, {
|
159 | endian: 'little'
|
160 | });
|
161 | };
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | BN.prototype.toScriptNumBuffer = function() {
|
170 | return this.toSM({
|
171 | endian: 'little'
|
172 | });
|
173 | };
|
174 |
|
175 | BN.trim = function(buf, natlen) {
|
176 | return buf.slice(natlen - buf.length, buf.length);
|
177 | };
|
178 |
|
179 | BN.pad = function(buf, natlen, size) {
|
180 | var rbuf = Buffer.alloc(size);
|
181 | for (var i = 0; i < buf.length; i++) {
|
182 | rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i];
|
183 | }
|
184 | for (i = 0; i < size - natlen; i++) {
|
185 | rbuf[i] = 0;
|
186 | }
|
187 | return rbuf;
|
188 | };
|
189 |
|
190 | module.exports = BN;
|