Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

int256.gno

22.03 Kb · 932 lines
  1package int256
  2
  3import (
  4	"encoding/binary"
  5	"math"
  6	"math/bits"
  7
  8	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(&quot)
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}