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

Possible issue in ModExpGadget #842

Open
kunxian-xia opened this issue Aug 29, 2023 · 1 comment
Open

Possible issue in ModExpGadget #842

kunxian-xia opened this issue Aug 29, 2023 · 1 comment

Comments

@kunxian-xia
Copy link

An example case:

base_len = 1, exp_len = 1, mod_len = 1
base = 0x21, exp_len = 0x23, mod_len = 0x57

I.e. the input bytes are as follows (note that we always right-pad the real input with 0 to have length 192)

0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
2123570000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

That is, we have call_data_length = 96 + 3 = 99.

cb.require_equal(
"input acc bytes with padding must equal",
input_bytes_acc.expr(),
padding_zero.expr() * input.bytes_rlc()
+ rlc_rev(&garbage_bytes_holder, cb.challenges().keccak_input()),
);

The code above can be translated to the following constraints:

// kr is short for challenges.keccak_input()
// padding_zero = kr^93 
if i < 93: input_bytes_acc[i] = garbage_bytes[i];
if 93 <= i < 96: input_bytes_acc[i] = garbage_bytes[i] + input[i]  // vulnerability here
if i >= 96: input_bytes_acc[i] = input[i]

In the example, it means

  • 0x21 = garbage_bytes[93] + input[93]: we can set input[93] to any byte that we want.
@noel2004
Copy link
Member

So we should not put the "valid bytes" at the right-end and expect the bytes beyond valid is 0

For example, consider we have a N bytes segment and only m bytes in it is valid (m is dynamic)

Currently we put the m bytes at the right end of N bytes like [ 0 .... 0 <m bytes>]
and calculate the rlc = <RLC of the other> * (R**m) + <RLC of N bytes>, which is not sound

But we can put m bytes at left end: [<m bytes> 0 .... 0]
and calculate the rlc = (R**(m-n) *(<RLC of the other> * (R**N) + <RLC of N bytes>)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants