/// <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);
        }
Beispiel #2
0
 public PairIndexArray ToPairIndexArray()
 {
     return(PairIndexArray.FromBytes(ToBytes(), Length));
 }
Beispiel #3
0
 public static BitArray FromPairIndexArray(PairIndexArray array)
 {
     return(new BitArray(array.ToBytes(), array.Length));
 }
 public Task <byte[][]> ReceiveAsync(PairIndexArray selectionIndices, int numberOfInvocations, int numberOfMessageBytes)
 {
     return(ReceiveAsync(BitArray.FromPairIndexArray(selectionIndices), numberOfInvocations, numberOfMessageBytes));
 }