private async Task <BitArray> UnmaskOutputs(OutputPartyMapping outputMapping, BitArray localSharesOfOutput) { List <int>[] outputIds = new List <int> [MultiPartySession.NumberOfParties]; for (int partyId = 0; partyId < outputIds.Length; ++partyId) { outputIds[partyId] = new List <int>(); } for (int outputId = 0; outputId < outputMapping.NumberOfOutputs; ++outputId) { for (int partyId = 0; partyId < MultiPartySession.NumberOfParties; ++partyId) { if (outputMapping.GetAssignedParties(outputId).Contains(partyId)) { outputIds[partyId].Add(outputId); } } } foreach (ITwoPartyNetworkSession session in MultiPartySession.RemotePartySessions) { List <int> remoteOutputIds = outputIds[session.RemoteParty.Id]; if (remoteOutputIds.Count > 0) { BitArray localSharesOfRemoteOutput = new BitArray(remoteOutputIds.Count); for (int i = 0; i < remoteOutputIds.Count; ++i) { localSharesOfRemoteOutput[i] = localSharesOfOutput[remoteOutputIds[i]]; } await session.Channel.WriteMessageAsync(localSharesOfRemoteOutput.ToBytes()); } } List <int> localOutputIds = outputIds[MultiPartySession.LocalParty.Id]; BitArray localOutputValues = new BitArray(localOutputIds.Count); for (int i = 0; i < localOutputIds.Count; ++i) { localOutputValues[i] = localSharesOfOutput[localOutputIds[i]]; } if (localOutputIds.Count > 0) { foreach (ITwoPartyNetworkSession session in MultiPartySession.RemotePartySessions) { BitArray remoteSharesOfLocalOutput = BitArray.FromBytes(await session.Channel.ReadMessageAsync(), localOutputIds.Count); localOutputValues.Xor(remoteSharesOfLocalOutput); } } return(localOutputValues); }
public async Task <BitArray> EvaluateAsync(IBatchEvaluableCircuit evaluable, InputPartyMapping inputMapping, OutputPartyMapping outputMapping, BitArray localInputValues) { if (inputMapping.NumberOfInputs != evaluable.Context.NumberOfInputGates) { throw new ArgumentException( "The number of inputs in input mapping does not match the number of declared inputs in the circuit.", nameof(inputMapping) ); } if (outputMapping.NumberOfOutputs != evaluable.Context.NumberOfOutputGates) { throw new ArgumentException( "The number of outputs in output mapping does not match the number of declared outputs in the circuit.", nameof(outputMapping) ); } SecretSharingBooleanCircuitEvaluator evaluator = new SecretSharingBooleanCircuitEvaluator(MultiPartySession, _multiplicativeSharing); BitArray maskedInputs = await MaskInputs(inputMapping, localInputValues); Task <Bit>[] inputTasks = maskedInputs.Select(Task.FromResult).ToArray(); Task <Bit>[] outputTasks = evaluable.Evaluate(evaluator, inputTasks); BitArray maskedOutputs = new BitArray(await Task.WhenAll(outputTasks)); return(await UnmaskOutputs(outputMapping, maskedOutputs)); }