Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Unexpected result on Rsh #8

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

Unexpected result on Rsh #8

IsraelGomes opened this issue May 17, 2024 · 0 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant