public byte[] HandleRequest(byte[] requestBytes)
        {
            object request = DiffPrivRequest.ParseRequest(requestBytes);

            if (request is Common.GetQuoteRequest)
            {
                GetQuoteResponse getQuoteResponse = new GetQuoteResponse(0, key_pair);
                return(getQuoteResponse.Encode());
            }
            if (request is InitializeDBRequest)
            {
                InitializeDBRequest r = (InitializeDBRequest)request;
                if (rows_received != 0)
                {
                    Console.Error.WriteLine("Received request to initialize DB after receiving rows");
                    return(DiffPrivSrvResponse.EncodeInitializeDBResponse(18));
                }

                if (r.budget_num < r.budget_den)
                {
                    Console.Error.WriteLine("Received request to initialize DB with budget < 1");
                    return(DiffPrivSrvResponse.EncodeInitializeDBResponse(16));
                }

                budget = new BigRational(r.budget_num, r.budget_den);
                rows.Clear();
                return(DiffPrivSrvResponse.EncodeInitializeDBResponse(0));
            }
            if (request is AddRowRequest)
            {
                byte[] ciphertext = ((AddRowRequest)request).ciphertext;
                byte[] plaintext;
                try
                {
                    plaintext = key_pair.Decrypt(ciphertext, false);
                }
                catch
                {
                    Console.Error.WriteLine("Received undecryptable add-row request");
                    return(DiffPrivSrvResponse.EncodeAddRowResponse());
                }

                HandleAddRowRequest(plaintext);
                return(DiffPrivSrvResponse.EncodeAddRowResponse());
            }
            if (request is QueryRequest)
            {
                QueryRequest r = (QueryRequest)request;
                return(HandleQueryRequest(r));
            }
            return(InvalidResponse.Encode());
        }
        public void HandleAddRowRequest(byte[] plaintext)
        {
            if (plaintext.Length < 16)
            {
                Console.Error.WriteLine("Received add-row request with < 16 bytes, with length {0}", plaintext.Length);
                return;
            }

            int row_nonce_size = (int)CommonRoutines.ExtractBEWord(plaintext, 0);
            int row_data_size  = (int)CommonRoutines.ExtractBEWord(plaintext, 4);

            if (plaintext.Length < 16 + row_nonce_size + row_data_size)
            {
                Console.Error.WriteLine("Received too-small add-row request, with length {0}", plaintext.Length);
                return;
            }

            UInt32 max_budget_num = CommonRoutines.ExtractBEWord(plaintext, 8);
            UInt32 max_budget_den = CommonRoutines.ExtractBEWord(plaintext, 12);

            byte[]   row_nonce = plaintext.Skip(16).Take(row_nonce_size).ToArray();
            byte[]   row_data  = plaintext.Skip(16 + row_nonce_size).Take(row_data_size).ToArray();
            UInt32[] row_words = CommonRoutines.BEByteSeqToWordSeq(row_data);

            if (max_budget_den == 0)
            {
                Console.Error.WriteLine("Received add-row request with 0 budget denominator");
                return;
            }

            BigRational max_budget = new BigRational(max_budget_num, max_budget_den);

            if (budget > max_budget)
            {
                Console.Error.WriteLine("Received add-row request with too restrictive a budget requirement");
                return;
            }

            foreach (DiffPrivRow row in rows)
            {
                if (row.nonce.SequenceEqual(row_nonce))
                {
                    Console.Error.WriteLine("Received add-row request with duplicate nonce, so not adding it");
                    return;
                }
            }

            rows.Add(new DiffPrivRow(row_nonce, row_words));
        }
        private static UInt32 FindHighestPowerLeThreshold(BigRational alpha, BigRational threshold, UInt32 max_power)
        {
            UInt32      e          = 0;
            BigRational alpha_to_e = new BigRational(1);

            while (e < max_power)
            {
                alpha_to_e = alpha_to_e * alpha;
                if (alpha_to_e > threshold)
                {
                    return(e);
                }
                ++e;
            }
            return(max_power);
        }
        private static bool FindHigherPowerOfTwo(BigRational r, out UInt32 x)
        {
            x = 0;
            BigRational two      = new BigRational(2);
            BigRational two_to_x = new BigRational(1);

            while (x < 0xFFFFFFFF)
            {
                if (two_to_x >= r)
                {
                    return(true);
                }
                ++x;
                two_to_x *= two;
            }
            return(two_to_x >= r);
        }
        public byte[] HandleQueryRequest(QueryRequest request)
        {
            if (request.row_min > request.row_max)
            {
                Console.Error.WriteLine("Row value range empty");
                return(DiffPrivSrvResponse.EncodeQueryResponse(1, 0));
            }
            if (request.answer_min > request.answer_max)
            {
                Console.Error.WriteLine("Answer range empty");
                return(DiffPrivSrvResponse.EncodeQueryResponse(2, 0));
            }
            if (request.answer_units <= 0)
            {
                Console.Error.WriteLine("Answer units not positive");
                return(DiffPrivSrvResponse.EncodeQueryResponse(3, 0));
            }
            if (request.alpha_num <= request.alpha_den)
            {
                Console.Error.WriteLine("Alpha not greater than 1");
                return(DiffPrivSrvResponse.EncodeQueryResponse(6, 0));
            }
            if (request.beta_num <= request.beta_den)
            {
                Console.Error.WriteLine("Beta not greater than 1");
                return(DiffPrivSrvResponse.EncodeQueryResponse(13, 0));
            }

            UInt32[]      program_words = CommonRoutines.BEByteSeqToWordSeq(request.program_encoding);
            MapperProgram program       = new MapperProgram(program_words);

            if (!program.IsValid())
            {
                Console.Error.WriteLine("Invalid program provided for query");
                return(DiffPrivSrvResponse.EncodeQueryResponse(4, 0));
            }

            if (request.answer_units >= 0x80000000)
            {
                Console.Error.WriteLine("Answer granularity too high");
                return(DiffPrivSrvResponse.EncodeQueryResponse(17, 0));
            }

            BigRational alpha = new BigRational(request.alpha_num, request.alpha_den);
            BigRational beta  = new BigRational(request.beta_num, request.beta_den);
            UInt32      delta = DivideRoundingUp(request.row_max - request.row_min, request.answer_units);
            UInt32      B     = request.answer_max - request.answer_min;

            if (B <= 0)
            {
                Console.Error.WriteLine("Answer range empty");
                return(DiffPrivSrvResponse.EncodeQueryResponse(5, 0));
            }
            if (alpha <= new BigRational(1))
            {
                return(DiffPrivSrvResponse.EncodeQueryResponse(6, 0));
            }
            BigRational alpha_to_delta = BigRational.Power(alpha, delta);

            if (beta <= alpha_to_delta)
            {
                Console.Error.WriteLine("Beta not greater than alpha to the power of delta");
                return(DiffPrivSrvResponse.EncodeQueryResponse(7, 0));
            }

            if (beta > budget)
            {
                Console.Error.WriteLine("Not enough budget for request");
                return(DiffPrivSrvResponse.EncodeQueryResponse(11, 0));
            }

            BigRational one = new BigRational(1);
            BigRational two = new BigRational(2);
            BigRational min_alpha_minus_1_and_2 = alpha - one;

            if (min_alpha_minus_1_and_2 > two)
            {
                min_alpha_minus_1_and_2 = two;
            }
            BigRational noiseEntropyPart1 = (alpha + one) * (beta + one) / ((beta - alpha_to_delta) * min_alpha_minus_1_and_2);

            UInt32 r1;

            if (!FindHigherPowerOfTwo(noiseEntropyPart1, out r1) || r1 >= 0xFFFFFFE0)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to noise entropy part 1");
                return(DiffPrivSrvResponse.EncodeQueryResponse(8, 0));
            }

            UInt32 log_alpha;

            if (!FindHigherPowerOfTwo(alpha, out log_alpha) || log_alpha > 0xFFFFFFFFUL / B)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to alpha");
                return(DiffPrivSrvResponse.EncodeQueryResponse(8, 0));
            }

            UInt32 r2 = log_alpha * (B - 1);

            if (r2 >= 0xFFFFFFC8 - r1)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to r2");
                return(DiffPrivSrvResponse.EncodeQueryResponse(8, 0));
            }

            UInt32 r = RoundUpToMultiple(r1 + r2 + 7, 8);
            UInt32 num_randoms_needed = RoundUpToMultiple(r / 8, 4) + 1;

            bool negate_noise = (rng.Next() % 2 == 0);

            byte[] randoms = new byte[num_randoms_needed];
            rng.NextBytes(randoms);
            randoms[num_randoms_needed - 1] = 0;
            BigInteger U = new BigInteger(randoms);

            BigRational one_half    = new BigRational(1, 2);
            BigRational numerator   = new BigRational(U) + one_half;
            BigRational denominator = BigRational.Power(two, (num_randoms_needed - 1) * 8);
            BigRational u           = numerator / denominator;

            BigRational threshold      = (two * alpha) / (u * (alpha + one));
            UInt32      absolute_noise = FindHighestPowerLeThreshold(alpha, threshold, B);

            UInt32 answer        = ComputeSum(program, request.row_min, request.row_max, request.answer_units, request.answer_min, request.answer_max);
            UInt32 noised_answer = AddNoise(answer, absolute_noise, negate_noise);
            UInt32 response      = ClipWord32(noised_answer, request.answer_min, request.answer_max);

            budget = budget / beta;
            return(DiffPrivSrvResponse.EncodeQueryResponse(0, response));
        }
Example #6
0
 private static UInt32 FindHighestPowerLeThreshold (BigRational alpha, BigRational threshold, UInt32 max_power)
 {
     UInt32 e = 0;
     BigRational alpha_to_e = new BigRational(1);
     while (e < max_power)
     {
         alpha_to_e = alpha_to_e * alpha;
         if (alpha_to_e > threshold)
         {
             return e;
         }
         ++e;
     }
     return max_power;
 }
Example #7
0
        public byte[] HandleQueryRequest(QueryRequest request)
        {
            if (request.row_min > request.row_max)
            {
                Console.Error.WriteLine("Row value range empty");
                return DiffPrivSrvResponse.EncodeQueryResponse(1, 0);
            }
            if (request.answer_min > request.answer_max)
            {
                Console.Error.WriteLine("Answer range empty");
                return DiffPrivSrvResponse.EncodeQueryResponse(2, 0);
            }
            if (request.answer_units <= 0)
            {
                Console.Error.WriteLine("Answer units not positive");
                return DiffPrivSrvResponse.EncodeQueryResponse(3, 0);
            }
            if (request.alpha_num <= request.alpha_den)
            {
                Console.Error.WriteLine("Alpha not greater than 1");
                return DiffPrivSrvResponse.EncodeQueryResponse(6, 0);
            }
            if (request.beta_num <= request.beta_den)
            {
                Console.Error.WriteLine("Beta not greater than 1");
                return DiffPrivSrvResponse.EncodeQueryResponse(13, 0);
            }

            UInt32[] program_words = CommonRoutines.BEByteSeqToWordSeq(request.program_encoding);
            MapperProgram program = new MapperProgram(program_words);
            if (!program.IsValid())
            {
                Console.Error.WriteLine("Invalid program provided for query");
                return DiffPrivSrvResponse.EncodeQueryResponse(4, 0);
            }

            if (request.answer_units >= 0x80000000)
            {
                Console.Error.WriteLine("Answer granularity too high");
                return DiffPrivSrvResponse.EncodeQueryResponse(17, 0);
            }

            BigRational alpha = new BigRational(request.alpha_num, request.alpha_den);
            BigRational beta = new BigRational(request.beta_num, request.beta_den);
            UInt32 delta = DivideRoundingUp(request.row_max - request.row_min, request.answer_units);
            UInt32 B = request.answer_max - request.answer_min;

            if (B <= 0)
            {
                Console.Error.WriteLine("Answer range empty");
                return DiffPrivSrvResponse.EncodeQueryResponse(5, 0);
            }
            if (alpha <= new BigRational(1))
            {
                return DiffPrivSrvResponse.EncodeQueryResponse(6, 0);
            }
            BigRational alpha_to_delta = BigRational.Power(alpha, delta);
            if (beta <= alpha_to_delta)
            {
                Console.Error.WriteLine("Beta not greater than alpha to the power of delta");
                return DiffPrivSrvResponse.EncodeQueryResponse(7, 0);
            }

            if (beta > budget)
            {
                Console.Error.WriteLine("Not enough budget for request");
                return DiffPrivSrvResponse.EncodeQueryResponse(11, 0);
            }

            BigRational one = new BigRational(1);
            BigRational two = new BigRational(2);
            BigRational min_alpha_minus_1_and_2 = alpha - one;
            if (min_alpha_minus_1_and_2 > two)
            {
                min_alpha_minus_1_and_2 = two;
            }
            BigRational noiseEntropyPart1 = (alpha + one) * (beta + one) / ((beta - alpha_to_delta) * min_alpha_minus_1_and_2);

            UInt32 r1;
            if (!FindHigherPowerOfTwo(noiseEntropyPart1, out r1) || r1 >= 0xFFFFFFE0)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to noise entropy part 1");
                return DiffPrivSrvResponse.EncodeQueryResponse(8, 0);
            }

            UInt32 log_alpha;
            if (!FindHigherPowerOfTwo(alpha, out log_alpha) || log_alpha > 0xFFFFFFFFUL / B)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to alpha");
                return DiffPrivSrvResponse.EncodeQueryResponse(8, 0);
            }

            UInt32 r2 = log_alpha * (B-1);
            if (r2 >= 0xFFFFFFC8 - r1)
            {
                Console.Error.WriteLine("Requires too many bits of randomness due to r2");
                return DiffPrivSrvResponse.EncodeQueryResponse(8, 0);
            }

            UInt32 r = RoundUpToMultiple(r1 + r2 + 7, 8);
            UInt32 num_randoms_needed = RoundUpToMultiple(r / 8, 4) + 1;

            bool negate_noise = (rng.Next() % 2 == 0);
            byte[] randoms = new byte[num_randoms_needed];
            rng.NextBytes(randoms);
            randoms[num_randoms_needed - 1] = 0;
            BigInteger U = new BigInteger(randoms);

            BigRational one_half = new BigRational(1, 2);
            BigRational numerator = new BigRational(U) + one_half;
            BigRational denominator = BigRational.Power(two, (num_randoms_needed - 1) * 8);
            BigRational u = numerator / denominator;

            BigRational threshold = (two * alpha) / (u * (alpha + one));
            UInt32 absolute_noise = FindHighestPowerLeThreshold(alpha, threshold, B);

            UInt32 answer = ComputeSum(program, request.row_min, request.row_max, request.answer_units, request.answer_min, request.answer_max);
            UInt32 noised_answer = AddNoise(answer, absolute_noise, negate_noise);
            UInt32 response = ClipWord32(noised_answer, request.answer_min, request.answer_max);

            budget = budget / beta;
            return DiffPrivSrvResponse.EncodeQueryResponse(0, response);
        }
Example #8
0
 private static bool FindHigherPowerOfTwo (BigRational r, out UInt32 x)
 {
     x = 0;
     BigRational two = new BigRational(2);
     BigRational two_to_x = new BigRational(1);
     while (x < 0xFFFFFFFF)
     {
         if (two_to_x >= r)
         {
             return true;
         }
         ++x;
         two_to_x *= two;
     }
     return two_to_x >= r;
 }
Example #9
0
        public void HandleAddRowRequest(byte[] plaintext)
        {
            if (plaintext.Length < 16)
            {
                Console.Error.WriteLine("Received add-row request with < 16 bytes, with length {0}", plaintext.Length);
                return;
            }

            int row_nonce_size = (int)CommonRoutines.ExtractBEWord(plaintext, 0);
            int row_data_size = (int)CommonRoutines.ExtractBEWord(plaintext, 4);
            if (plaintext.Length < 16 + row_nonce_size + row_data_size)
            {
                Console.Error.WriteLine("Received too-small add-row request, with length {0}", plaintext.Length);
                return;
            }

            UInt32 max_budget_num = CommonRoutines.ExtractBEWord(plaintext, 8);
            UInt32 max_budget_den = CommonRoutines.ExtractBEWord(plaintext, 12);
            byte[] row_nonce = plaintext.Skip(16).Take(row_nonce_size).ToArray();
            byte[] row_data = plaintext.Skip(16 + row_nonce_size).Take(row_data_size).ToArray();
            UInt32[] row_words = CommonRoutines.BEByteSeqToWordSeq(row_data);

            if (max_budget_den == 0)
            {
                Console.Error.WriteLine("Received add-row request with 0 budget denominator");
                return;
            }

            BigRational max_budget = new BigRational(max_budget_num, max_budget_den);
            if (budget > max_budget)
            {
                Console.Error.WriteLine("Received add-row request with too restrictive a budget requirement");
                return;
            }

            foreach (DiffPrivRow row in rows)
            {
                if (row.nonce.SequenceEqual(row_nonce))
                {
                    Console.Error.WriteLine("Received add-row request with duplicate nonce, so not adding it");
                    return;
                }
            }

            rows.Add(new DiffPrivRow(row_nonce, row_words));
        }
Example #10
0
        public byte[] HandleRequest(byte[] requestBytes)
        {
            object request = DiffPrivRequest.ParseRequest(requestBytes);
            if (request is Common.GetQuoteRequest)
            {
                GetQuoteResponse getQuoteResponse = new GetQuoteResponse(0, key_pair);
                return getQuoteResponse.Encode();
            }
            if (request is InitializeDBRequest)
            {
                InitializeDBRequest r = (InitializeDBRequest)request;
                if (rows_received != 0)
                {
                    Console.Error.WriteLine("Received request to initialize DB after receiving rows");
                    return DiffPrivSrvResponse.EncodeInitializeDBResponse(18);
                }

                if (r.budget_num < r.budget_den)
                {
                    Console.Error.WriteLine("Received request to initialize DB with budget < 1");
                    return DiffPrivSrvResponse.EncodeInitializeDBResponse(16);
                }

                budget = new BigRational(r.budget_num, r.budget_den);
                rows.Clear();
                return DiffPrivSrvResponse.EncodeInitializeDBResponse(0);
            }
            if (request is AddRowRequest)
            {
                byte[] ciphertext = ((AddRowRequest)request).ciphertext;
                byte[] plaintext;
                try
                {
                    plaintext = key_pair.Decrypt(ciphertext, false);
                }
                catch
                {
                    Console.Error.WriteLine("Received undecryptable add-row request");
                    return DiffPrivSrvResponse.EncodeAddRowResponse();
                }

                HandleAddRowRequest(plaintext);
                return DiffPrivSrvResponse.EncodeAddRowResponse();
            }
            if (request is QueryRequest)
            {
                QueryRequest r = (QueryRequest)request;
                return HandleQueryRequest(r);
            }
            return InvalidResponse.Encode();
        }
Example #11
0
 public StateMachine()
 {
     key_pair = new RSACryptoServiceProvider(CommonParams.serverKeyBits);
     rows = new List<DiffPrivRow>();
     budget = new BigRational(1);
     rows_received = 0;
     rng = new Random();
 }
Example #12
0
 public static BigRational Power(BigRational x, UInt32 e)
 {
     BigRational x_to_e = new BigRational(1);
     while (e > 0)
     {
         x_to_e *= x;
         e -= 1;
     }
     return x_to_e;
 }