-
Notifications
You must be signed in to change notification settings - Fork 225
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
Odd behavior with nargo test (stack overflow) and nargo prove (same test pass but only with hexadecimal encoding) #2456
Comments
@TomAFrench what is the status of this issue? |
The first issue is inherent to toml as it cannot hold a numeric value which wouldn't fit inside an i64. I can reproduce the stack overflow issue, as part of this I've simplified the circuit to the below. fn main(
private_key: Field,
randomness1: Field,
randomness2: Field,
value: u40,
balance_old_me_clear: u40, // balance_old_me_clear is the clear (i.e decrypted) balance of sender, this is computed offchain by solving the DLP with babygiant algorithm, after calling bjj_exp_elgamal_decrypt with his private key
public_key_me: pub Gaffine,
public_key_to: pub Gaffine,
balance_old_me_encrypted_1: pub Gaffine,
balance_old_me_encrypted_2: Gaffine,
balance_old_to_encrypted_1: pub Gaffine,
balance_old_to_encrypted_2: pub Gaffine,
balance_new_me_encrypted_1: pub Gaffine,
balance_new_me_encrypted_2: pub Gaffine,
balance_new_to_encrypted_1: pub Gaffine,
balance_new_to_encrypted_2: pub Gaffine
) {
let computed_public_key = bjj_priv_to_pub_key(private_key);
assert_eq(public_key_me, computed_public_key); // check that the sender really owns the private key corresponding to his public key
assert(value <= balance_old_me_clear); // the sender must have sufficient balance
assert(value >= 1); // this is to deter potential front-running issue: ref https://crypto.stanford.edu/~buenz/papers/zether.pdf §3.1. Here we adopt a simpler approach than the multistep approach proposed in the Zether paper, for a better UX: an attacker who tries to DOS the sender should at least pay 1 token to either original sender or receiver. The "1" threshold could be changed to ensure correct economic incentives, typically this should be at least a multiple of the average gas price of a transfer transaction.
// another more straightforward solution to front-running would be simply to do the homomorphic addition in the smart contract rather than the circuit, but this is too expensive today on Ethereum, according to the Zeestar paper §III : https://files.sri.inf.ethz.ch/website/papers/sp22-zeestar.pdf
let bjj_affine: AffineCurve = baby_jubjub().curve;
let base_pt: Gaffine = baby_jubjub().base8;
let embedded_balance_old_me_clear = bjj_affine.mul(balance_old_me_clear as Field, base_pt);
let decoded_value = bjj_exp_elgamal_decrypt(
private_key,
(balance_old_me_encrypted_1, balance_old_me_encrypted_2)
);
assert_eq(decoded_value, embedded_balance_old_me_clear); // check that unencrypted balance of sender really corresponds to his encrypted balance
let balance_new_me_encrypted_computed = bjj_exp_elgamal_encrypt(public_key_me, balance_old_me_clear - value, randomness1);
// checks that the new encrypted balance of sender is correct
assert_eq(balance_new_me_encrypted_computed.1, balance_new_me_encrypted_2);
assert_eq(balance_new_me_encrypted_computed.0, balance_new_me_encrypted_1);
let value_encrypted_to = bjj_exp_elgamal_encrypt(public_key_to, value, randomness2);
let balance_new_to_encrypted_computed = (
bjj_affine.add(balance_old_to_encrypted_1, value_encrypted_to.0), bjj_affine.add(balance_old_to_encrypted_2, value_encrypted_to.1)
); // addition of the points on Baby Jubjub : this operation is additevely homomorphic for Exponential ElGamal
// checks that the new encrypted balance of receiver is correct
assert_eq(balance_new_to_encrypted_computed.0, balance_new_to_encrypted_1);
assert_eq(balance_new_to_encrypted_computed.1, balance_new_to_encrypted_2);
} When compiling this circuit I get a huge number of repeats blocks in SSA which just immediately jump to a different block. We should probably catch these earlier and do some minor inlining in this case.
|
Aim
When working on a Private token project, a test that should pass panicked when I used
nargo test
with a "stack overflow" error. I then tried the same test vianargo prove
by putting the same values for the input of main function in theProver.toml
file. Then unexpectedly again, withnargo prove
I received this errorError: Expected witness values to be integers, provided value causes
number too large to fit in target typeerror
. This was not making a lot of sense, so I decided to convert my 3 big Field inputs from their decimal form to their hexadecimal form insideProver.toml
file. Then finally,nargo prove
passed as expected from the beginning.I am not sure if those two issues are related, but I create a unique, as both happened almost at the same time.
Expected Behavior
nargo test
should have passed correctly, andnargo prove
should have passed also with decimal values.Bug
nargo test
->fatal runtime error: stack overflow
nargo prove
(before hexadecimal conversion) ->Error: Expected witness values to be integers, provided value causes "number too large to fit in target type" error
To Reproduce
Installation Method
Binary
Nargo Version
nargo 0.10.3 (git version hash: 2db759f, is dirty: false)
Additional Context
No response
Would you like to submit a PR for this Issue?
No
Support Needs
No response
The text was updated successfully, but these errors were encountered: