- Kind
- Pure package
- Name
- v1
- Namespace
- gnoswap / int256
- Exported functions
- n/a — not supported for pure packages by the node (vm/qfuncs)
- Module
- gno.land/p/gnoswap/int256/v1
- gno
- 0.9
1package int25623import (4 "encoding/binary"5 "math"6 "math/bits"78
not supported for pure packages by the node (vm/qfuncs)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
u256 "gno.land/p/gnoswap/uint256/v1"
9)
10
11type Int [4]uint64
12
13// Zero returns a fresh Int whose 256 bits are all zero.
14//
15// Returns:
16// - zero: A mutable *Int representing the signed value 0.
17func Zero() *Int {
18 return &Int{}
19}
20
21// One returns a fresh Int representing the signed value 1.
22//
23// Returns:
24// - one: A mutable *Int with only its least-significant bit set.
25func One() *Int {
26 return &Int{1, 0, 0, 0}
27}
28
29// MinInt256 returns the minimum signed 256-bit integer, -2^255.
30//
31// Returns:
32// - minimum: A fresh *Int containing the two's-complement minimum value.
33func MinInt256() *Int {
34 return &Int{0, 0, 0, 0x8000000000000000}
35}
36
37// MaxInt256 returns the maximum signed 256-bit integer, 2^255 - 1.
38//
39// Returns:
40// - maximum: A fresh *Int containing the largest positive int256 value.
41func MaxInt256() *Int {
42 return &Int{0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff}
43}
44
45// NewInt constructs a signed 256-bit integer from an int64.
46//
47// Parameters:
48// - val: Signed 64-bit value to sign-extend into 256 bits.
49//
50// Returns:
51// - value: A fresh *Int representing val.
52func NewInt(val int64) *Int {
53 z := &Int{}
54 z.SetInt64(val)
55 return z
56}
57
58// Set copies the complete 256-bit value from x into z.
59//
60// Parameters:
61// - x: Source Int whose four limbs are copied.
62//
63// Returns:
64// - z: The receiver after copying x.
65func (z *Int) Set(x *Int) *Int {
66 z[0], z[1], z[2], z[3] = x[0], x[1], x[2], x[3]
67 return z
68}
69
70// SetInt64 assigns x to z with two's-complement sign extension.
71//
72// Parameters:
73// - x: Signed 64-bit value to store.
74//
75// Returns:
76// - z: The receiver representing x as an Int.
77func (z *Int) SetInt64(x int64) *Int {
78 if x >= 0 {
79 z[3], z[2], z[1], z[0] = 0, 0, 0, uint64(x)
80 return z
81 }
82
83 z[3], z[2], z[1], z[0] = 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, uint64(x)
84 return z
85}
86
87// IsInt64 reports whether z can be represented exactly as a signed int64.
88//
89// Returns:
90// - fits: True when z is in [math.MinInt64, math.MaxInt64], false otherwise.
91func (z *Int) IsInt64() bool {
92 return ((z[1]|z[2]|z[3]) == 0 && z[0] <= 0x7fffffffffffffff) || // zero or positive int64
93 ((z[1]&z[2]&z[3]) == 0xffffffffffffffff && z[0] >= 0x8000000000000000) // negative int64
94}
95
96// Int64 converts z to int64 after checking its signed range.
97//
98// Returns:
99// - value: z's exact signed 64-bit value.
100//
101// Panics if z is outside the signed int64 range.
102func (z *Int) Int64() int64 {
103 if !z.IsInt64() {
104 panic("int256: int64 overflow")
105 }
106 s := z.Sign()
107 if s == 0 {
108 return 0
109 }
110 if s > 0 {
111 // overflow when z[0] > math.MaxInt64
112 return int64(z[0])
113 }
114 // -(2^64 - z[0])
115 return -int64(math.MaxUint64 - z[0] + 1)
116}
117
118// SetUint64 assigns the non-negative uint64 x to z, clearing its upper limbs.
119//
120// Parameters:
121// - x: Unsigned 64-bit value to store.
122//
123// Returns:
124// - z: The receiver representing x as a non-negative Int.
125func (z *Int) SetUint64(x uint64) *Int {
126 z[3], z[2], z[1], z[0] = 0, 0, 0, x
127 return z
128}
129
130// IsUint64 reports whether z fits in an unsigned 64-bit word.
131//
132// Returns:
133// - fits: True when all three upper 64-bit limbs of z are zero.
134func (z *Int) IsUint64() bool {
135 return (z[1] | z[2] | z[3]) == 0
136}
137
138// Uint64 converts z to uint64 when its upper 192 bits are zero.
139//
140// Returns:
141// - value: z's exact unsigned 64-bit value.
142//
143// Panics if any upper limb of z is non-zero.
144func (z *Int) Uint64() uint64 {
145 if !z.IsUint64() {
146 panic("int256: uint64 overflow")
147 }
148 return z[0]
149}
150
151// Abs returns the unsigned magnitude of z.
152//
153// Returns:
154// - magnitude: A *u256.Uint containing |z|; negative values are negated before conversion.
155//
156// Panics for MinInt256 because NegOverflow cannot represent its positive magnitude as Int.
157func (z *Int) Abs() *u256.Uint {
158 if z.IsNeg() {
159 neg := new(Int).NegOverflow(z)
160 return &u256.Uint{neg[0], neg[1], neg[2], neg[3]}
161 }
162 return &u256.Uint{z[0], z[1], z[2], z[3]}
163}
164
165// Sign reports the signed sign of z.
166//
167// Returns:
168// - sign: -1 for negative z, 0 for zero z, or 1 for positive z.
169func (z *Int) Sign() int {
170 if z.IsZero() {
171 return 0
172 }
173 if z[3]&0x8000000000000000 == 0 {
174 return 1
175 }
176 return -1
177}
178
179// IsZero reports whether every limb of z is zero.
180//
181// Returns:
182// - isZero: True exactly when z represents the signed value 0.
183func (z *Int) IsZero() bool {
184 return (z[0] | z[1] | z[2] | z[3]) == 0
185}
186
187// IsOne reports whether z represents the signed value 1.
188//
189// Returns:
190// - isOne: True exactly when the low limb is 1 and all upper limbs are zero.
191func (z *Int) IsOne() bool {
192 return (z[0] == 1) && (z[1]|z[2]|z[3]) == 0
193}
194
195// IsNeg reports whether z has its signed two's-complement sign bit set.
196//
197// Returns:
198// - isNegative: True when z is negative, including MinInt256.
199func (z *Int) IsNeg() bool {
200 return z[3]&0x8000000000000000 != 0
201}
202
203// IsPositive reports whether z is strictly greater than zero.
204//
205// Returns:
206// - isPositive: True when the sign bit is clear and at least one value bit is set.
207func (z *Int) IsPositive() bool {
208 return (z[3]&0x8000000000000000) == 0 && (z[3]|z[2]|z[1]|z[0]) != 0
209}
210
211// IsMinI256 reports whether z equals MinInt256.
212//
213// Returns:
214// - isMinimum: True only for the bit pattern 0x8000...0000.
215func (z *Int) IsMinI256() bool {
216 return (z[3] == 0x8000000000000000) && ((z[2] | z[1] | z[0]) == 0)
217}
218
219// NegOverflow computes the two's-complement negation of x and rejects the
220// one value whose positive magnitude is outside signed int256.
221//
222// Parameters:
223// - x: Signed 256-bit value to negate.
224//
225// Returns:
226// - z: The receiver containing -x.
227//
228// Panics when x is MinInt256.
229func (z *Int) NegOverflow(x *Int) *Int {
230 if x[3] == 0x8000000000000000 && x[2] == 0 && x[1] == 0 && x[0] == 0 {
231 panic("int256: overflow")
232 }
233
234 return z.Neg(x)
235}
236
237// Neg computes the two's-complement negation of x modulo 2^256.
238//
239// Parameters:
240// - x: 256-bit value whose bits are complemented and incremented.
241//
242// Returns:
243// - z: The receiver containing the wrapped negation of x.
244func (z *Int) Neg(x *Int) *Int {
245 var carry uint64
246 z[0], z[1], z[2], z[3] = ^x[0], ^x[1], ^x[2], ^x[3]
247 z[0], carry = bits.Add64(z[0], 1, 0)
248 z[1], carry = bits.Add64(z[1], 0, carry)
249 z[2], carry = bits.Add64(z[2], 0, carry)
250 z[3] += carry
251 return z
252}
253
254// Eq reports whether z and x have identical 256-bit representations.
255//
256// Parameters:
257// - x: Int to compare with z.
258//
259// Returns:
260// - equal: True when all four limbs match.
261func (z *Int) Eq(x *Int) bool {
262 return (z[0] == x[0]) && (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3])
263}
264
265// Neq reports whether z and x have different 256-bit representations.
266//
267// Parameters:
268// - x: Int to compare with z.
269//
270// Returns:
271// - different: True when at least one limb differs.
272func (z *Int) Neq(x *Int) bool {
273 return !z.Eq(x)
274}
275
276// Add adds x and y modulo 2^256.
277//
278// Parameters:
279// - x: First signed 256-bit addend.
280// - y: Second signed 256-bit addend.
281//
282// Returns:
283// - z: The receiver containing the low 256 bits of x + y.
284func (z *Int) Add(x, y *Int) *Int {
285 var carry uint64
286 z[0], carry = bits.Add64(x[0], y[0], 0)
287 z[1], carry = bits.Add64(x[1], y[1], carry)
288 z[2], carry = bits.Add64(x[2], y[2], carry)
289 z[3] = x[3] + y[3] + carry
290 return z
291}
292
293// AddOverflow adds x and y modulo 2^256 and reports signed overflow.
294//
295// Parameters:
296// - x: First signed 256-bit addend.
297// - y: Second signed 256-bit addend.
298//
299// Returns:
300// - z: The wrapped 256-bit sum.
301// - overflow: True when x and y have the same sign but the wrapped sum has the opposite sign.
302func (z *Int) AddOverflow(x, y *Int) (*Int, bool) {
303 var carry uint64
304 z[0], carry = bits.Add64(x[0], y[0], 0)
305 z[1], carry = bits.Add64(x[1], y[1], carry)
306 z[2], carry = bits.Add64(x[2], y[2], carry)
307 z[3] = x[3] + y[3] + carry
308 var overflow bool
309 signX, signY, signZ := x.Sign(), y.Sign(), z.Sign()
310 if (signX == signY) && (signX != signZ) {
311 overflow = true
312 }
313 return z, overflow
314}
315
316// Sub subtracts y from x modulo 2^256.
317//
318// Parameters:
319// - x: Signed 256-bit minuend.
320// - y: Signed 256-bit subtrahend.
321//
322// Returns:
323// - z: The receiver containing the low 256 bits of x - y.
324func (z *Int) Sub(x, y *Int) *Int {
325 var carry uint64
326 z[0], carry = bits.Sub64(x[0], y[0], 0)
327 z[1], carry = bits.Sub64(x[1], y[1], carry)
328 z[2], carry = bits.Sub64(x[2], y[2], carry)
329 z[3] = x[3] - y[3] - carry
330 return z
331}
332
333// SubOverflow subtracts y from x modulo 2^256 and reports signed overflow.
334//
335// Parameters:
336// - x: Signed 256-bit minuend.
337// - y: Signed 256-bit subtrahend.
338//
339// Returns:
340// - z: The wrapped 256-bit difference.
341// - overflow: True when the mathematical signed difference is outside the int256 range.
342func (z *Int) SubOverflow(x, y *Int) (*Int, bool) {
343 var carry uint64
344 z[0], carry = bits.Sub64(x[0], y[0], 0)
345 z[1], carry = bits.Sub64(x[1], y[1], carry)
346 z[2], carry = bits.Sub64(x[2], y[2], carry)
347 z[3] = x[3] - y[3] - carry
348 var overflow bool
349 signX, signY, signZ := x.Sign(), y.Sign(), z.Sign()
350 if (signX == 0 && y.IsMinI256()) || ((signX != 0) && (signX != signY) && (signX != signZ)) {
351 overflow = true
352 }
353 return z, overflow
354}
355
356// Mul multiplies x and y modulo 2^256.
357//
358// Parameters:
359// - x: First signed 256-bit factor.
360// - y: Second signed 256-bit factor.
361//
362// Returns:
363// - z: The receiver containing the low 256 bits of x * y.
364func (z *Int) Mul(x, y *Int) *Int {
365 var (
366 res Int
367 carry uint64
368 res1, res2, res3 uint64
369 )
370
371 carry, res[0] = bits.Mul64(x[0], y[0])
372 carry, res1 = umulHop(carry, x[1], y[0])
373 carry, res2 = umulHop(carry, x[2], y[0])
374 res3 = x[3]*y[0] + carry
375
376 carry, res[1] = umulHop(res1, x[0], y[1])
377 carry, res2 = umulStep(res2, x[1], y[1], carry)
378 res3 = res3 + x[2]*y[1] + carry
379
380 carry, res[2] = umulHop(res2, x[0], y[2])
381 res3 = res3 + x[1]*y[2] + carry
382
383 res[3] = res3 + x[0]*y[3]
384
385 return z.Set(&res)
386}
387
388// MulOverflow multiplies x and y and reports whether the signed product exceeds int256.
389// The returned value is still the wrapped low 256-bit product.
390//
391// Parameters:
392// - x: First signed 256-bit factor.
393// - y: Second signed 256-bit factor.
394//
395// Returns:
396// - z: The low 256 bits of the signed product, with its sign restored.
397// - overflow: True when the mathematical product is outside [-2^255, 2^255 - 1].
398func (z *Int) MulOverflow(x, y *Int) (*Int, bool) {
399 if (x.IsMinI256() && y.IsOne()) || (x.IsOne() && y.IsMinI256()) {
400 return z.Set(MinInt256()), false
401 }
402
403 var flipSign bool
404 xSign, ySign := x.Sign(), y.Sign()
405 if xSign*ySign == -1 {
406 flipSign = true
407 }
408
409 xCopy := x.Clone()
410 yCopy := y.Clone()
411
412 if xSign < 0 {
413 xCopy.Neg(xCopy)
414 }
415 if ySign < 0 {
416 yCopy.Neg(yCopy)
417 }
418
419 p := umul(xCopy, yCopy)
420 z[0], z[1], z[2], z[3] = p[0], p[1], p[2], p[3]
421
422 var overflow bool
423 if (p[4] | p[5] | p[6] | p[7]) != 0 {
424 overflow = true
425 } else if z.IsNeg() {
426 // The 256th bit is set, which means the absolute value is >= 2^255
427 // This is only valid if the result should be exactly -2^255
428 if !flipSign || !z.IsMinI256() {
429 overflow = true
430 }
431 }
432
433 if flipSign {
434 z.Neg(z)
435 }
436
437 return z, overflow
438}
439
440func umul(x, y *Int) [8]uint64 {
441 var (
442 res [8]uint64
443 carry, carry4, carry5, carry6 uint64
444 res1, res2, res3, res4, res5 uint64
445 )
446
447 carry, res[0] = bits.Mul64(x[0], y[0])
448 carry, res1 = umulHop(carry, x[1], y[0])
449 carry, res2 = umulHop(carry, x[2], y[0])
450 carry4, res3 = umulHop(carry, x[3], y[0])
451
452 carry, res[1] = umulHop(res1, x[0], y[1])
453 carry, res2 = umulStep(res2, x[1], y[1], carry)
454 carry, res3 = umulStep(res3, x[2], y[1], carry)
455 carry5, res4 = umulStep(carry4, x[3], y[1], carry)
456
457 carry, res[2] = umulHop(res2, x[0], y[2])
458 carry, res3 = umulStep(res3, x[1], y[2], carry)
459 carry, res4 = umulStep(res4, x[2], y[2], carry)
460 carry6, res5 = umulStep(carry5, x[3], y[2], carry)
461
462 carry, res[3] = umulHop(res3, x[0], y[3])
463 carry, res[4] = umulStep(res4, x[1], y[3], carry)
464 carry, res[5] = umulStep(res5, x[2], y[3], carry)
465 res[7], res[6] = umulStep(carry6, x[3], y[3], carry)
466
467 return res
468}
469
470func umulStep(z, x, y, carry uint64) (hi, lo uint64) {
471 hi, lo = bits.Mul64(x, y)
472 lo, carry = bits.Add64(lo, carry, 0)
473 hi += carry
474 lo, carry = bits.Add64(lo, z, 0)
475 hi += carry
476 return hi, lo
477}
478
479func umulHop(z, x, y uint64) (hi, lo uint64) {
480 hi, lo = bits.Mul64(x, y)
481 lo, carry := bits.Add64(lo, z, 0)
482 hi += carry
483 return hi, lo
484}
485
486// Clear sets every limb of z to zero.
487//
488// Returns:
489// - z: The receiver representing the signed value 0.
490func (z *Int) Clear() *Int {
491 z[0], z[1], z[2], z[3] = 0, 0, 0, 0
492 return z
493}
494
495// SetOne sets z to the signed value 1.
496//
497// Returns:
498// - z: The receiver with only its least-significant bit set.
499func (z *Int) SetOne() *Int {
500 z[3], z[2], z[1], z[0] = 0, 0, 0, 1
501 return z
502}
503
504// SetAllBitsOne sets every bit of z to one, the two's-complement representation of -1.
505//
506// Returns:
507// - z: The receiver containing the all-ones 256-bit pattern.
508func (z *Int) SetAllBitsOne() *Int {
509 z[0], z[1], z[2], z[3] = 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff
510 return z
511}
512
513// Div divides signed 256-bit x by y, truncating the quotient toward zero.
514//
515// Parameters:
516// - x: Signed 256-bit dividend.
517// - y: Signed 256-bit divisor.
518//
519// Returns:
520// - z: The receiver containing the signed quotient x / y.
521//
522// Panics if y is zero.
523func (z *Int) Div(x, y *Int) *Int {
524 if x.Sign() > 0 {
525 if y.Sign() > 0 {
526 return z.uquo(x, y)
527 }
528 z.uquo(x, new(Int).Neg(y))
529 return z.Neg(z)
530 }
531 if y.Sign() < 0 {
532 return z.uquo(new(Int).Neg(x), new(Int).Neg(y))
533 }
534 z.uquo(new(Int).Neg(x), y)
535 return z.Neg(z)
536}
537
538func (z *Int) uquo(x, y *Int) *Int {
539 if y.IsZero() {
540 panic("zero division")
541 }
542 if x.IsZero() {
543 return z.Clear()
544 }
545 if x.Eq(y) {
546 return z.SetOne()
547 }
548 if x.IsInt64() && y.IsInt64() {
549 return z.SetInt64(x.Int64() / y.Int64())
550 }
551 quot := Int{}
552 udivrem(quot[:], x[:], y)
553 return z.Set(")
554}
555
556// Rem computes the signed remainder of x divided by y, preserving x's sign.
557//
558// Parameters:
559// - x: Signed 256-bit dividend.
560// - y: Signed 256-bit divisor.
561//
562// Returns:
563// - z: The receiver containing x % y, with magnitude less than |y|.
564//
565// Panics if y is zero.
566func (z *Int) Rem(x, y *Int) *Int {
567 if x.Sign() > 0 {
568 if y.Sign() > 0 {
569 return z.urem(x, y)
570 }
571 return z.urem(x, new(Int).Neg(y))
572 }
573 if y.Sign() < 0 {
574 z.urem(new(Int).Neg(x), new(Int).Neg(y))
575 return z.Neg(z)
576 }
577 z.urem(new(Int).Neg(x), y)
578 return z.Neg(z)
579}
580
581func (z *Int) urem(x, y *Int) *Int {
582 if y.IsZero() {
583 panic("zero division")
584 }
585 if x.IsZero() {
586 return z.Clear()
587 }
588 if x.Eq(y) {
589 return z.Clear()
590 }
591 if x.IsInt64() && y.IsInt64() {
592 xInt64 := x.Int64()
593 yInt64 := y.Int64()
594 return z.SetInt64(xInt64 % yInt64)
595 }
596 quot := Int{}
597 rem := udivrem(quot[:], x[:], y)
598 return z.Set(&rem)
599}
600
601// Lt reports whether z is less than x as signed int256 values.
602//
603// Parameters:
604// - x: Signed 256-bit value to compare with z.
605//
606// Returns:
607// - less: True when z < x.
608func (z *Int) Lt(x *Int) bool {
609 return z.Cmp(x) < 0
610}
611
612// Lte reports whether z is less than or equal to x as signed int256 values.
613//
614// Parameters:
615// - x: Signed 256-bit value to compare with z.
616//
617// Returns:
618// - lessOrEqual: True when z <= x.
619func (z *Int) Lte(x *Int) bool {
620 return z.Cmp(x) <= 0
621}
622
623// Gt reports whether z is greater than x as signed int256 values.
624//
625// Parameters:
626// - x: Signed 256-bit value to compare with z.
627//
628// Returns:
629// - greater: True when z > x.
630func (z *Int) Gt(x *Int) bool {
631 return z.Cmp(x) > 0
632}
633
634// Gte reports whether z is greater than or equal to x as signed int256 values.
635//
636// Parameters:
637// - x: Signed 256-bit value to compare with z.
638//
639// Returns:
640// - greaterOrEqual: True when z >= x.
641func (z *Int) Gte(x *Int) bool {
642 return z.Cmp(x) >= 0
643}
644
645// Cmp compares z and x as signed two's-complement int256 values.
646//
647// Parameters:
648// - x: Signed 256-bit value to compare with z.
649//
650// Returns:
651// - comparison: -1 when z < x, 0 when z == x, and 1 when z > x.
652func (z *Int) Cmp(x *Int) int {
653 zneg := int8(z[3] >> 63)
654 xneg := int8(x[3] >> 63)
655 if zneg != xneg {
656 return int(xneg - zneg)
657 }
658 d0, carry := bits.Sub64(z[0], x[0], 0)
659 d1, carry := bits.Sub64(z[1], x[1], carry)
660 d2, carry := bits.Sub64(z[2], x[2], carry)
661 d3, carry := bits.Sub64(z[3], x[3], carry)
662 if carry == 1 {
663 return -1
664 }
665 if d0|d1|d2|d3 == 0 {
666 return 0
667 }
668 return 1
669}
670
671// Clone returns an independent copy of z.
672//
673// Returns:
674// - clone: A fresh *Int with the same four limbs as z.
675func (z *Int) Clone() *Int {
676 return &Int{z[0], z[1], z[2], z[3]}
677}
678
679// Or sets z to the bitwise OR of x and y.
680//
681// Parameters:
682// - x: First 256-bit operand.
683// - y: Second 256-bit operand.
684//
685// Returns:
686// - z: The receiver containing x | y.
687func (z *Int) Or(x, y *Int) *Int {
688 z[0] = x[0] | y[0]
689 z[1] = x[1] | y[1]
690 z[2] = x[2] | y[2]
691 z[3] = x[3] | y[3]
692 return z
693}
694
695// And sets z to the bitwise AND of x and y.
696//
697// Parameters:
698// - x: First 256-bit operand.
699// - y: Second 256-bit operand.
700//
701// Returns:
702// - z: The receiver containing x & y.
703func (z *Int) And(x, y *Int) *Int {
704 z[0] = x[0] & y[0]
705 z[1] = x[1] & y[1]
706 z[2] = x[2] & y[2]
707 z[3] = x[3] & y[3]
708 return z
709}
710
711// Xor sets z to the bitwise exclusive OR of x and y.
712//
713// Parameters:
714// - x: First 256-bit operand.
715// - y: Second 256-bit operand.
716//
717// Returns:
718// - z: The receiver containing x ^ y.
719func (z *Int) Xor(x, y *Int) *Int {
720 z[0] = x[0] ^ y[0]
721 z[1] = x[1] ^ y[1]
722 z[2] = x[2] ^ y[2]
723 z[3] = x[3] ^ y[3]
724 return z
725}
726
727// Not sets z to the bitwise complement of x.
728//
729// Parameters:
730// - x: 256-bit operand whose bits are complemented.
731//
732// Returns:
733// - z: The receiver containing ^x.
734func (z *Int) Not(x *Int) *Int {
735 z[0] = ^x[0]
736 z[1] = ^x[1]
737 z[2] = ^x[2]
738 z[3] = ^x[3]
739 return z
740}
741
742// Lsh sets z to x left-shifted by n bits, truncating to 256 bits.
743//
744// Parameters:
745// - x: 256-bit bit pattern to shift.
746// - n: Number of bit positions to shift left; n >= 256 yields zero.
747//
748// Returns:
749// - z: The receiver containing (x << n) modulo 2^256.
750func (z *Int) Lsh(x *Int, n uint) *Int {
751 if n == 0 {
752 return z.Set(x)
753 }
754 if n >= 256 {
755 return z.Clear()
756 }
757 // Handle exact multiples of 64 separately to avoid 64-bit shift issues
758 if n&0x3f == 0 {
759 switch n {
760 case 64:
761 z[3], z[2], z[1], z[0] = x[2], x[1], x[0], 0
762 case 128:
763 z[3], z[2], z[1], z[0] = x[1], x[0], 0, 0
764 case 192:
765 z[3], z[2], z[1], z[0] = x[0], 0, 0, 0
766 }
767 return z
768 }
769 switch {
770 case n > 192:
771 n -= 192
772 z[3], z[2], z[1], z[0] = x[0]<<n, 0, 0, 0
773 case n > 128:
774 n -= 128
775 z[3] = (x[1] << n) | (x[0] >> (64 - n))
776 z[2] = x[0] << n
777 z[1], z[0] = 0, 0
778 case n > 64:
779 n -= 64
780 z[3] = (x[2] << n) | (x[1] >> (64 - n))
781 z[2] = (x[1] << n) | (x[0] >> (64 - n))
782 z[1] = x[0] << n
783 z[0] = 0
784 default:
785 z[3] = (x[3] << n) | (x[2] >> (64 - n))
786 z[2] = (x[2] << n) | (x[1] >> (64 - n))
787 z[1] = (x[1] << n) | (x[0] >> (64 - n))
788 z[0] = x[0] << n
789 }
790 return z
791}
792
793// Rsh shifts x right by n bits using signed arithmetic semantics.
794// Non-negative values receive zero-fill; negative values receive sign extension.
795//
796// Parameters:
797// - x: Signed 256-bit value to shift.
798// - n: Number of bit positions to shift right.
799//
800// Returns:
801// - z: The receiver containing the arithmetic right shift of x.
802func (z *Int) Rsh(x *Int, n uint) *Int {
803 if n == 0 {
804 return z.Set(x)
805 }
806 if x.IsNeg() {
807 return z.negRsh(x, n)
808 }
809 return z.rsh(x, n)
810}
811
812func (z *Int) rsh(x *Int, n uint) *Int {
813 if n >= 256 {
814 return z.Clear()
815 }
816 // Handle exact multiples of 64 separately to avoid 64-bit shift issues
817 if n&0x3f == 0 {
818 switch n {
819 case 0:
820 return z.Set(x)
821 case 64:
822 z[3], z[2], z[1], z[0] = 0, x[3], x[2], x[1]
823 case 128:
824 z[3], z[2], z[1], z[0] = 0, 0, x[3], x[2]
825 case 192:
826 z[3], z[2], z[1], z[0] = 0, 0, 0, x[3]
827 }
828 return z
829 }
830 switch {
831 case n > 192:
832 n -= 192
833 z[3], z[2], z[1], z[0] = 0, 0, 0, x[3]>>n
834 case n > 128:
835 n -= 128
836 z[3], z[2] = 0, 0
837 z[1] = x[3] >> n
838 z[0] = (x[3] << (64 - n)) | (x[2] >> n)
839 case n > 64:
840 n -= 64
841 z[3] = 0
842 z[2] = x[3] >> n
843 z[1] = (x[3] << (64 - n)) | (x[2] >> n)
844 z[0] = (x[2] << (64 - n)) | (x[1] >> n)
845 default:
846 z[3] = x[3] >> n
847 z[2] = (x[3] << (64 - n)) | (x[2] >> n)
848 z[1] = (x[2] << (64 - n)) | (x[1] >> n)
849 z[0] = (x[1] << (64 - n)) | (x[0] >> n)
850 }
851 return z
852}
853
854func (z *Int) negRsh(x *Int, n uint) *Int {
855 if n >= 256 {
856 return z.SetAllBitsOne()
857 }
858 var v uint64 = 0xffffffffffffffff
859 // Handle exact multiples of 64 separately to avoid 64-bit shift issues
860 if n&0x3f == 0 {
861 switch n {
862 case 0:
863 return z.Set(x)
864 case 64:
865 z[3], z[2], z[1], z[0] = v, x[3], x[2], x[1]
866 case 128:
867 z[3], z[2], z[1], z[0] = v, v, x[3], x[2]
868 case 192:
869 z[3], z[2], z[1], z[0] = v, v, v, x[3]
870 }
871 return z
872 }
873 switch {
874 case n > 192:
875 n -= 192
876 z[3], z[2], z[1], z[0] = v, v, v, (v<<(64-n))|(x[3]>>n)
877 case n > 128:
878 n -= 128
879 z[3], z[2] = v, v
880 z[1] = (v << (64 - n)) | (x[3] >> n)
881 z[0] = (x[3] << (64 - n)) | (x[2] >> n)
882 case n > 64:
883 n -= 64
884 z[3] = v
885 z[2] = (v << (64 - n)) | (x[3] >> n)
886 z[1] = (x[3] << (64 - n)) | (x[2] >> n)
887 z[0] = (x[2] << (64 - n)) | (x[1] >> n)
888 default:
889 z[3] = (v << (64 - n)) | (x[3] >> n)
890 z[2] = (x[3] << (64 - n)) | (x[2] >> n)
891 z[1] = (x[2] << (64 - n)) | (x[1] >> n)
892 z[0] = (x[1] << (64 - n)) | (x[0] >> n)
893 }
894 return z
895}
896
897// BitLen returns the number of bits needed to represent z's raw 256-bit pattern.
898//
899// Returns:
900// - length: Bit length of the four-limb representation; zero has length 0 and
901// a negative value may require all 256 bits.
902func (z *Int) BitLen() int {
903 switch {
904 case z[3] != 0:
905 return 192 + bits.Len64(z[3])
906 case z[2] != 0:
907 return 128 + bits.Len64(z[2])
908 case z[1] != 0:
909 return 64 + bits.Len64(z[1])
910 default:
911 return bits.Len64(z[0])
912 }
913}
914
915// SetBytes32 loads the first 32 bytes of in as a big-endian 256-bit value.
916//
917// Parameters:
918// - in: Byte slice containing at least 32 bytes, with the most-significant byte first.
919// Bytes beyond the first 32 are ignored.
920//
921// Returns:
922// - z: The receiver populated from the 32-byte big-endian representation.
923//
924// Panics if in contains fewer than 32 bytes.
925func (z *Int) SetBytes32(in []byte) *Int {
926 _ = in[31] // bounds check hint to compiler; see golang.org/issue/14808
927 z[3] = binary.BigEndian.Uint64(in[0:8])
928 z[2] = binary.BigEndian.Uint64(in[8:16])
929 z[1] = binary.BigEndian.Uint64(in[16:24])
930 z[0] = binary.BigEndian.Uint64(in[24:32])
931 return z
932}
933