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)); }
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; }
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); }
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[] 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 StateMachine() { key_pair = new RSACryptoServiceProvider(CommonParams.serverKeyBits); rows = new List<DiffPrivRow>(); budget = new BigRational(1); rows_received = 0; rng = new Random(); }
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; }