@btc-vision/btc-runtime 1.4.5 → 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,13 +19,13 @@ export class StoredU256Array {
19
19
  private _isChanged: Set<u64> = new Set(); // Set of slotIndexes that are modified
20
20
 
21
21
  // Internal variables for length and startIndex management
22
- private _length: u64 = 0; // Current length of the array
22
+ private _length: u64 = 0; // Current length of the array
23
23
  private _startIndex: u64 = 0; // Starting index of the array
24
- private _isChangedLength: bool = false; // Indicates if the length has been modified
25
- private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
24
+ private _isChangedLength: bool = false; // Indicates if the length has been modified
25
+ private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
26
26
 
27
27
  // Define a maximum allowed length to prevent excessive storage usage
28
- private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1); // we need to check what happen in overflow situation to be able to set it to u64.MAX_VALUE
28
+ private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1);
29
29
 
30
30
  /**
31
31
  * @constructor
@@ -52,21 +52,26 @@ export class StoredU256Array {
52
52
  this.lengthPointer = lengthPointer;
53
53
  this.baseU256Pointer = baseU256Pointer;
54
54
 
55
- this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length
55
+ this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length
56
56
  this._startIndex = storedLengthAndStartIndex.lo2; // Bytes 8-15: startIndex
57
57
  }
58
58
 
59
59
  /**
60
60
  * @method get
61
61
  * @description Retrieves the u256 value at the specified global index.
62
+ * Returns zero instead of reverting if the index is out of bounds.
62
63
  * @param {u64} index - The global index (0 to ∞) of the u256 value to retrieve.
63
- * @returns {u256} - The u256 value at the specified index.
64
+ * @returns {u256} - The u256 value at the specified index or zero if out of bounds.
64
65
  */
65
66
  @inline
66
67
  public get(index: u64): u256 {
67
- assert(index < this._length, 'Index out of bounds');
68
+ if (index > this.MAX_LENGTH) {
69
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
70
+ }
71
+
68
72
  const slotIndex: u32 = <u32>index;
69
73
  this.ensureValues(slotIndex);
74
+
70
75
  const value = this._values.get(slotIndex);
71
76
  return value ? value : u256.Zero;
72
77
  }
