-
Notifications
You must be signed in to change notification settings - Fork 34
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
Added concatenated balance for nonzero constraint process #294
Conversation
prover/src/entry.rs
Outdated
for (i, balance) in self.balances.iter().rev().enumerate() { | ||
// Shift bits: 1 for buffer; 19 is highest bit for two power of userbase; 64 is for the maximum range check limit | ||
concatenated_balance += balance << ((1 + 19 + 64) * i); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to have 19
as a constant or a generic and also add an assertion that the concatenated balance would not exceed the field bit size.
prover/src/circuits/summa_circuit.rs
Outdated
let mut balances_expr = meta.query_advice(balances[N_CURRENCIES - 1], Rotation::cur()); | ||
|
||
// Base shift value for 84 bits. | ||
let base_shift = Fp::from(1 << 63).mul(&Fp::from(1 << 21)); | ||
|
||
let mut current_shift = Expression::Constant(base_shift); | ||
|
||
for i in (0..N_CURRENCIES - 1).rev() { | ||
let balance = meta.query_advice(balances[i], Rotation::cur()); | ||
let shifted_balance = balance * current_shift.clone(); | ||
balances_expr = balances_expr + shifted_balance; | ||
|
||
if i != 0 { | ||
current_shift = current_shift * Expression::Constant(base_shift); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works because we know exactly that N_CURRENCIES=3
, but will break if the prover changes the N_CURRENCIES
. I think it's better to add an assertion about the parameter combination (i.e., would there be "overlap" between shifted values for the given N_USERS, N_CURRENCIES and max possible range of a balance) and also calculate the base_shift
based on these parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While adding the assertions you suggested, I noticed that the verification of proof generated with N_CURRENCIES
= 2 failed. I still don't have any clue why it doesn't work with two currencies. Therefore, I have simply modified it to allow only 1 or 3 currencies with the assertion.
I believe I can remove contract and fix the backend as I did in PR #297 after merging PR #292.
)); | ||
} | ||
|
||
// Define shift bits: 1 for buffer, bits for user base that not exceed 19, and 64 bits for the balances range check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 19?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firstly, we can allocate 84 bits for each of the three currencies, totaling 252 bits, which does not exceed the modulus in the field.
The maximum user balance is
We use one bit as a buffer to separate the total sum balance in the concatenated balance, leaving us with 19 bits at the end. That's why the user base shouldn't exceed
I added an additional advice column for the concatenated balance, which combines more than two balances into one with shifted positions. For example, consider the following total balances:
The concatenated balance appears as:
There is an 84-bit shift between each balance.
Additionally, I introduced a constraint for the concatenated balances, formulated as ( D = (A << (84 * 2) ) + (B << 84) + C )