1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | 'use strict'
|
27 |
|
28 | import _Bn from 'bn.js'
|
29 |
|
30 | function Bn (n, base, ...rest) {
|
31 | if (!(this instanceof Bn)) {
|
32 | return new Bn(n, base, ...rest)
|
33 | }
|
34 | _Bn.call(this, n, base, ...rest)
|
35 | }
|
36 |
|
37 | Object.keys(_Bn).forEach(function (key) {
|
38 | Bn[key] = _Bn[key]
|
39 | })
|
40 | Bn.prototype = Object.create(_Bn.prototype)
|
41 | Bn.prototype.constructor = Bn
|
42 |
|
43 | function reverseBuf (buf) {
|
44 | const buf2 = Buffer.alloc(buf.length)
|
45 | for (let i = 0; i < buf.length; i++) {
|
46 | buf2[i] = buf[buf.length - 1 - i]
|
47 | }
|
48 | return buf2
|
49 | }
|
50 |
|
51 | Bn.prototype.fromHex = function (hex, opts) {
|
52 | return this.fromBuffer(Buffer.from(hex, 'hex'), opts)
|
53 | }
|
54 |
|
55 | Bn.prototype.toHex = function (opts) {
|
56 | return this.toBuffer(opts).toString('hex')
|
57 | }
|
58 |
|
59 | Bn.prototype.toJSON = function () {
|
60 | return this.toString()
|
61 | }
|
62 |
|
63 | Bn.prototype.fromJSON = function (str) {
|
64 | const bn = Bn(str)
|
65 | bn.copy(this)
|
66 | return this
|
67 | }
|
68 |
|
69 | Bn.prototype.fromNumber = function (n) {
|
70 | const bn = Bn(n)
|
71 | bn.copy(this)
|
72 | return this
|
73 | }
|
74 |
|
75 | Bn.prototype.toNumber = function () {
|
76 | return parseInt(this.toString(10), 10)
|
77 | }
|
78 |
|
79 | Bn.prototype.fromString = function (str, base) {
|
80 | const bn = Bn(str, base)
|
81 | bn.copy(this)
|
82 | return this
|
83 | }
|
84 |
|
85 | Bn.fromBuffer = function (buf, opts = { endian: 'big' }) {
|
86 | if (opts.endian === 'little') {
|
87 | buf = reverseBuf(buf)
|
88 | }
|
89 | const hex = buf.toString('hex')
|
90 | const bn = new Bn(hex, 16)
|
91 | return bn
|
92 | }
|
93 |
|
94 | Bn.prototype.fromBuffer = function (buf, opts) {
|
95 | const bn = Bn.fromBuffer(buf, opts)
|
96 | bn.copy(this)
|
97 |
|
98 | return this
|
99 | }
|
100 |
|
101 | Bn.prototype.toBuffer = function (opts = { size: undefined, endian: 'big' }) {
|
102 | let buf
|
103 | if (opts.size) {
|
104 | const hex = this.toString(16, 2)
|
105 | const natlen = hex.length / 2
|
106 | buf = Buffer.from(hex, 'hex')
|
107 |
|
108 | if (natlen === opts.size) {
|
109 |
|
110 | } else if (natlen > opts.size) {
|
111 | buf = buf.slice(natlen - buf.length, buf.length)
|
112 | } else if (natlen < opts.size) {
|
113 | const rbuf = Buffer.alloc(opts.size)
|
114 | for (let i = 0; i < buf.length; i++) {
|
115 | rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i]
|
116 | }
|
117 | for (let i = 0; i < opts.size - natlen; i++) {
|
118 | rbuf[i] = 0
|
119 | }
|
120 | buf = rbuf
|
121 | }
|
122 | } else {
|
123 | const hex = this.toString(16, 2)
|
124 | buf = Buffer.from(hex, 'hex')
|
125 | }
|
126 |
|
127 | if (opts.endian === 'little') {
|
128 | buf = reverseBuf(buf)
|
129 | }
|
130 | const longzero = Buffer.from([0])
|
131 | if (Buffer.compare(buf, longzero) === 0) {
|
132 | return Buffer.from([])
|
133 | }
|
134 | return buf
|
135 | }
|
136 |
|
137 | Bn.prototype.toFastBuffer = Bn.prototype.toBuffer
|
138 |
|
139 | Bn.fromFastBuffer = Bn.fromBuffer
|
140 | Bn.prototype.fromFastBuffer = Bn.prototype.fromBuffer
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 | Bn.prototype.fromSm = function (buf, opts = { endian: 'big' }) {
|
147 | if (buf.length === 0) {
|
148 | this.fromBuffer(Buffer.from([0]))
|
149 | }
|
150 |
|
151 | const endian = opts.endian
|
152 | if (endian === 'little') {
|
153 | buf = reverseBuf(buf)
|
154 | }
|
155 |
|
156 | if (buf[0] & 0x80) {
|
157 | buf[0] = buf[0] & 0x7f
|
158 | this.fromBuffer(buf)
|
159 | this.neg().copy(this)
|
160 | } else {
|
161 | this.fromBuffer(buf)
|
162 | }
|
163 | return this
|
164 | }
|
165 |
|
166 | Bn.prototype.toSm = function (opts = { endian: 'big' }) {
|
167 | const endian = opts.endian
|
168 |
|
169 | let buf
|
170 | if (this.cmp(0) === -1) {
|
171 | buf = this.neg().toBuffer()
|
172 | if (buf[0] & 0x80) {
|
173 | buf = Buffer.concat([Buffer.from([0x80]), buf])
|
174 | } else {
|
175 | buf[0] = buf[0] | 0x80
|
176 | }
|
177 | } else {
|
178 | buf = this.toBuffer()
|
179 | if (buf[0] & 0x80) {
|
180 | buf = Buffer.concat([Buffer.from([0x00]), buf])
|
181 | }
|
182 | }
|
183 |
|
184 | if ((buf.length === 1) & (buf[0] === 0)) {
|
185 | buf = Buffer.from([])
|
186 | }
|
187 |
|
188 | if (endian === 'little') {
|
189 | buf = reverseBuf(buf)
|
190 | }
|
191 |
|
192 | return buf
|
193 | }
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 | Bn.prototype.fromBits = function (bits, opts = { strict: false }) {
|
200 |
|
201 |
|
202 | let buf = Buffer.alloc(4)
|
203 | buf.writeUInt32BE(bits, 0)
|
204 | bits = buf.readInt32BE(0)
|
205 | if (opts.strict && bits & 0x00800000) {
|
206 | throw new Error('negative bit set')
|
207 | }
|
208 | const nsize = bits >> 24
|
209 | const nword = bits & 0x007fffff
|
210 | buf = Buffer.alloc(4)
|
211 | buf.writeInt32BE(nword)
|
212 | if (nsize <= 3) {
|
213 | buf = buf.slice(1, nsize + 1)
|
214 | } else {
|
215 | const fill = Buffer.alloc(nsize - 3)
|
216 | fill.fill(0)
|
217 | buf = Buffer.concat([buf, fill])
|
218 | }
|
219 | this.fromBuffer(buf)
|
220 | if (bits & 0x00800000) {
|
221 | Bn(0)
|
222 | .sub(this)
|
223 | .copy(this)
|
224 | }
|
225 | return this
|
226 | }
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 | Bn.prototype.toBits = function () {
|
233 | let buf
|
234 | if (this.lt(0)) {
|
235 | buf = this.neg().toBuffer()
|
236 | } else {
|
237 | buf = this.toBuffer()
|
238 | }
|
239 | let nsize = buf.length
|
240 | let nword
|
241 | if (nsize > 3) {
|
242 | nword = Buffer.concat([Buffer.from([0]), buf.slice(0, 3)]).readUInt32BE(0)
|
243 | } else if (nsize <= 3) {
|
244 | const blank = Buffer.alloc(3 - nsize + 1)
|
245 | blank.fill(0)
|
246 | nword = Buffer.concat([blank, buf.slice(0, nsize)]).readUInt32BE(0)
|
247 | }
|
248 | if (nword & 0x00800000) {
|
249 |
|
250 |
|
251 | nword >>= 8
|
252 | nsize++
|
253 | }
|
254 | if (this.lt(0)) {
|
255 | nword |= 0x00800000
|
256 | }
|
257 | const bits = (nsize << 24) | nword
|
258 |
|
259 | buf = Buffer.alloc(4)
|
260 | buf.writeInt32BE(bits, 0)
|
261 | return buf.readUInt32BE(0)
|
262 | }
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | Bn.prototype.fromScriptNumBuffer = function (
|
271 | buf,
|
272 | fRequireMinimal,
|
273 | nMaxNumSize
|
274 | ) {
|
275 | if (nMaxNumSize === undefined) {
|
276 | nMaxNumSize = 4
|
277 | }
|
278 | if (buf.length > nMaxNumSize) {
|
279 | throw new Error('script number overflow')
|
280 | }
|
281 | if (fRequireMinimal && buf.length > 0) {
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 | if ((buf[buf.length - 1] & 0x7f) === 0) {
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 | if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
|
295 | throw new Error('non-minimally encoded script number')
|
296 | }
|
297 | }
|
298 | }
|
299 | return this.fromSm(buf, { endian: 'little' })
|
300 | }
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 | Bn.prototype.toScriptNumBuffer = function (buf) {
|
307 | return this.toSm({ endian: 'little' })
|
308 | }
|
309 |
|
310 | Bn.prototype.neg = function () {
|
311 | const _neg = _Bn.prototype.neg.call(this)
|
312 | const neg = Object.create(Bn.prototype)
|
313 | _neg.copy(neg)
|
314 | return neg
|
315 | }
|
316 |
|
317 | Bn.prototype.add = function (bn) {
|
318 | const _bn = _Bn.prototype.add.call(this, bn)
|
319 | bn = Object.create(Bn.prototype)
|
320 | _bn.copy(bn)
|
321 | return bn
|
322 | }
|
323 |
|
324 | Bn.prototype.sub = function (bn) {
|
325 | const _bn = _Bn.prototype.sub.call(this, bn)
|
326 | bn = Object.create(Bn.prototype)
|
327 | _bn.copy(bn)
|
328 | return bn
|
329 | }
|
330 |
|
331 | Bn.prototype.mul = function (bn) {
|
332 | const _bn = _Bn.prototype.mul.call(this, bn)
|
333 | bn = Object.create(Bn.prototype)
|
334 | _bn.copy(bn)
|
335 | return bn
|
336 | }
|
337 |
|
338 |
|
339 |
|
340 |
|
341 | Bn.prototype.mod = function (bn) {
|
342 | const _bn = _Bn.prototype.mod.call(this, bn)
|
343 | bn = Object.create(Bn.prototype)
|
344 | _bn.copy(bn)
|
345 | return bn
|
346 | }
|
347 |
|
348 |
|
349 |
|
350 |
|
351 | Bn.prototype.umod = function (bn) {
|
352 | const _bn = _Bn.prototype.umod.call(this, bn)
|
353 | bn = Object.create(Bn.prototype)
|
354 | _bn.copy(bn)
|
355 | return bn
|
356 | }
|
357 |
|
358 | Bn.prototype.invm = function (bn) {
|
359 | const _bn = _Bn.prototype.invm.call(this, bn)
|
360 | bn = Object.create(Bn.prototype)
|
361 | _bn.copy(bn)
|
362 | return bn
|
363 | }
|
364 |
|
365 | Bn.prototype.div = function (bn) {
|
366 | const _bn = _Bn.prototype.div.call(this, bn)
|
367 | bn = Object.create(Bn.prototype)
|
368 | _bn.copy(bn)
|
369 | return bn
|
370 | }
|
371 |
|
372 | Bn.prototype.ushln = function (bits) {
|
373 | const _bn = _Bn.prototype.ushln.call(this, bits)
|
374 | const bn = Object.create(Bn.prototype)
|
375 | _bn.copy(bn)
|
376 | return bn
|
377 | }
|
378 |
|
379 | Bn.prototype.ushrn = function (bits) {
|
380 | const _bn = _Bn.prototype.ushrn.call(this, bits)
|
381 | const bn = Object.create(Bn.prototype)
|
382 | _bn.copy(bn)
|
383 | return bn
|
384 | }
|
385 |
|
386 | Bn.prototype.cmp = function (bn) {
|
387 | return _Bn.prototype.cmp.call(this, bn)
|
388 | }
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 | function decorate (name) {
|
397 | Bn.prototype['_' + name] = Bn.prototype[name]
|
398 | const f = function (b) {
|
399 | if (typeof b === 'string') {
|
400 | b = new Bn(b)
|
401 | } else if (typeof b === 'number') {
|
402 | b = new Bn(b.toString())
|
403 | }
|
404 | return this['_' + name](b)
|
405 | }
|
406 | Bn.prototype[name] = f
|
407 | }
|
408 |
|
409 | Bn.prototype.eq = function (b) {
|
410 | return this.cmp(b) === 0
|
411 | }
|
412 |
|
413 | Bn.prototype.neq = function (b) {
|
414 | return this.cmp(b) !== 0
|
415 | }
|
416 |
|
417 | Bn.prototype.gt = function (b) {
|
418 | return this.cmp(b) > 0
|
419 | }
|
420 |
|
421 | Bn.prototype.geq = function (b) {
|
422 | return this.cmp(b) >= 0
|
423 | }
|
424 |
|
425 | Bn.prototype.lt = function (b) {
|
426 | return this.cmp(b) < 0
|
427 | }
|
428 |
|
429 | Bn.prototype.leq = function (b) {
|
430 | return this.cmp(b) <= 0
|
431 | }
|
432 |
|
433 | decorate('add')
|
434 | decorate('sub')
|
435 | decorate('mul')
|
436 | decorate('mod')
|
437 | decorate('invm')
|
438 | decorate('div')
|
439 | decorate('cmp')
|
440 | decorate('gt')
|
441 | decorate('geq')
|
442 | decorate('lt')
|
443 | decorate('leq')
|
444 |
|
445 | export { Bn }
|