@@ -79,7 +84,10 @@ export class StoredU256Array {
79
84
  */
80
85
  @inline
81
86
  public set(index: u64, value: u256): void {
82
- assert(index < this._length, 'Index exceeds current array length');
87
+ if (index > this.MAX_LENGTH) {
88
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
89
+ }
90
+
83
91
  const slotIndex: u32 = <u32>index;
84
92
  this.ensureValues(slotIndex);
85
93
 
@@ -96,7 +104,7 @@ export class StoredU256Array {
96
104
  * @param {u256} value - The u256 value to append.
97
105
  */
98
106
  public push(value: u256): void {
99
- if (this._length >= this.MAX_LENGTH) {
107
+ if (this._length > this.MAX_LENGTH) {
100
108
  throw new Revert(
101
109
  'Push operation failed: Array has reached its maximum allowed length.',
102
110
  );
@@ -150,8 +158,8 @@ export class StoredU256Array {
150
158
  * @param {u64} index - The global index of the u256 value to delete.
151
159
  */
152
160
  public delete(index: u64): void {
153
- if (index >= this._length) {
154
- throw new Revert('Delete operation failed: Index out of bounds.');
161
+ if (index > this.MAX_LENGTH) {
162
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
155
163
  }
156
164
 
157
165
  const slotIndex: u32 = <u32>index;
@@ -164,42 +172,10 @@ export class StoredU256Array {
164
172
  }
165
173
  }
166
174
 
167
- /**
168
- * @method shift
169
- * @description Removes the first element of the array by setting it to zero, decrementing the length, and incrementing the startIndex.
170
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
171
- */
172
- public shift(): void {
173
- if (this._length === 0) {
174
- throw new Revert('Shift operation failed: Array is empty.');
175
- }
176
-
177
- const currentStartIndex: u64 = this._startIndex;
178
- const slotIndex: u32 = <u32>currentStartIndex;
179
- this.ensureValues(slotIndex);
180
-
181
- const currentValue = this._values.get(slotIndex);
182
- if (!u256.eq(currentValue, u256.Zero)) {
183
- this._values.set(slotIndex, u256.Zero);
184
- this._isChanged.add(slotIndex);
185
- }
186
-
187
- // Decrement the length
188
- this._length -= 1;
189
- this._isChangedLength = true;
190
-
191
- // Increment the startIndex with wrap-around
192
- if (this._startIndex < this.MAX_LENGTH - 1) {
193
- this._startIndex += 1;
194
- } else {
195
- this._startIndex = 0;
196
- }
197
- this._isChangedStartIndex = true;
198
- }
199
-
200
175
  /**
201
176
  * @method save
202
- * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots if any have been modified.
177
+ * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots
178
+ * if any have been modified.
203
179
  */
204
180
  public save(): void {
205
181
  // Save all changed slots
@@ -210,6 +186,7 @@ export class StoredU256Array {
210
186
  const value = this._values.get(slotIndex);
211
187
  Blockchain.setStorageAt(storagePointer, value);
212
188
  }
189
+
213
190
  this._isChanged.clear();
214
191
 
215
192
  // Save length and startIndex if changed
@@ -239,6 +216,7 @@ export class StoredU256Array {
239
216
  // Reset the length and startIndex to zero
240
217
  const zeroLengthAndStartIndex = u256.Zero;
241
218
  Blockchain.setStorageAt(this.lengthPointer, zeroLengthAndStartIndex);
219
+
242
220
  this._length = 0;
243
221
  this._startIndex = 0;
244
222
  this._isChangedLength = false;
@@ -272,7 +250,9 @@ export class StoredU256Array {
272
250
  */
273
251
  @inline
274
252
  public getAll(startIndex: u32, count: u32): u256[] {
275
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
253
+ if ((startIndex + count) > this._length) {
254
+ throw new Revert('Requested range exceeds array length');
255
+ }
276
256
  const result: u256[] = new Array<u256>(count);
277
257
  for (let i: u32 = 0; i < count; i++) {
278
258
  result[i] = this.get(<u64>(startIndex + i));
@@ -354,25 +334,6 @@ export class StoredU256Array {
354
334
  return this._startIndex;
355
335
  }
356
336
 
357
- /**
358
- * @method setLength
359
- * @description Sets the length of the array.
360
- * @param {u64} newLength - The new length to set.
361
- */
362
- public setLength(newLength: u64): void {
363
- if (newLength > this.MAX_LENGTH) {
364
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
365
- }
366
-
367
- if (newLength > this._startIndex) {
368
- this._startIndex = newLength;
369
- this._isChangedStartIndex = true;
370
- }
371
-
372
- this._length = newLength;
373
- this._isChangedLength = true;
374
- }
375
-
376
337
  /**
377
338
  * @private
378
339
  * @method ensureValues
@@ -65,11 +65,15 @@ export class StoredU32Array {
65
65
  */
66
66
  @inline
67
67
  public get(index: u64): u32 {
68
- assert(index < this._length, 'Index out of bounds');
68
+ if (index > this.MAX_LENGTH) {
69
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
70
+ }
69
71
 
70
72
  const slotIndex: u64 = index / 8; // Each slot holds 8 u32s
71
73
  const subIndex: u8 = <u8>(index % 8); // 0..7
74
+
72
75
  this.ensureValues(slotIndex);
76
+
73
77
  const slotValues = this._values.get(slotIndex);
74
78
  return slotValues ? slotValues[subIndex] : 0;
75
79
  }
@@ -82,7 +86,10 @@ export class StoredU32Array {
82
86
  */
83
87
  @inline
84
88
  public set(index: u64, value: u32): void {
85
- assert(index < this._length, 'Index exceeds current array length');
89
+ if (index > this.MAX_LENGTH) {
90
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
91
+ }
92
+
86
93
  const slotIndex: u64 = index / 8;
87
94
  const subIndex: u8 = <u8>(index % 8);
88
95
 
@@ -100,7 +107,7 @@ export class StoredU32Array {
100
107
  * @param {u32} value - The u32 value to append.
101
108
  */
102
109
  public push(value: u32): void {
103
- if (this._length >= this.MAX_LENGTH) {
110
+ if (this._length > this.MAX_LENGTH) {
104
111
  throw new Revert(
105
112
  'Push operation failed: Array has reached its maximum allowed length.',
106
113
  );
@@ -134,8 +141,8 @@ export class StoredU32Array {
134
141
  * @param {u64} index - The global index of the u32 value to delete.
135
142
  */
136
143
  public delete(index: u64): void {
137
- if (index >= this._length) {
138
- throw new Revert('Delete operation failed: Index out of bounds.');
144
+ if (index > this.MAX_LENGTH) {
145
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
139
146
  }
140
147
 
141
148
  const slotIndex: u64 = index / 8;
@@ -258,7 +265,9 @@ export class StoredU32Array {
258
265
  */
259
266
  @inline
260
267
  public getAll(startIndex: u64, count: u64): u32[] {
261
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
268
+ if ((startIndex + count) > this._length) {
269
+ throw new Revert('Requested range exceeds array length');
270
+ }
262
271
 
263
272
  if (u32.MAX_VALUE < count) {
264
273
  throw new Revert('Requested range exceeds maximum allowed value.');
@@ -344,25 +353,6 @@ export class StoredU32Array {
344
353
  return this._startIndex;
345
354
  }
346
355
 
347
- /**
348
- * @method setLength
349
- * @description Adjusts the length of the array (may truncate if newLength < currentLength).
350
- * @param {u64} newLength - The new length to set.
351
- */
352
- public setLength(newLength: u64): void {
353
- if (newLength > this.MAX_LENGTH) {
354
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
355
- }
356
-
357
- if (newLength > this._startIndex) {
358
- this._startIndex = newLength;
359
- this._isChangedStartIndex = true;
360
- }
361
-
362
- this._length = newLength;
363
- this._isChangedLength = true;
364
- }
365
-
366
356
  /**
367
357
  * @method deleteLast
368
358
  * @description Deletes the last element of the array by setting it to zero and decrementing the length.
@@ -63,11 +63,15 @@ export class StoredU8Array {
63
63
  */
64
64
  @inline
65
65
  public get(index: u64): u8 {
66
- assert(index < this._length, 'Index out of bounds');
66
+ if (index > this.MAX_LENGTH) {
67
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
68
+ }
67
69
 
68
70
  const slotIndex: u64 = index / 32; // Each slot holds thirty-two u8s
69
71
  const subIndex: u8 = <u8>(index % 32);
72
+
70
73
  this.ensureValues(slotIndex);
74
+
71
75
  const slotValues = this._values.get(slotIndex);
72
76
  return slotValues ? slotValues[subIndex] : 0;
73
77
  }
@@ -80,7 +84,9 @@ export class StoredU8Array {
80
84
  */
81
85
  @inline
82
86
  public set(index: u64, value: u8): void {
83
- assert(index < this._length, 'Index exceeds current array length');
87
+ if (index > this.MAX_LENGTH) {
88
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
89
+ }
84
90
 
85
91
  const slotIndex: u64 = index / 32;
86
92
  const subIndex: u8 = <u8>(index % 32);
@@ -99,7 +105,7 @@ export class StoredU8Array {
99
105
  * @param {u8} value - The u8 value to append.
100
106
  */
101
107
  public push(value: u8): void {
102
- if (this._length >= this.MAX_LENGTH) {
108
+ if (this._length > this.MAX_LENGTH) {
103
109
  throw new Revert(
104
110
  'Push operation failed: Array has reached its maximum allowed length.',
105
111
  );
@@ -130,8 +136,8 @@ export class StoredU8Array {
130
136
  * @param {u64} index - The global index of the u8 value to delete.
131
137
  */
132
138
  public delete(index: u64): void {
133
- if (index >= this._length) {
134
- throw new Revert('Delete operation failed: Index out of bounds.');
139
+ if (index > this.MAX_LENGTH) {
140
+ throw new Revert('Operation failed: Index exceeds maximum allowed value.');
135
141
  }
136
142
 
137
143
  const slotIndex: u64 = index / 32;
@@ -145,38 +151,6 @@ export class StoredU8Array {
145
151
  }
146
152
  }
147
153
 
148
- /**
149
- * @method shift
150
- * @description Removes the first element of the array by setting it to zero, decrementing the length,
151
- * and incrementing the startIndex (with wrap-around if needed).
152
- */
153
- public shift(): void {
154
- if (this._length === 0) {
155
- throw new Revert('Shift operation failed: Array is empty.');
156
- }
157
-
158
- const currentStartIndex: u64 = this._startIndex;
159
- const slotIndex: u64 = currentStartIndex / 32;
160
- const subIndex: u8 = <u8>(currentStartIndex % 32);
161
- this.ensureValues(slotIndex);
162
-
163
- const slotValues = this._values.get(slotIndex);
164
- if (slotValues && slotValues[subIndex] !== 0) {
165
- slotValues[subIndex] = 0;
166
- this._isChanged.add(slotIndex);
167
- }
168
-
169
- this._length -= 1;
170
- this._isChangedLength = true;
171
-
172
- if (this._startIndex < this.MAX_LENGTH - 1) {
173
- this._startIndex += 1;
174
- } else {
175
- this._startIndex = 0;
176
- }
177
- this._isChangedStartIndex = true;
178
- }
179
-
180
154
  /**
181
155
  * @method save
182
156
  * @description Persists all cached u8 values, the length, and the startIndex to their respective storage slots if any have been modified.
@@ -251,7 +225,10 @@ export class StoredU8Array {
251
225
  */
252
226
  @inline
253
227
  public getAll(startIndex: u64, count: u64): u8[] {
254
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
228
+ if ((startIndex + count) > this._length) {
229
+ throw new Revert('Requested range exceeds array length');
230
+ }
231
+
255
232
  if (u32.MAX_VALUE < count) {
256
233
  throw new Revert('Requested range exceeds maximum allowed value.');
257
234
  }
@@ -335,26 +312,6 @@ export class StoredU8Array {
335
312
  return this._startIndex;
336
313
  }
337
314
 
338
- /**
339
- * @method setLength
340
- * @description Sets the length of the array.
341
- * @param {u64} newLength - The new length to set.
342
- */
343
- public setLength(newLength: u64): void {
344
- if (newLength > this.MAX_LENGTH) {
345
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
346
- }
347
-
348
- // If newLength is bigger than _startIndex, adjust startIndex
349
- if (newLength > this._startIndex) {
350
- this._startIndex = newLength;
351
- this._isChangedStartIndex = true;
352
- }
353
-
354
- this._length = newLength;
355
- this._isChangedLength = true;
356
- }
357
-
358
315
  /**
359
316
  * @method deleteLast
360
317
  * @description Removes the last element of the array by setting it to zero and decrementing the length.
@@ -1,7 +1,6 @@
1
1
  import { Potential } from '../lang/Definitions';
2
- import { decodeHexArray, encodeHexFromBuffer } from '../utils';
2
+ import { ADDRESS_BYTE_LENGTH, decodeHexArray, encodeHexFromBuffer } from '../utils';
3
3
  import { bech32m as _bech32m, toWords } from '../utils/b32';
4
- import { ADDRESS_BYTE_LENGTH } from '../utils/lengths';
5
4
 
6
5
  @final
7
6
  export class Address extends Uint8Array {
@@ -80,15 +80,30 @@ export class SafeMath {
80
80
 
81
81
  while (!r.isZero()) {
82
82
  const quotient = SafeMath.div(old_r, r);
83
- const r_copy = r;
84
- r = SafeMath.sub(old_r, SafeMath.mul(quotient, r));
85
- old_r = r_copy;
86
83
 
87
- const s_copy = s;
88
- s = SafeMath.sub(old_s, SafeMath.mul(quotient, s));
89
- old_s = s_copy;
84
+ // --- Update r ---
85
+ {
86
+ // old_r - (quotient * r)
87
+ const tmp = r;
88
+ r = u256.sub(old_r, u256.mul(quotient, r)); // unchecked subtract
89
+ old_r = tmp;
90
+ }
91
+
92
+ // --- Update s ---
93
+ {
94
+ // old_s - (quotient * s)
95
+ const tmp = s;
96
+ s = u256.sub(old_s, u256.mul(quotient, s)); // unchecked subtract
97
+ old_s = tmp;
98
+ }
90
99
  }
91
100
 
101
+ // At this point, `old_r` is the gcd(k, p). If gcd != 1 => no inverse
102
+ // (in a prime field p, gcd=1 if k != 0).
103
+ // We could enforce this by checking `old_r == 1` but we'll leave it to the caller.
104
+
105
+ // The extended Euclidean algorithm says `old_s` is the inverse (possibly negative),
106
+ // so we reduce mod p
92
107
  return SafeMath.mod(old_s, p);
93
108
  }
94
109
 
@@ -248,52 +263,48 @@ export class SafeMath {
248
263
 
249
264
  @unsafe
250
265
  public static shl(value: u256, shift: i32): u256 {
251
- if (shift == 0) {
252
- return value.clone();
266
+ // If shift <= 0, no left shift needed (shift=0 => return clone, shift<0 => treat as 0).
267
+ if (shift <= 0) {
268
+ return shift == 0 ? value.clone() : new u256(); // or just return value if shift<0 is invalid
253
269
  }
254
270
 
255
- const totalBits = 256;
256
- const bitsPerSegment = 64;
271
+ // If shift >= 256, the result is zero
272
+ if (shift >= 256) {
273
+ return new u256();
274
+ }
257
275
 
258
- // Normalize shift to be within 0-255 range
276
+ // Now shift is in [1..255]. Masking is optional for clarity:
259
277
  shift &= 255;
260
278
 
261
- if (shift >= totalBits) {
262
- return new u256(); // Shift size larger than width results in zero
263
- }
264
-
265
- // Determine how many full 64-bit segments we are shifting
279
+ const bitsPerSegment = 64;
266
280
  const segmentShift = (shift / bitsPerSegment) | 0;
267
281
  const bitShift = shift % bitsPerSegment;
268
282
 
269
283
  const segments = [value.lo1, value.lo2, value.hi1, value.hi2];
270
284
  const result = SafeMath.shlSegment(segments, segmentShift, bitShift, bitsPerSegment, 4);
271
-
272
285
  return new u256(result[0], result[1], result[2], result[3]);
273
286
  }
274
287
 
275
288
  public static shl128(value: u128, shift: i32): u128 {
276
- if (shift == 0) {
277
- return value.clone();
289
+ if (shift <= 0) {
290
+ return shift == 0 ? value.clone() : new u128();
278
291
  }
279
292
 
280
- const totalBits = 256;
281
- const bitsPerSegment = 64;
293
+ // Here the total bit width is 128, so shifting >= 128 bits => zero
294
+ if (shift >= 128) {
295
+ return new u128();
296
+ }
282
297
 
283
- // Normalize shift to be within 0-255 range
284
- shift &= 255;
298
+ // Mask to 0..127
299
+ shift &= 127;
285
300
 
286
- if (shift >= totalBits) {
287
- return new u128(); // Shift size larger than width results in zero
288
- }
301
+ const bitsPerSegment = 64;
289
302
 
290
- // Determine how many full 64-bit segments we are shifting
291
303
  const segmentShift = (shift / bitsPerSegment) | 0;
292
304
  const bitShift = shift % bitsPerSegment;
293
305
 
294
306
  const segments = [value.lo, value.hi];
295
307
  const result = SafeMath.shlSegment(segments, segmentShift, bitShift, bitsPerSegment, 2);
296
-
297
308
  return new u128(result[0], result[1]);
298
309
  }
299
310
 
@@ -369,9 +380,26 @@ export class SafeMath {
369
380
  * @returns The incremented value
370
381
  */
371
382
  static inc(value: u256): u256 {
383
+ if (u256.eq(value, u256.Max)) {
384
+ throw new Error('SafeMath: increment overflow');
385
+ }
386
+
372
387
  return value.preInc();
373
388
  }
374
389
 
390
+ /**
391
+ * Decrement a u256 value by 1
392
+ * @param value The value to decrement
393
+ * @returns The decremented value
394
+ */
395
+ public static dec(value: u256): u256 {
396
+ if (u256.eq(value, u256.Zero)) {
397
+ throw new Error('SafeMath: decrement overflow');
398
+ }
399
+
400
+ return value.preDec();
401
+ }
402
+
375
403
  /**
376
404
  * Approximates the binary logarithm (log2) of a u256 integer.
377
405
  * @param x - The input value for which to calculate log2(x).
@@ -96,6 +96,10 @@ export class SafeMathI128 {
96
96
  * Increment an i128 by 1 with overflow check.
97
97
  */
98
98
  public static inc(value: i128): i128 {
99
+ if (value == SafeMathI128.MAX) {
100
+ throw new Error('SafeMathI128: inc overflow');
101
+ }
102
+
99
103
  return SafeMathI128.add(value, SafeMathI128.ONE);
100
104
  }
101
105
 
@@ -103,6 +107,10 @@ export class SafeMathI128 {
103
107
  * Decrement an i128 by 1 with underflow check.
104
108
  */
105
109
  public static dec(value: i128): i128 {
110
+ if (value == SafeMathI128.MIN) {
111
+ throw new Error('SafeMathI128: dec underflow');
112
+ }
113
+
106
114
  return SafeMathI128.sub(value, SafeMathI128.ONE);
107
115
  }
108
116
 
@@ -1,55 +0,0 @@
1
- let random_state0_64: u64;
2
- let random_state1_64: u64;
3
- let random_state0_32: u32;
4
- let random_state1_32: u32;
5
- let random_seeded = false;
6
-
7
- function murmurHash3(h: u64): u64 {
8
- // Force all bits of a hash block to avalanche
9
- h ^= h >> 33; // see: https://github.com/aappleby/smhasher
10
- // eslint-disable-next-line no-loss-of-precision
11
- h *= 0xff51afd7ed558ccd;
12
- h ^= h >> 33;
13
- // eslint-disable-next-line no-loss-of-precision
14
- h *= 0xc4ceb9fe1a85ec53;
15
- h ^= h >> 33;
16
- return h;
17
- }
18
-
19
- function splitMix32(h: u32): u32 {
20
- h += 0x6d2b79f5;
21
- h = (h ^ (h >> 15)) * (h | 1);
22
- h ^= h + (h ^ (h >> 7)) * (h | 61);
23
- return h ^ (h >> 14);
24
- }
25
-
26
- function seedRandom(value: i64): void {
27
- // Instead zero seed use golden ratio:
28
- // phi = (1 + sqrt(5)) / 2
29
- // trunc(2^64 / phi) = 0x9e3779b97f4a7c15
30
-
31
- // eslint-disable-next-line no-loss-of-precision
32
- if (value == 0) value = 0x9e3779b97f4a7c15;
33
- random_state0_64 = murmurHash3(value);
34
- random_state1_64 = murmurHash3(~random_state0_64);
35
- random_state0_32 = splitMix32(<u32>value);
36
- random_state1_32 = splitMix32(random_state0_32);
37
- random_seeded = true;
38
- }
39
-
40
- /**
41
- * Safe deterministic random number generator
42
- * @param {u64} seed - The seed to use
43
- */
44
- export function randomU64(seed: i64): u64 {
45
- if (!random_seeded) seedRandom(seed);
46
- let s1 = random_state0_64;
47
- const s0 = random_state1_64;
48
- random_state0_64 = s0;
49
- s1 ^= s1 << 23;
50
- s1 ^= s1 >> 17;
51
- s1 ^= s0;
52
- s1 ^= s0 >> 26;
53
- random_state1_64 = s1;
54
- return s0;
55
- }