void attack_cpa<real>::process(const time_map &tmap, const trace &pt) { boost::lock_guard<boost::mutex> lock(m_mutex); // accumulate power and power^2 for each sample for (size_t s = 0; s < pt.size(); ++s) { m_t1[tmap[s]] += pt[s].power; m_t2[tmap[s]] += pt[s].power * pt[s].power; } for (int k = 0; k < m_guesses; ++k) { const int target = m_crypto->compute(m_byte, k); const int weight = util::popcnt[target & m_mask] - m_center; real *tw = &m_tw[k * m_nevents], fw = (real)weight; if (weight != 0) { m_w1[k] += fw; m_w2[k] += fw * fw; for (size_t s = 0; s < pt.size(); ++s) tw[tmap[s]] += pt[s].power * fw; } } ++m_traces; }
bool has_one_repetition(const trace &t) { if (t.size() <= 1) return true; if (t.back()== t[t.size()-2]) return false; if (t.tar_size()== t.size()){ if (t[0] == t.back()) return false; } return true; }
bool has_two_repetition(const trace &t) { if (t.size() <= 2) return true; edge e1 = t.back(); edge e2 = t[t.size()-2]; for (size_t i = 0; i < t.size()-2; i++) { if (t[i] == e1 && t[i+1] == e2) return false; if (t[i] == e2 && t[i+1] == e1) return false; } return true; }
// ----------------------------------------------------------------------------- // static bool trace_reader::copy_trace(const trace &pt_in, trace &pt_out, const trace::event_set &events) { trace::real last_power = 0.0f; trace::event_set::const_iterator curr_event = events.begin(); foreach (const trace::sample sample, pt_in.samples()) { // primetime may break the power sample into multiple events if (pt_out.size() && pt_out.back().time == sample.time) return false; // sample and hold by copying the previous power into each empty sample while ((curr_event != events.end()) && (*curr_event < sample.time)) pt_out.push_back(trace::sample(*curr_event++, sample.power)); assert(sample.time == *curr_event); pt_out.push_back(trace::sample(*curr_event++, sample.power)); // if this is disabled, last_power will always be 0 (ie. empty samples) last_power = sample.power; } // pad out (with sample and hold) any trailing samples, if necessary while (curr_event != events.end()) pt_out.push_back(trace::sample(*curr_event++, last_power)); return true; }
bool is_canon(const trace &t) { if (t.size() == 0) return true; if (t.tail_vertex() != t.head_vertex()) return true; vector<vertex> vt = t.get_vertex_trace(); vertex minv = vt[0]; vector<int> pp; for (size_t i = 0; i < vt.size(); i++) { if (i != 0 && vt[i] == minv) { pp.push_back(i); } } for (int p : pp) { //check backward for (size_t i = 0; i < vt.size(); i++) { int j = p-i; if (j <= 0) j = abs(j-1); if (vt[i] < vt[j]) { break; } else if (vt[i] > vt[j]) { return false; } } if (p == (int)vt.size()-1) continue; //check forward for (size_t i = 0; i < vt.size(); i++) { int j = (p+i); if (j >= (int)vt.size()) { j = (j+1)%vt.size(); } if (vt[i] < vt[j]) { break; } else if (vt[i] > vt[j]) { return false; } } } return true; }