public static RunItem ComputeRunStats(this RunItem runItem) { try { Trace.WriteLine("Start ComputeRunStats : RunItem " + runItem.KeyId); // Load the base64 keys String galKeyString = "", galSingleStepKeyString = "", relinKeyString = ""; KeyUtilities.GetKeys(runItem.KeyId, ref galKeyString, ref galSingleStepKeyString, ref relinKeyString); // Calculate the cipher results SEALWrapper sw = new SEALWrapper(4096); sw.LoadKeys(galKeyString, galSingleStepKeyString, relinKeyString); sw.ComputeStatsCiphers(runItem.Cipher1, runItem.Cipher2, runItem.Summary, runItem.CipherGyro); runItem.Stats = sw.getStats(); runItem.Summary = sw.getSummary(); runItem.CipherGyro = sw.getMlResults(); Trace.WriteLine("End ComputeRunStats : RunItem " + runItem.KeyId); } catch (Exception e) { Trace.TraceError("{%s} occurred while computing stats {RunItem : %d}", runItem.KeyId, e); } return(runItem); }
public void TestCipherMath() { int count = 10; int slotCount = 4096; double scale = 1.0; double Lat = 47.0; double Long = 122.0; double now = 1536782668; double startOfDay = now - 1736; int offset = 0; int yearofCentury = 3; offset += 100; int dayOfYear = 22 + offset; offset += 366; int dayOfWeek = 3 + offset; offset += 7; int weekOfYear = 2 + offset; // Create the Summary Mask List <double> summaryMask = new List <double>(slotCount); for (int i = 0; i < slotCount; i++) { summaryMask.Add(0); } summaryMask[yearofCentury] = 1; summaryMask[(slotCount / 2) + yearofCentury] = 1; summaryMask[dayOfWeek] = 1; summaryMask[(slotCount / 2) + dayOfWeek] = 1; summaryMask[weekOfYear] = 1; summaryMask[(slotCount / 2) + weekOfYear] = 1; summaryMask[dayOfYear] = 1; summaryMask[(slotCount / 2) + dayOfYear] = 1; // Create the Lats, Longs, and Timestamps List <double> lats = new List <double>(slotCount / 2); List <double> longs = new List <double>(slotCount / 2); List <double> timestamps = new List <double>(slotCount / 2); for (int i = 0; i < count; i++) { lats.Add(Lat); longs.Add(Long); Lat += 0.01; Long += 0.01; timestamps.Add((now - startOfDay) + (i * 2)); } for (int i = count; i < slotCount / 2; i++) { lats.Add(0); longs.Add(0); timestamps.Add(0); } // Create the average gyroscope data List <double> gyro = new List <double>(slotCount / 2); for (int i = 0; i < 6; ++i) { gyro.Add(1); } // Calculate the Cartesian List <double> cx = new List <double>(slotCount / 2); List <double> cy = new List <double>(slotCount / 2); List <double> cz = new List <double>(slotCount / 2); double PI = 3.14159265359; for (int i = 0; i < count; i++) { cx.Add((double)(6371.0 * Math.Cos(lats[i] * PI / 180.0) * Math.Cos(longs[i] * PI / 180.0) * scale)); cy.Add((double)(6371.0 * Math.Cos(lats[i] * PI / 180.0) * Math.Sin(longs[i] * PI / 180.0) * scale)); cz.Add((double)(6371.0 * Math.Sin(lats[i] * PI / 180.0) * scale)); } for (int i = count; i < slotCount / 2; i++) { cx.Add(0); cy.Add(0); cz.Add(0); } List <double> statsGold = new List <double>(slotCount); List <double> summaryGold = new List <double>(slotCount); double delta, totalDistance = 0, totalTime = timestamps[count - 1] - timestamps[0]; for (int i = 0; i < count - 1; i++) { delta = (double)Math.Pow((cx[i + 1] - cx[i]), 2) + (double)Math.Pow((cy[i + 1] - cy[i]), 2) + (double)Math.Pow((cz[i + 1] - cz[i]), 2); statsGold.Add(delta); totalDistance += delta; } for (int i = count - 1; i < slotCount; i++) { statsGold.Add(0); } statsGold[(slotCount / 2) - 1] = totalTime; statsGold[(slotCount / 2) + yearofCentury] = totalDistance; statsGold[(slotCount / 2) + dayOfWeek] = totalDistance; statsGold[(slotCount / 2) + weekOfYear] = totalDistance; statsGold[(slotCount / 2) + dayOfYear] = totalDistance; for (int i = 0; i < slotCount; i++) { summaryGold.Add(0); } summaryGold[yearofCentury] = totalTime; summaryGold[dayOfWeek] = totalTime; summaryGold[weekOfYear] = totalTime; summaryGold[dayOfYear] = totalTime; summaryGold[(slotCount / 2) + yearofCentury] = totalDistance; summaryGold[(slotCount / 2) + dayOfWeek] = totalDistance; summaryGold[(slotCount / 2) + weekOfYear] = totalDistance; summaryGold[(slotCount / 2) + dayOfYear] = totalDistance; // Create the vectors for the cipher math List <double> firstList = new List <double>(slotCount); List <double> secondList = new List <double>(slotCount); for (int i = 0; i < count; i++) { firstList.Add(cx[i]); secondList.Add(cz[i]); } for (int i = count; i < slotCount / 2; i++) { firstList.Add(cx[count - 1]); secondList.Add(cz[count - 1]); } for (int i = 0; i < count; i++) { firstList.Add(cy[i]); secondList.Add(timestamps[i]); } for (int i = count; i < slotCount / 2; i++) { firstList.Add(cy[count - 1]); secondList.Add(timestamps[count - 1]); } // Create the Ciphertexts SEALWrapper sw = new SEALWrapper(slotCount, true, true); String firstbase64 = sw.Encrypt(firstList); String secondbase64 = sw.Encrypt(secondList); String summaryMaskBase64 = sw.Encrypt(summaryMask); String gyroBase64 = sw.Encrypt(gyro); String galKeysString = sw.getGaloisKeys(); String galKeysSingleStepString = sw.getGaloisSingleStepKeys(); String relinKeysString = sw.getRelinKeys(); // Perform the add with a new SEALWrapper to simulate the call from the server SEALWrapper serverSW = new SEALWrapper(slotCount); serverSW.LoadKeys(galKeysString, galKeysSingleStepString, relinKeysString); Assert.IsTrue(serverSW.ComputeStatsCiphers(firstbase64, secondbase64, summaryMaskBase64, gyroBase64), "Server Call"); String statsBase64 = serverSW.getStats(); String summaryBase64 = serverSW.getSummary(); String mlBase64 = serverSW.getMlResults(); // Get the List result with the first SEALWrapper that has the keys still List <double> statsList = sw.Decrypt(statsBase64); List <double> summaryList = sw.Decrypt(summaryBase64); List <double> mlList = sw.Decrypt(mlBase64); // Reset the near zero to zero for (int i = 0; i < slotCount; i++) { if (Math.Abs(statsList[i]) < 0.00001) { statsList[i] = 0.0; } if (Math.Abs(summaryList[i]) < 0.00001) { summaryList[i] = 0.0; } } // Test that the results match Assert.AreEqual(statsList.Count, statsGold.Count, "Stats Size"); Assert.AreEqual(summaryList.Count, summaryGold.Count, "Summary Size"); for (int i = 0; i < slotCount; i++) { double diffStatsList = Math.Abs(statsList[i] - statsGold[i]); double diffSummaryList = Math.Abs(summaryList[i] - summaryGold[i]); Assert.IsTrue(diffStatsList < 0.1, "Stats Index Miss Match: " + i); Assert.IsTrue(diffSummaryList < 0.1, "Summary Index Miss Match: " + i); } // Test gyro output double[] tensorB = new double[] { 0.41964226961135864, 6.6290693283081055, -2.404352903366089, -0.024301817640662193, -0.17596858739852905, 0.14117737114429474 }; double expectedMlResult = 0; for (int i = 0; i < tensorB.Length; ++i) { expectedMlResult += tensorB[i]; } Assert.IsTrue(Math.Abs(expectedMlResult - mlList[0]) < 0.1); }