-
Notifications
You must be signed in to change notification settings - Fork 83
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
Optimistic Randomness for ABA #63
Comments
When you say 'coin schedule' do you mean (for option 2) instead of calling get_coin() and modulus the result by 2, we'd act like round 1 had a coin flip modulus 2 result of 1, round 2 also had a coin flip modulus 2 result of 1, round three had a coin flip modulus 2 result of 0... and round 5 we actually ran the common coin protocol? In addition, when you have those trailing ...s in the options, are the elided values coin() or a repetition of the pattern? |
@Vagabond yes your description is exactly what I mean by "coin schedule". |
Yeah, this seems really interesting. I like it. Just to confirm: the idea here is that in the usual case, when an attacker is not actively attacking ABA, a fixed coin schedule allows us to reach agreement faster with the fallback to the heavyweight common coin if we exceed 4 rounds (which is the expected number needed to converge)? Does this weaken security or just allow an adversary, if they are present, to cause ABA to take more rounds to complete? |
I believe you only need to do the very first round deterministic 1, since if every honest node begins by voting 1 then every node is guaranteed to always have bin_vals={1} and hence terminate on the first round. Similarly you should only need one round of deterministic 0 to handle the benign crashed nodes. I personally quite like the prf idea. You could even adjust the number of prf rounds dynamically to minimize the average number of message rounds until termination, so that in the presence of an active network adversary the prf rounds decrease, and in absence they increase. |
@ChronusZ even if every node starts by inputting |
@amiller It doesn't really matter if the actual process needs to continue longer after you've already produced an output right? Continuing longer only parallelizes with the rest of the protocol with no cost to latency. By the way, another point worth mentioning is that a simple modification to the CONF round turns it into an RBC READY-type round which can also be used to fix this. More specifically, you add the logic:
This way if you terminate in round r, by the reliability of the CONF message you know everyone else can eventually terminate on round r, and by the ABBA properties you know that no one will terminate on a different value even in a future round. Also, one more optimization that occurs to me is that by making the first round deterministically flip to 1, for any round r>1 all instances can get to the end of round r independently of any other other instance. Thus you can share the coins for each round between all instances by waiting until every single instance has gotten to the end of round r before flipping the coin for round r, and this won't introduce any issues for liveness. |
Alternatively, you could just add a READY-type message at the very end, and after outputting a value in some round only continue to the next round if t+1 nodes send a message for the next round. Then if t+1 honest nodes output in round r everyone can eventually receiving enough READY's to terminate, and otherwise everyone receives enough messages from the next round to participate in the next round themselves. |
Right, it's OK if the actual process continues longer even after output is delivered, it is just a little bit inelegant. In our Go implementation we've found it's easier to code to be able to clean up memory by only having one active at a time.
This is a really interesting optimization. If we could share common coins between instances it could cut down on the worst-case threshold crypto bottleneck. Indeed the main reason why we did not try to share the common coins between instances is because of a deadlock problem.. we need to be able to proceed with some ABA's that receive input 1 and complete before providing input 0 to any other ABAs. So if we wait until all instances are ready to proceed with the coin, then we would get stuck. Your observation is that by forcing the first coin to be 1 we are already removing that deadlock. We are guaranteeing that at least |
I'm probably missing something, but I was wondering whether some kind of special v*/termination message is necessary anyway, to guarantee that all instances terminate (not for output, of course, but for termination)?
|
tl;dr: we could cut down on the threshold signature cryptography Common Coins in the ABA protocol by using "forced" common coin values in the optimistic case.
The following suggestion comes from Christian Cachin:
In other words, the common coin cryptography is intended to handle a very extreme attacker scenario, where the attacker learns the common coin value, and equivocates at least once, and manipulates the network delivery to selectively delay convergence. The suggested coin schedule is basically:
[prg(), prg(), ... prg(), coin(), coin(), ...]
, whereprg()
means a coin that is random but predictable, like the hash of the current round number, andcoin()
is a real threshold common coin.Note that although this is optimism, it is optimism about adversarial network manipulation rather than optimism about timing or about a leader node like in PBFT, hence still within HoneyBadger ethos :)
Another related suggestion comes from Micali's "Byzantine Agreement, Made Trivial" paper. Although this protocol is intended for the Synchronous setting, it contains a nice insight about how to handle termination. Recall that in ABA, it can be the case that some node observes agreement on
v
in roundr
, but then we need to wait until the next roundr'>r
wherecoin(r')=v
for other honest nodes to reach agreement. This is a bit inelegant since ABA instances may have to remaining lingering around even after terminating. We could "fire and forget" our shares of a few of the remaining common coins, although we wouldn't know exactly how many it will take! Micali's suggestion is to draw coins in the order:[0, 1, coin(), 0, 1, coin(), 0, 1, coin(), ...]
Another suggestion is to have a special message,
v*
, which is basically an abbreviation forBVAL(v)
andAUX({v})
for all subsequent rounds. This guarantees at most one more common coin needs to be sent along withv*
.Another observation on the choice of coin schedule: Most of the ABA instances need to settle on
1
, in factN-f
of them must do so before any0
s can be input. So we can optimize for the typical case by starting with[1,1,...]
. Furthermore, in the case of a benign crash of some nodes, the corresponding ABA instances will receive input0
for everyone. So[1,1,0,0,...]
should resolve most cases in 4 iterations.So, I'd propose a coin schedule that looks like the following:
Option 1:
[1,1,0,0,prg(),prg(),prg(),prg(),1,0,coin(),1,0,coin(),...]
Option 2:
[1,1,0,0,coin(),1,0,coin(),...]
Both of these have the qualities:
0
and1
v*
without even computing a common coin shareOverall I'd prefer option 2 here since it makes it easier to create test scenarios that exercise the common coin.
Also note: the fix of adding an additional
CONF
message per #59 is only necessary for those rounds involvingcoin()
, since the purpose ofCONF
is to prevent a network manipulation adversary from predicting the coin value before influencing the estimates of the nodes, so it's redundant when the value is predictable anyway.The text was updated successfully, but these errors were encountered: