Пример #1
0
        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));
        }
Пример #2
0
        private async Task <BitArray> MaskInputs(InputPartyMapping inputMapping, BitArray localInputValues)
        {
            List <int>[] inputIds = new List <int> [MultiPartySession.NumberOfParties];
            for (int partyId = 0; partyId < inputIds.Length; ++partyId)
            {
                inputIds[partyId] = new List <int>();
            }

            for (int inputId = 0; inputId < inputMapping.NumberOfInputs; ++inputId)
            {
                int partyId = inputMapping.GetAssignedParty(inputId);
                if (partyId < 0 || partyId >= MultiPartySession.NumberOfParties)
                {
                    throw new ArgumentException("Input mapping assigns inputs to party not participating in current session.", nameof(inputMapping));
                }

                inputIds[partyId].Add(inputId);
            }

            List <int> localInputIds = inputIds[MultiPartySession.LocalParty.Id];

            if (localInputValues.Length != localInputIds.Count)
            {
                throw new ArgumentException(
                          "Number of provided inputs does not match the number of declared inputs in the circuit for the local party.",
                          nameof(localInputValues)
                          );
            }

            BitArray localSharesOfInput = new BitArray(inputMapping.NumberOfInputs);

            // --- Share local inputs and send via network ---
            if (localInputIds.Count > 0)
            {
                BitArray localSharesOfLocalInput = localInputValues.Clone();

                foreach (ITwoPartyNetworkSession session in MultiPartySession.RemotePartySessions)
                {
                    BitArray remoteSharesOfLocalInput = _cryptoContext.RandomNumberGenerator.GetBits(localInputIds.Count);
                    localSharesOfLocalInput.Xor(remoteSharesOfLocalInput);

                    await session.Channel.WriteMessageAsync(remoteSharesOfLocalInput.ToBytes());
                }

                for (int localInputId = 0; localInputId < localInputIds.Count; ++localInputId)
                {
                    localSharesOfInput[localInputIds[localInputId]] = localSharesOfLocalInput[localInputId];
                }
            }

            // --- Receive shares of remote inputs via network ---
            foreach (ITwoPartyNetworkSession session in MultiPartySession.RemotePartySessions)
            {
                List <int> remoteInputIds = inputIds[session.RemoteParty.Id];

                if (remoteInputIds.Count > 0)
                {
                    BitArray localSharesOfRemoteInput = BitArray.FromBytes(await session.Channel.ReadMessageAsync(), remoteInputIds.Count);

                    if (localSharesOfRemoteInput.Length != remoteInputIds.Count)
                    {
                        throw new ProtocolException("Number of input shares received from remote party does not match number of declared inputs in the circuit.");
                    }

                    for (int remoteInputId = 0; remoteInputId < remoteInputIds.Count; ++remoteInputId)
                    {
                        localSharesOfInput[remoteInputIds[remoteInputId]] = localSharesOfRemoteInput[remoteInputId];
                    }
                }
            }

            return(localSharesOfInput);
        }