Skip to content

Commit a56001b

Browse files
fix: shift with BigInt instead of JS number (#7703)
Co-authored-by: Begoña Álvarez de la Cruz <[email protected]>
1 parent c9559f0 commit a56001b

File tree

1 file changed

+20
-106
lines changed

1 file changed

+20
-106
lines changed

packages/shared/lib/core/layer-2/classes/special-stream.class.ts

Lines changed: 20 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -46,127 +46,41 @@ export class ReadSpecialStream extends ReadStream {
4646
}
4747
}
4848

49-
function shiftRight(s: bigint, n: bigint): bigint {
50-
const result = BigInteger(s).divide(BigInteger(2).pow(BigInteger(n)))
51-
return BigInt(result.toString())
49+
function shiftRight(n: bigint, shift: bigint): bigint {
50+
return n >> shift
5251
}
53-
// from https://github.com/iotaledger/wasp/blob/12845adea4fc097813a30a061853af4a43407d3c/packages/util/rwutil/convert.go#L113
52+
5453
function size64Encode(n: bigint): Buffer {
55-
if (n < BigInt(0x80)) {
56-
return Buffer.from([Number(n)])
57-
} else if (n < BigInt(0x4000)) {
58-
return Buffer.from([Number(n | BigInt(0x80)), Number(shiftRight(n, BigInt(7)))])
59-
} else if (n < BigInt(0x20_0000)) {
60-
return Buffer.from([
61-
Number(n | BigInt(0x80)),
62-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
63-
Number(shiftRight(n, BigInt(14))),
64-
])
65-
} else if (n < BigInt(0x1000_0000)) {
66-
return Buffer.from([
67-
Number(n | BigInt(0x80)),
68-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
69-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
70-
Number(shiftRight(n, BigInt(21))),
71-
])
72-
} else if (n < BigInt(0x8_0000_0000)) {
73-
return Buffer.from([
74-
Number(n | BigInt(0x80)),
75-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
76-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
77-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
78-
Number(shiftRight(n, BigInt(28))),
79-
])
80-
} else if (n < BigInt(0x400_0000_0000)) {
81-
return Buffer.from([
82-
Number(n | BigInt(0x80)),
83-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
84-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
85-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
86-
Number(shiftRight(n, BigInt(28)) | BigInt(0x80)),
87-
Number(shiftRight(n, BigInt(35))),
88-
])
89-
} else if (n < BigInt(0x2_0000_0000_0000)) {
90-
return Buffer.from([
91-
Number(n | BigInt(0x80)),
92-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
93-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
94-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
95-
Number(shiftRight(n, BigInt(28)) | BigInt(0x80)),
96-
Number(shiftRight(n, BigInt(35)) | BigInt(0x80)),
97-
Number(shiftRight(n, BigInt(42))),
98-
])
99-
} else if (n < BigInt(0x100_0000_0000_0000)) {
100-
return Buffer.from([
101-
Number(n | BigInt(0x80)),
102-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
103-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
104-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
105-
Number(shiftRight(n, BigInt(28)) | BigInt(0x80)),
106-
Number(shiftRight(n, BigInt(35)) | BigInt(0x80)),
107-
Number(shiftRight(n, BigInt(42)) | BigInt(0x80)),
108-
Number(shiftRight(n, BigInt(49))),
109-
])
110-
} else if (n < BigInt(0x8000_0000_0000_0000)) {
111-
return Buffer.from([
112-
Number(n | BigInt(0x80)),
113-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
114-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
115-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
116-
Number(shiftRight(n, BigInt(28)) | BigInt(0x80)),
117-
Number(shiftRight(n, BigInt(35)) | BigInt(0x80)),
118-
Number(shiftRight(n, BigInt(42)) | BigInt(0x80)),
119-
Number(shiftRight(n, BigInt(49)) | BigInt(0x80)),
120-
Number(shiftRight(n, BigInt(56))),
121-
])
122-
} else {
123-
return Buffer.from([
124-
Number(n | BigInt(0x80)),
125-
Number(shiftRight(n, BigInt(7)) | BigInt(0x80)),
126-
Number(shiftRight(n, BigInt(14)) | BigInt(0x80)),
127-
Number(shiftRight(n, BigInt(21)) | BigInt(0x80)),
128-
Number(shiftRight(n, BigInt(28)) | BigInt(0x80)),
129-
Number(shiftRight(n, BigInt(35)) | BigInt(0x80)),
130-
Number(shiftRight(n, BigInt(42)) | BigInt(0x80)),
131-
Number(shiftRight(n, BigInt(49)) | BigInt(0x80)),
132-
Number(shiftRight(n, BigInt(56)) | BigInt(0x80)),
133-
Number(shiftRight(n, BigInt(63))),
134-
])
54+
const parts: number[] = []
55+
while (n >= 0x80) {
56+
parts.push(Number((n & BigInt(0x7f)) | BigInt(0x80)))
57+
n = shiftRight(n, BigInt(7))
13558
}
59+
parts.push(Number(n)) // Last byte, without the continuation bit
60+
61+
return Buffer.from(parts)
13662
}
13763

138-
// Adapted from WASP golang implementation https://github.com/iotaledger/wasp/blob/7f880a7983d24d0dcd225e994d67b29741b318bc/packages/util/rwutil/convert.go#L76
13964
function size64Decode(readByte: () => number): [bigint, null | Error] {
14065
let byte = readByte()
141-
142-
if (!byte) {
143-
return [BigInt(0), new Error('no more bytes')]
144-
}
145-
14666
if (byte < 0x80) {
14767
return [BigInt(byte), null]
14868
}
14969

150-
let value = BigInt(byte) & BigInt(0x7f)
151-
152-
for (let shift = 7; shift < 63; shift += 7) {
70+
let value = BigInt(byte & 0x7f)
71+
let shift = 7
72+
while (shift < 64) {
15373
byte = readByte()
154-
if (!byte) {
155-
return [BigInt(0), new Error('no more bytes')]
74+
if (byte === -1) {
75+
// Assuming -1 signifies end of data or error in readByte
76+
return [BigInt(0), new Error('Unexpected end of data')]
15677
}
78+
value |= BigInt(byte & 0x7f) << BigInt(shift)
15779
if (byte < 0x80) {
158-
return [value | (BigInt(byte) << BigInt(shift)), null]
80+
return [value, null]
15981
}
160-
value |= (BigInt(byte) & BigInt(0x7f)) << BigInt(shift)
161-
}
162-
163-
byte = readByte()
164-
if (!byte) {
165-
return [BigInt(0), new Error('no more bytes')]
166-
}
167-
if (byte > 0x01) {
168-
return [BigInt(0), new Error('size64 overflow')]
82+
shift += 7
16983
}
17084

171-
return [value | (BigInt(byte) << BigInt(63)), null]
85+
return [BigInt(0), new Error('size64 overflow')]
17286
}

0 commit comments

Comments
 (0)