ABY
ABY copied to clipboard
B2AGate() returns weird values
I am trying a code that performs both Boolean and Arithmetic operations on SIMD values.
The first call on the B2AGate()
function works fine, but a second call to the same B2AGate
generates weird and random-looking numbers. Can the B2AGate
function be only called once in a circuit?
I believe my problem is the same as this issue opened last year: https://github.com/encryptogroup/ABY/issues/24
Thank you.
I just experienced the same behavior and it looks like this is due to the boolean sharings being of a bitlen
less than the circuit bitlen (e.g. 32). As a workaround for now, try to zero-pad your boolean sharings to full circuit bitlength before conversion.
BTW it really affects the second and following conversions, SIMD or not. The first conversion always succeeds, also if it is of a true simd share.
Thank you for the response. If the first conversion always succeeds (and succeeding conversions fail), is the bitlen
still the problem? The error may still occur even if bitlen
is the same as the circuit's.
I just found out that this workaround only works if all conversions are on the same circuit level. If you have SIMD shares and conversions on different circuit levels, then this workaround doesn't help either...
Minimal example is to create a boolean share with nvals=2
and convert it three times in a cycle bool->arith->bool->arith. The second B2A conversion generates random values again.
We're investigating the root of the problem...
We have fixed an issue with the B2A conversion in 01ee0dc86e9ceacf2687ebd2a2a2d2213bbbc2c5 There is another related problem that we are aware of and we are working on it at the moment.
Thanks for fixing the B2A conversion issue. What is the related problem?
B2A still returns weird random values if it called on the same circuit more than one time. I am not sure if the issue which @dd23 reports above as resolved resolves this problem. B2A clearly isn't working correctly after the first invocation. If you change the example given in #51 by replacing all yao shares to binary shares, you can easily reproduce the problem.
I recently fixed another bug that affects consecutive conversions on neighbouring layers, see PR #72 . Please try this one out and see if it fixes your problem. Note that you still have to zero-pad any boolean share to full bitlength before the conversion.
Yeah, I was going through your commit only right now. I think you have found the solution. Seems pretty logical to me. Will make the changes and report the results here. Thanks.
I keep getting SEG Fault when I add the declaration of m_vCONVGates2 in arithsharing.h. Do you have an idea why this is happening? I am working with this commit - d4670e52f515800c3c3bf04190665c8ed1eb0a4a, since the newer ones won't compile.
I propose you run git cherry-pick b3448f6dcbb371e8fdb88a4c2e2487aa2c4b2397
(hash of this PR's commit) instead of applying the changes manually, or is that what you did?
If the current public branch doesn't compile for you, you should file a separate bug report on this.
Doesn't the travis build of the latest public branch commits fail? Doesn't this mean that the project doesn't compile with the latest commits?
@mayank0403 The build is successful. However, the test cases currently fail on the Travis build server. (I think it has something to do with the race conditions #69.)
@lenerd Can you address issue #74 ? This is what is the error that I am facing while compiling the project.
@mayank0403 I have just started a Ubuntu VM and I am looking into it right now.
@sebastianst I just updated the latest commit with your the commit in your PR (#72 ) and in the code, I am using the same bitlen (32) for creating binary shares as the bitlen for the circuit (32), this code still gives random values with B2A gate being invocated more than one time. millionaire_prob.cpp.tar.gz
The problem and the outputs resemble to the one raised in #51.
(Please rather post such code as a gist in the future. Makes in easier to comment and update.) In line 63
condition = acirc->PutB2AGate(bcirc->PutGTGate(variable, put_cons32_gate(bcirc, 0)));
You don't zero-pad the GTGate share before conversion. Like I wrote earlier, zero-padding still needs to be done before conversion, i.e., add constant zero gates to the wires until full bitlen
(32 in your example).
This manual intervention is admittedly quite inconvenient and maybe it makes sense to do this implicitly in PutB2AGate
. @dd23 do you agree? We can add it until B2A is fully fixed to also handle non-full-bitlength conversions properly.
@sebastianst would it be possible for you to share the code where you zero-pad the binary shares before conversion? I cannot find a very lucid example or a description of how something like this could be done in the developer's manual. I was trying to do something like this -
std::vector<uint32_t> tmp = variable->get_wires();
tmp.insert(tmp.begin(), tmp.end(), tmp.end()+31);
variable = create_new_share(tmp, bcirc);
(Here variable
holds the binary shares which will be passed to the B2A gate for conversion.)
But clearly this doesn't work.
How do I explicitly put zeros into the wires even if I allocate new wires?
Never mind. I found the way.
std::vector<uint32_t> tmp = variable->get_wires();
share* zerobinary = put_cons32_gate(bcirc, 0);
std::vector<uint32_t> zerowires = zerobinary->get_wires();
zerobinary->set_wire_id(0, tmp[0]);
variable = zerobinary;
This works.
Yep that's a way. btw you can skip the 3rd line where you set zerowires
since you don't use it.
So does the conversion now work for you? If yes, we can close the issue.
Yeah, it works. Thanks.
I'd rather keep this issue open until the padding problem has been sorted out properly. The manual zero-padding adds some overhead and works as a workaround, but maybe we can implement a proper and more efficient solution.
In any case: thanks for your input so far!
PR #72 now has the full fix. @mayank0403 and others, you can give it a try and tell us if this also works without zero padding for you. Note that there's a bug in ENCRYPTO_utils/CBitVector::SetBitsPosOffset
and until it is fixed, you also need to apply 07646aed48fc9067670517777caba05c264caaaf for the conversion to work.
@sebastianst CBitVector::SetBitsPosOffset
is now fixed and the submodules are updated accordingly.