protected override async Task <byte[][]> ReceiveMaskedOptionsAsync(BitArray selectionIndices, BitMatrix tTransposed, int numberOfInvocations, int numberOfMessageBytes)
        {
            Debug.Assert(selectionIndices.Length == numberOfInvocations);
            Debug.Assert(tTransposed.Rows == SecurityParameter);
            Debug.Assert(tTransposed.Cols == numberOfInvocations);

            // retrieve the masked options from the sender and unmask the one indicated by the
            //  corresponding selection indices
            byte[][][] maskedOptions = await CommunicationTools.ReadOptionsAsync(Channel, 1, numberOfInvocations, numberOfMessageBytes);

            Debug.Assert(maskedOptions.Length == numberOfInvocations);

            byte[][] results = new byte[numberOfInvocations][];
            Parallel.For(0, numberOfInvocations, i =>
            {
                Debug.Assert(maskedOptions[i].Length == 1);
                Debug.Assert(maskedOptions[i][0].Length == numberOfMessageBytes);

                RandomOracle randomOracle = RandomOracleProvider.Create();

                int s = Convert.ToInt32(selectionIndices[i].Value);

                byte[] query = tTransposed.GetColumn((uint)i).ToBytes();

                if (s == 0)
                {
                    results[i] = randomOracle.Invoke(query).Take(numberOfMessageBytes).ToArray();
                }
                else
                {
                    results[i] = randomOracle.Mask(maskedOptions[i][0], query);
                }
            });
            return(results);
        }
Ejemplo n.º 2
0
        protected override async Task <byte[][]> ReceiveMaskedOptionsAsync(BitArray selectionIndices, BitMatrix tTransposed, int numberOfInvocations, int numberOfMessageBytes)
        {
            Debug.Assert(selectionIndices.Length == numberOfInvocations);
            Debug.Assert(tTransposed.Rows == SecurityParameter);
            Debug.Assert(tTransposed.Cols == numberOfInvocations);
            // note(lumip): could precompute the masks for the response to have only cheap Xor after
            //  waiting for the message, but not sure if it really is a significant performance issue

            // retrieve the masked options from the sender and unmask the one indicated by the
            //  corresponding selection indices
            byte[][][] maskedOptions = await CommunicationTools.ReadOptionsAsync(Channel, 2, numberOfInvocations, numberOfMessageBytes);

            Debug.Assert(maskedOptions.Length == numberOfInvocations);

            byte[][] results = new byte[numberOfInvocations][];
            Parallel.For(0, numberOfInvocations, i =>
            {
                int s = Convert.ToInt32(selectionIndices[i].Value);

                Debug.Assert(maskedOptions[i][s].Length == numberOfMessageBytes);
                byte[] query = tTransposed.GetColumn((uint)i).ToBytes();
                results[i]   = RandomOracleProvider.Create().Mask(maskedOptions[i][s], query);
            });
            return(results);
        }
        /// <summary>
        /// Receives and returns the matrix Q as specified in the OT extension protocol of Ishai et al.
        ///
        /// This is involves the preprocessing (expanding the base OTs for the number of invocations, etc..)
        /// for all variants of the OT extension. This method should be called is the first step by
        /// subclasses implementing the OT extension variants.
        /// </summary>
        /// <param name="numberOfInvocations">The number of invocations/instances of OT.</param>
        /// <returns>The matrix Q of correlated randomness.</returns>
        protected async Task <BitMatrix> ReceiveQMatrix(int numberOfInvocations)
        {
            if (_senderState.SeededRandomOracles == null)
            {
                await ExecuteSenderBaseOTAsync();
            }

            int numberOfRandomBytes = BitArray.RequiredBytes(numberOfInvocations);

            BitMatrix q = new BitMatrix((uint)numberOfInvocations, (uint)SecurityParameter);

            // note(lumip): could precompute the masks for the response to have only cheap Xor after
            //  waiting for the message, but not sure if it really is a significant performance issue

            // todo(lumip): should try-catch in case random oracle runs out
            //  and ideally performs new base OTs and repeat
            byte[][][] qOTResult = await CommunicationTools.ReadOptionsAsync(Channel, 1, SecurityParameter, numberOfRandomBytes);

            Debug.Assert(qOTResult.Length == SecurityParameter);

            PairIndexArray randomChoiceInts = _senderState.RandomChoices.ToPairIndexArray();

            Parallel.For(0, SecurityParameter, k =>
            {
                Debug.Assert(qOTResult[k].Length == 1);
                Debug.Assert(qOTResult[k][0].Length == numberOfRandomBytes);

                BitArray mask = BitArray.FromBytes(
                    _senderState.SeededRandomOracles[k].Take(numberOfRandomBytes).ToArray(),
                    numberOfInvocations
                    );
                int s = randomChoiceInts[k];

                BitArray qColumn = mask;
                if (s == 1)
                {
                    qColumn.Xor(BitArray.FromBytes(qOTResult[k][0], numberOfInvocations));
                }

                q.SetColumn((uint)k, qColumn);
            });
            return(q);
        }