Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Unexpected result on Rsh #8

Open
IsraelGomes opened this issue May 17, 2024 · 3 comments
Open

Unexpected result on Rsh #8

IsraelGomes opened this issue May 17, 2024 · 3 comments

Comments

@IsraelGomes
Copy link

IsraelGomes commented May 17, 2024

Hello.
I was using the Rsh method and came across an unexpected behavior. I think this code might reproduce the problem.
I am comparing it with uint256.

valueU256 := uint256.MustFromDecimal("6276865796315986613307619852238232712866172378830163935232")
fmt.Println("Result uint256:", valueU256.Rsh(valueU256, 128).Dec())
valueI256 := int256.MustFromDec("6276865796315986613307619852238232712866172378830163935232")
fmt.Println("Result int256:", valueI256.Rsh(valueI256, 128).Dec())

The code produce this result:

Result uint256: 18446050711097703530
Result int256: 0

A Rsh operation where z and x are same have that error, but if we use a new receiver as below it does not happen.

valueU256 := uint256.MustFromDecimal("6276865796315986613307619852238232712866172378830163935232")
fmt.Println("Result uint256:", valueU256.Rsh(valueU256, 128).Dec())
valueI256 := int256.MustFromDec("6276865796315986613307619852238232712866172378830163935232")
fmt.Println("Result int256:", new(int256.Int).Rsh(valueI256, 128).Dec())

The result is the same as uint256.

Result uint256: 18446050711097703530
Result int256: 18446050711097703530

I think it has to do with the order some things are done here:

func (z *Int) rsh(x *Int, n uint) *Int {
	if n >= 255 {
		return z.Clear()
	}
	switch {
	case n >= 192:
		n -= 192
		z[3], z[2], z[1], z[0] = 0, 0, 0, x[3]>>n
	case n >= 128:
		n -= 128
		z[3], z[2] = 0, 0// If z and x are the same reference, then this will change x[3] and x[2] as well
		z[1] = x[3] >> n // causing this to be z[1] = 0 >> n.
		z[0] = (x[3] << (64 - n)) | (x[2] >> n) // and this to be (0 << (64 - n)) | (0 >> n).
	case n >= 64:
// I think this case have the same problem as the previous one.
		n -= 64
		z[3] = 0
		z[2] = x[3] >> n
		z[1] = (x[3] << (64 - n)) | (x[2] >> n)
		z[0] = (x[2] << (64 - n)) | (x[1] >> n)
	default:
		z[3] = x[3] >> n
		z[2] = (x[3] << (64 - n)) | (x[2] >> n)
		z[1] = (x[2] << (64 - n)) | (x[1] >> n)
		z[0] = (x[1] << (64 - n)) | (x[0] >> n)
	}
	return `z`
}

It worked when I changed to:

func (z *Int) rsh(x *Int, n uint) *Int {
	if n >= 255 {
		return z.Clear()
	}
	switch {
	case n >= 192:
		n -= 192
		z[3], z[2], z[1], z[0] = 0, 0, 0, x[3]>>n
	case n >= 128:
		n -= 128
		z[0] = (x[3] << (64 - n)) | (x[2] >> n)
		z[1] = x[3] >> n
		z[3], z[2] = 0, 0
	case n >= 64:
		n -= 64
		z[0] = (x[2] << (64 - n)) | (x[1] >> n)
		z[1] = (x[3] << (64 - n)) | (x[2] >> n)
		z[2] = x[3] >> n
		z[3] = 0
	default:
		z[0] = (x[1] << (64 - n)) | (x[0] >> n)
		z[1] = (x[2] << (64 - n)) | (x[1] >> n)
		z[2] = (x[3] << (64 - n)) | (x[2] >> n)
		z[3] = x[3] >> n
	}
	return z
}

I hope this can help somehow.

@IsraelGomes IsraelGomes changed the title Unexpected Unexpected result on Rsh May 17, 2024
@vuquang23
Copy link
Contributor

@IsraelGomes sorry man i left the org for a long time so had no notice about this issue. Yeah its critical. I know how to fix it. But if you got it done already lets create a pr.

@IsraelGomes
Copy link
Author

I fixed it at the time, but I actually didn't test it.

@vuquang23
Copy link
Contributor

okay thanks man. let me do it.
btw seems no one maintains this repo at K so I just forked https://github.com/vuquang23/int256

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants