SIde-Channel Analysis toolKit (SICAK)
Software toolkit for side-channel analysis
ompcpa.hpp
Go to the documentation of this file.
1 /*
2 * SICAK - SIde-Channel Analysis toolKit
3 * Copyright (C) 2018 Petr Socha, FIT, CTU in Prague
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18 
19 /*
20 * Implemented algorithms are derived from equations published in:
21 * Schneider, T., Moradi, A., & Güneysu, T. (2016, April). Robust and one-pass parallel
22 * computation of correlation-based attacks at arbitrary order. In International
23 * Workshop on Constructive Side-Channel Analysis and Secure Design (pp. 199-217). Springer, Cham.
24 */
25 
36 #ifndef OMPCPA_H
37 #define OMPCPA_H
38 
39 #include <cmath>
40 #include <omp.h>
41 #include "exceptions.hpp"
42 #include "types_power.hpp"
43 #include "types_stat.hpp"
44 
50 template <class T, class U, class V>
52 
53  if(c.mOrder() != 1 || c.csOrder() != 2 || c.acsOrder() != 1)
54  throw RuntimeException("Not a valid first-order univariate CPA context!");
55 
56  if (c.p1Width() != pt.samplesPerTrace())
57  throw RuntimeException("Incompatible context: Numbers of samples per trace don't match.");
58 
59  if (c.p2Width() != pp.noOfCandidates())
60  throw RuntimeException("Incompatible context: Numbers of key candidates don't match.");
61 
62  if (pt.noOfTraces() != pp.noOfTraces())
63  throw RuntimeException("Number of power traces doesn't match the number of power predictions.");
64 
65  const long long noOfTraces = pt.noOfTraces();
66  const long long samplesPerTrace = pt.samplesPerTrace();
67  const long long noOfCandidates = pp.noOfCandidates();
68 
69  for (long long trace = 0; trace < noOfTraces; trace++) {
70 
71  #pragma omp parallel for
72  for (long long candidate = 0; candidate < noOfCandidates; candidate++) {
73 
74  T p_trace = static_cast<T>(c.p1Card()) / (static_cast<T>(c.p1Card()) + 1.0f);
75  T p_pp = pp(candidate, trace);
76  T p_predsAvg = c.p2M(1)(candidate); // c.predsAvg(candidate);
77  T p_optAlpha = p_trace * (p_pp - p_predsAvg);
78  T * p_predsTracesCSum = &( c.p12ACS(1)(0, candidate) ); //&(c.predsTracesCSum(0, candidate));
79  const U * p_pt = &(pt(0, trace));
80  T * p_tracesAvg = &( c.p1M(1)(0) ); //&(c.tracesAvg(0));
81 
82  for (long long sample = 0; sample < samplesPerTrace; sample++) {
83 
84  //*(p_predsTracesCSum++) += p_trace * ( *(p_pt++) - *(p_tracesAvg++) ) * ( p_pp - p_predsAvg);
85  *(p_predsTracesCSum++) += p_optAlpha * (static_cast<T>(*(p_pt++)) - *(p_tracesAvg++));
86 
87  }
88 
89  }
90 
91  for (long long candidate = 0; candidate < noOfCandidates; candidate++) {
92  T temp = 0;
93  temp = (static_cast<T>(pp(candidate, trace)) - c.p2M(1)(candidate));
94  c.p2M(1)(candidate) += (temp / static_cast<T>((c.p1Card() + 1)));
95  c.p2CS(2)(candidate) += temp * (static_cast<T>(pp(candidate, trace)) - c.p2M(1)(candidate));
96  }
97 
98  for (long long sample = 0; sample < samplesPerTrace; sample++) {
99  T temp = 0;
100  temp = (static_cast<T>(pt(sample, trace)) - c.p1M(1)(sample));
101  c.p1M(1)(sample) += (temp / static_cast<T>((c.p1Card() + 1)));
102  c.p1CS(2)(sample) += temp * (static_cast<T>(pt(sample, trace)) - c.p1M(1)(sample));
103  }
104 
105  c.p1Card() = c.p1Card() + 1;
106 
107  }
108 
109  c.p2Card() = c.p1Card();
110 
111 }
112 
118 template <class T>
120 
121  if(firstAndOut.mOrder() != 1 || firstAndOut.csOrder() != 2 || firstAndOut.acsOrder() != 1 || second.mOrder() != 1 || second.csOrder() != 2 || second.acsOrder() != 1)
122  throw RuntimeException("Not valid first-order univariate CPA contexts!");
123 
124  if(firstAndOut.p1Card() != firstAndOut.p2Card() || second.p1Card() != second.p2Card())
125  throw RuntimeException("Malformed CPA context");
126 
127  if(firstAndOut.p1Width() != second.p1Width() || firstAndOut.p2Width() != second.p2Width())
128  throw RuntimeException("Only contexts with same number of candidates and same number of samples per trace can be merged");
129 
130  const size_t samplesPerTrace = firstAndOut.p1Width();
131  const size_t noOfCandidates = firstAndOut.p2Width();
132 
133  const size_t firstSize = firstAndOut.p1Card();
134  const size_t secondSize = second.p1Card();
135 
136  // First, merge the ACSs
137  for(size_t candidate = 0; candidate < noOfCandidates; candidate++){
138 
139  for(size_t sample = 0; sample < samplesPerTrace; sample++) {
140 
141  firstAndOut.p12ACS(1)(sample, candidate) += second.p12ACS(1)(sample, candidate);
142  firstAndOut.p12ACS(1)(sample, candidate) += ( (secondSize * firstSize * firstSize + firstSize * secondSize * secondSize) /
143  ((firstSize + secondSize) * (firstSize + secondSize)) ) *
144  (second.p1M(1)(sample) - firstAndOut.p1M(1)(sample)) *
145  (second.p2M(1)(candidate) - firstAndOut.p2M(1)(candidate));
146 
147  }
148 
149  }
150 
151  // then merge the MSums
152  for(size_t sample = 0; sample < samplesPerTrace; sample++) {
153  firstAndOut.p1CS(2)(sample) += second.p1CS(2)(sample);
154  firstAndOut.p1CS(2)(sample) += (firstSize * secondSize) *
155  ( (second.p1M(1)(sample) - firstAndOut.p1M(1)(sample)) / (firstSize + secondSize) ) *
156  ( (second.p1M(1)(sample) - firstAndOut.p1M(1)(sample)) / (firstSize + secondSize) ) *
157  (firstSize + secondSize);
158  }
159 
160  for(size_t candidate = 0; candidate < noOfCandidates; candidate++){
161  firstAndOut.p2CS(2)(candidate) += second.p2CS(2)(candidate);
162  firstAndOut.p2CS(2)(candidate) += (firstSize * secondSize) *
163  ( (second.p2M(1)(candidate) - firstAndOut.p2M(1)(candidate)) / (firstSize + secondSize) ) *
164  ( (second.p2M(1)(candidate) - firstAndOut.p2M(1)(candidate)) / (firstSize + secondSize) ) *
165  (firstSize + secondSize);
166 
167  }
168 
169  // then merge the means
170  for(size_t sample = 0; sample < samplesPerTrace; sample++) {
171  firstAndOut.p1M(1)(sample) = ( (firstAndOut.p1M(1)(sample) * firstSize) + (second.p1M(1)(sample) * secondSize) ) / (firstSize + secondSize);
172  }
173 
174  for(size_t candidate = 0; candidate < noOfCandidates; candidate++){
175  firstAndOut.p2M(1)(candidate) = ( (firstAndOut.p2M(1)(candidate) * firstSize) + (second.p2M(1)(candidate) * secondSize) ) / (firstSize + secondSize);
176  }
177 
178  // finally update the cardinality of the context
179  firstAndOut.p1Card() += second.p1Card();
180  firstAndOut.p2Card() = firstAndOut.p1Card();
181 
182 }
183 
189 template <class T>
191 
192  if(c.mOrder() != 1 || c.csOrder() != 2 || c.acsOrder() != 1 || c.p1Card() != c.p2Card())
193  throw RuntimeException("Not a valid first-order univariate CPA context!");
194 
195  size_t samplesPerTrace = c.p1Width();
196  size_t noOfCandidates = c.p2Width();
197 
198  correlations.init(samplesPerTrace, noOfCandidates);
199  Vector<T> sqrtTracesCS2(samplesPerTrace);
200  Vector<T> sqrtPredsCS2(noOfCandidates);
201 
202 
203  for (size_t sample = 0; sample < samplesPerTrace; sample++) {
204  sqrtTracesCS2(sample) = sqrt(c.p1CS(2)(sample));
205  }
206 
207  for (size_t candidate = 0; candidate < noOfCandidates; candidate++) {
208  sqrtPredsCS2(candidate) = sqrt(c.p2CS(2)(candidate));
209  }
210 
211  for (size_t candidate = 0; candidate < noOfCandidates; candidate++) {
212 
213  for (size_t sample = 0; sample < samplesPerTrace; sample++) {
214 
215  if (sqrtTracesCS2(sample) == 0 || sqrtPredsCS2(candidate) == 0) throw RuntimeException("Division by zero");
216 
217  correlations(sample, candidate) = c.p12ACS(1)(sample, candidate) / (sqrtTracesCS2(sample) * sqrtPredsCS2(candidate));
218 
219  }
220 
221  }
222 
223 }
224 
225 #endif /* OMPCPA_H */
226 
227 
virtual size_t noOfTraces() const
Returns number of power traces.
Definition: types_power.hpp:67
An abstract class, representing all the matrix-like data types.
Definition: types_basic.hpp:132
A class representing a vector, stored in the machine's free space.
Definition: types_basic.hpp:217
A class representing a Two-population Univariate Moment-based statistical context.
Definition: types_stat.hpp:43
virtual Matrix< T > & p12ACS(size_t order)
Adjusted central moment sum both populations, order 1 upto acsOrder.
Definition: types_stat.hpp:220
This header file contains exceptions.
virtual size_t mOrder() const
Maximum order of the raw moments, 1 upto mOrder.
Definition: types_stat.hpp:183
virtual size_t csOrder() const
Maximum order of the central moment sums, 2 upto csOrder.
Definition: types_stat.hpp:185
void UniFoCpaAddTraces(UnivariateContext< T > &c, const PowerTraces< U > &pt, const PowerPredictions< V > &pp)
Adds given power traces and power predictions to the given statistical context. Use zeroed or meaning...
Definition: ompcpa.hpp:51
virtual void init(size_t cols, size_t rows)=0
Initializes the matrix with a specified number of cols and rows.
void UniFoCpaMergeContexts(UnivariateContext< T > &firstAndOut, const UnivariateContext< T > &second)
Merges two UnivariateContext and leaves the result in first context given.
Definition: ompcpa.hpp:119
virtual size_t p2Width() const
Width of the second population.
Definition: types_stat.hpp:180
virtual size_t & p1Card()
Cardinality of the first population.
Definition: types_stat.hpp:190
virtual size_t p1Width() const
Width of the first population.
Definition: types_stat.hpp:178
virtual size_t acsOrder() const
Maximum order of the adjusted central moment sums, 1 upto acsOrder.
Definition: types_stat.hpp:187
virtual Vector< T > & p2CS(size_t order)
Central moment sum of the second population, order 2 upto csOrder.
Definition: types_stat.hpp:215
This header file contains class templates of power traces and power consumption containers.
virtual size_t noOfTraces() const
Returns number of power predictions.
Definition: types_power.hpp:105
virtual size_t samplesPerTrace() const
Returns number of samples per trace.
Definition: types_power.hpp:65
A class representing a Matrix with 'noOfTraces' power predictions, with 'noOfCandidates' key candidat...
Definition: types_power.hpp:82
virtual size_t & p2Card()
Cardinality of the second population.
Definition: types_stat.hpp:195
virtual Vector< T > & p1CS(size_t order)
Central moment sum of the first population, order 2 upto csOrder.
Definition: types_stat.hpp:210
virtual size_t noOfCandidates() const
Returns number of key candidates per power prediction.
Definition: types_power.hpp:103
virtual Vector< T > & p2M(size_t order)
Raw moment of the second population, order 1 upto mOrder.
Definition: types_stat.hpp:205
An exception which cannot be directly influenced by the user, or predicted beforehand.
Definition: exceptions.hpp:76
This header file contains class templates of statistical computational contexts.
A class representing a Matrix with 'noOfTraces' power traces, with 'samplesPerTrace' samples per powe...
Definition: types_power.hpp:44
virtual Vector< T > & p1M(size_t order)
Raw moment of the first population, order 1 upto mOrder.
Definition: types_stat.hpp:200
void UniFoCpaComputeCorrelationMatrix(const UnivariateContext< T > &c, MatrixType< T > &correlations)
Computes final correlation matrix based on a UnivariateContext given, stores results in correlations.
Definition: ompcpa.hpp:190