public object Clone() { XORArbiterPUF xCopy = new XORArbiterPUF(NumPUF); //Copy over the shallow variables (can improve this using shallow method copy later) xCopy.BitNumber = BitNumber; xCopy.MeanForAPUF = MeanForAPUF; xCopy.VarianceForAPUF = VarianceForAPUF; xCopy.NoiseMeanForAPUF = NoiseMeanForAPUF; xCopy.NoiseVarianceForAPUF = NoiseVarianceForAPUF; //Copy each individual APUF into the array for (int i = 0; i < NumPUF; i++) { xCopy.ArbiterPUFArray[i] = (ArbiterPUF)ArbiterPUFArray[i].Clone(); } return(xCopy); }
//Takes in weights, phi challenges and target response bits, gives average error of APUF model public override double ObjFunValue(double[] weightVector, double[][] phiChallenges, double[][] targets) { int bitNum = phiChallenges[0].Length - 1; XORArbiterPUF xModel = new XORArbiterPUF(bitNum, weightVector); int sampleNumber = phiChallenges.Length; //Number of challenge-response pairs (number of training samples) double error = 0; for (int currentSample = 0; currentSample < sampleNumber; currentSample++) { double currentTarget = targets[currentSample][0]; double modelOutput = xModel.ComputeResponse(phiChallenges[currentSample]); if (modelOutput != currentTarget) { error++; } } error = error / (double)sampleNumber; //Give the average error return(error); }
//This is a version to match Ha's noise, not sure if right public static void GenerateReliabilityTrainingDataHaWay(XORArbiterPUF xPUF, int numberOfMeasurements, double[][] trainingData, double[][] trainingReliability, Random randomGenerator) { int trainingSize = trainingData.Length; int bitNum = xPUF.BitNumber; //pregenerate training data inputs double[] noisyAPUFWeight1 = new double[bitNum + 1]; double[] noisyAPUFWeight2 = new double[bitNum + 1]; double[] sumOfResponses = new double[trainingSize]; for (int i = 0; i < trainingSize; i++) { trainingData[i] = GenerateRandomPhiVector(bitNum, randomGenerator); } for (int m = 0; m < numberOfMeasurements; m++) //Ha's way is flipped { double[] noiseAPUF1 = new double[bitNum + 1]; double[] noiseAPUF2 = new double[bitNum + 1]; for (int i = 0; i < noiseAPUF1.Length; i++) { noiseAPUF1[i] = GenerateRandomNormalVariable(0, 0.1, randomGenerator); noiseAPUF2[i] = GenerateRandomNormalVariable(0, 0.1, randomGenerator); } double[] originalAPUFWeight1 = xPUF.GetAllGroundTruthWeights()[0]; double[] originalAPUFWeight2 = xPUF.GetAllGroundTruthWeights()[1]; //Combine the noisy and original weights for (int i = 0; i < noisyAPUFWeight1.Length; i++) { noisyAPUFWeight1[i] = originalAPUFWeight1[i] + noiseAPUF1[i]; noisyAPUFWeight2[i] = originalAPUFWeight2[i] + noiseAPUF2[i]; } ArbiterPUF aNoisy1 = new ArbiterPUF(noisyAPUFWeight1); ArbiterPUF aNoisy2 = new ArbiterPUF(noisyAPUFWeight2); //Compute for each sample for (int i = 0; i < trainingSize; i++) { int cc = aNoisy1.ComputeResponse(trainingData[i]); int ccc = aNoisy2.ComputeResponse(trainingData[i]); int result = aNoisy1.ComputeResponse(trainingData[i]) ^ aNoisy2.ComputeResponse(trainingData[i]); sumOfResponses[i] = sumOfResponses[i] + result; } } //Last compute the reliability for (int i = 0; i < trainingSize; i++) { trainingReliability[i] = new double[1]; //trainingReliability[i][0]= Math.Abs(numberOfMeasurements / 2.0 - (sumOfResponses[i] / (double)numberOfMeasurements)); trainingReliability[i][0] = Math.Abs(numberOfMeasurements / 2.0 - (sumOfResponses[i])); } //for (int i = 0; i < trainingSize; i++) //{ // double sumOfResponses = 0; // //trainingData[i] = GenerateRandomPhiVector(bitNum); // trainingData[i] = GenerateRandomPhiVector(bitNum, randomGenerator); // for (int m = 0; m < numberOfMeasurements; m++) // { // double randomNoise // sumOfResponses = sumOfResponses + aPUF.ComputeNoisyResponse(trainingData[i]); //sum the measurements // } // trainingReliability[i] = new double[1]; // //trainingReliability[i][0] = sumOfResponses / (double)numberOfMeasurements; // trainingReliability[i][0] = Math.Abs(numberOfMeasurements / 2.0 - (sumOfResponses / (double)numberOfMeasurements)); //} }
//Generates the reliability training data for ONION attack only public static List <ReliabilityDataPoint> GenerateReliabilityTrainingDataOnion(XORArbiterPUF xPUF, int numberOfMeasurements, double[][] trainingData, double[][] trainingReliability, Random randomGenerator) { List <ReliabilityDataPoint> ReliabilityDataPointList = new List <ReliabilityDataPoint>(); //This stores all the noisy and non noisy data points with appropriate APUF labels int trainingSize = trainingData.Length; int bitNum = xPUF.BitNumber; for (int i = 0; i < trainingSize; i++) { double sumOfResponses = 0; trainingData[i] = GenerateRandomPhiVector(bitNum, randomGenerator); int[] previousAPUFResponses = new int[xPUF.GetPUFNum()]; //this stores all previous PUF responses to see if flip occured List <ArbiterPUF> currentNoisyAPUFList = new List <ArbiterPUF>(); //this stores all the APUFs making the challenge noisy for (int m = 0; m < numberOfMeasurements; m++) { int finalResult = 0; for (int p = 0; p < xPUF.GetPUFNum(); p++) { int currentResult = xPUF.GetAPUFAtIndex(p).ComputeNoisyResponse(trainingData[i]); finalResult = finalResult ^ currentResult; //this is the extra part for the onion attack if (m == 0) //this is the first time measurement being done so record responses { previousAPUFResponses[p] = currentResult; } else //compare to see if flipping occured { if (previousAPUFResponses[p] == currentResult) { //This APUF is reliable for this challenge, do nothing } else //This APUF is noisy for this phi { previousAPUFResponses[p] = currentResult; //store the new flip if (currentNoisyAPUFList.Contains(xPUF.GetAPUFAtIndex(p)) == false) //make sure the APUF hasn't been duplicated { currentNoisyAPUFList.Add(xPUF.GetAPUFAtIndex(p)); //note this does NOT copy, only puts pointer in memory } } } } //sumOfResponses = sumOfResponses + xPUF.ComputeNoisyResponse(trainingData[i]); //sum the measurements sumOfResponses = sumOfResponses + finalResult; } trainingReliability[i] = new double[1]; trainingReliability[i][0] = Math.Abs(numberOfMeasurements / 2.0 - sumOfResponses); //All measurements have been done, time to store the data point for onion analysis if (!currentNoisyAPUFList.Any() == true) //this means no APUFs made this challenge noisy so it is reliable { ReliabilityDataPointList.Add(new ReliabilityDataPoint(trainingData[i], trainingReliability[i][0], false)); } else { ReliabilityDataPointList.Add(new ReliabilityDataPoint(trainingData[i], trainingReliability[i][0], true, currentNoisyAPUFList)); } } return(ReliabilityDataPointList); }
//Use Ha's method to attack XOR APUF with the absolute objective function public static void AttackXORAPUFwithAbsoluteMethod() { //Generate a noisy PUF int bitNum = 64; int pufNum = 2; int numberOfMeasurements = 5; //I am guessing this, no clue double aPUFMean = 0.0; double aPUFVar = 1.0; double aPUFMeanNoise = 0.0; double aPUFNoiseVar = aPUFVar / 10.0; //Create the XOR APUF XORArbiterPUF xPUF = new XORArbiterPUF(pufNum, bitNum, aPUFMean, aPUFVar, aPUFMeanNoise, aPUFNoiseVar); //Generate training data (reliability information) int trainingSize = 30000; //fix back int testingSize = 10000; int attackRepeatNum = 15; ParallelOptions options = new ParallelOptions { MaxDegreeOfParallelism = 10 }; //make independent copies in memory XORArbiterPUF[] xArray = new XORArbiterPUF[attackRepeatNum]; for (int i = 0; i < xArray.Length; i++) { xArray[i] = (XORArbiterPUF)xPUF.Clone(); } double[][] solutionList = new double[attackRepeatNum][]; //Two different objective functions, one for CMA-ES, the other to test the final model accuracy ObjectiveFunctionResponse rObj = new ObjectiveFunctionResponse(); //ObjectiveFunctionReliabilityStandard[] sObjArray = new ObjectiveFunctionReliabilityStandard[attackRepeatNum]; ObjectiveFunctionReliabilityAbsolute[] sObjArray = new ObjectiveFunctionReliabilityAbsolute[attackRepeatNum]; for (int i = 0; i < sObjArray.Length; i++) { sObjArray[i] = new ObjectiveFunctionReliabilityAbsolute(); } Parallel.For(0, attackRepeatNum, a => { //for (int a = 0; a < attackRepeatNum; a++) //{ Random randomGenerator = new Random((int)DateTime.Now.Ticks); //remove the dependences for parallelization int dimensionNumber = bitNum + 1; double[][] trainingData = new double[trainingSize][]; //these will be phi vectors double[][] trainingReliability = new double[trainingSize][]; //DataGeneration.GenerateReliabilityTrainingDataHaWay(xArray[a], numberOfMeasurements, trainingData, trainingReliability, randomGenerator); DataGeneration.GenerateReliabilityTrainingData(xArray[a], numberOfMeasurements, trainingData, trainingReliability, randomGenerator); //Generate the first solution randomly for CMA-ES double[] firstSolution = new double[bitNum + 1]; for (int i = 0; i < firstSolution.Length; i++) { //firstSolution[i] = AppConstants.rx.NextDouble(); firstSolution[i] = randomGenerator.NextDouble(); } Console.Out.WriteLine("Data generation for core " + a.ToString() + " complete. Beginning CMA-ES"); CMAESCandidate solutionCMAES = CMAESMethods.ComputeCMAES(dimensionNumber, sObjArray[a], trainingData, trainingReliability, firstSolution, randomGenerator); double[] solution = solutionCMAES.GetWeightVector(); solutionList[a] = solution; //store the solution in independent memory // } }); //Just see if we can recover the 0th APUF //ArbiterPUF aPUF = xPUF.GetAPUFAtIndex(0); //Testing data can be in form of response because we don't care about the reliability double[][] accMeasures = new double[solutionList.Length][]; for (int i = 0; i < solutionList.Length; i++) { accMeasures[i] = new double[pufNum]; } Random randomGenerator2 = new Random((int)DateTime.Now.Ticks); for (int j = 0; j < pufNum; j++) { ArbiterPUF aPUF = xPUF.GetAPUFAtIndex(j); double[][] testingData = new double[testingSize][]; //these will be phi vectors double[][] testingResponse = new double[testingSize][]; DataGeneration.GenerateTrainingData(aPUF, testingData, testingResponse, randomGenerator2); for (int i = 0; i < solutionList.Length; i++) { accMeasures[i][j] = 1.0 - rObj.ObjFunValue(solutionList[i], testingData, testingResponse); Console.Out.WriteLine("The accuracy for PUF " + j.ToString() + " " + accMeasures[i][j].ToString()); } //Ground truth sanity check double gca = 1.0 - rObj.ObjFunValue(aPUF.GetGroundTruthWeight(), testingData, testingResponse); Console.Out.WriteLine("The ground truth accuracy for PUF " + j.ToString() + " " + gca.ToString()); } int k = 0; }