Skip to content

Instantly share code, notes, and snippets.

@sneves
Created May 23, 2016 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sneves/15d7ae82831044b0ac12c413adad36bf to your computer and use it in GitHub Desktop.
Save sneves/15d7ae82831044b0ac12c413adad36bf to your computer and use it in GitHub Desktop.
#include <cstddef>
#include <cstdint>
#include <vector>
#include <random>
#include <numeric>
#include <iostream>
#include <algorithm>
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
static void salsa_core(uint32_t x[16], size_t rounds) {
uint32_t in[16];
for(size_t i = 0; i < 16; ++i) in[i] = x[i];
for(size_t i = 0; i < rounds; i += 2) {
x[ 4] ^= R(x[ 0] + x[12], 7); x[ 8] ^= R(x[ 4] + x[ 0], 9);
x[12] ^= R(x[ 8] + x[ 4],13); x[ 0] ^= R(x[12] + x[ 8],18);
x[ 9] ^= R(x[ 5] + x[ 1], 7); x[13] ^= R(x[ 9] + x[ 5], 9);
x[ 1] ^= R(x[13] + x[ 9],13); x[ 5] ^= R(x[ 1] + x[13],18);
x[14] ^= R(x[10] + x[ 6], 7); x[ 2] ^= R(x[14] + x[10], 9);
x[ 6] ^= R(x[ 2] + x[14],13); x[10] ^= R(x[ 6] + x[ 2],18);
x[ 3] ^= R(x[15] + x[11], 7); x[ 7] ^= R(x[ 3] + x[15], 9);
x[11] ^= R(x[ 7] + x[ 3],13); x[15] ^= R(x[11] + x[ 7],18);
x[ 1] ^= R(x[ 0] + x[ 3], 7); x[ 2] ^= R(x[ 1] + x[ 0], 9);
x[ 3] ^= R(x[ 2] + x[ 1],13); x[ 0] ^= R(x[ 3] + x[ 2],18);
x[ 6] ^= R(x[ 5] + x[ 4], 7); x[ 7] ^= R(x[ 6] + x[ 5], 9);
x[ 4] ^= R(x[ 7] + x[ 6],13); x[ 5] ^= R(x[ 4] + x[ 7],18);
x[11] ^= R(x[10] + x[ 9], 7); x[ 8] ^= R(x[11] + x[10], 9);
x[ 9] ^= R(x[ 8] + x[11],13); x[10] ^= R(x[ 9] + x[ 8],18);
x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9);
x[14] ^= R(x[13] + x[12],13); x[15] ^= R(x[14] + x[13],18);
}
for (size_t i = 0; i < 16; ++i) x[i] += in[i];
}
static void sorsa_core(uint32_t x[16], size_t rounds) {
uint32_t in[16];
for(size_t i = 0; i < 16; ++i) in[i] = x[i];
for(size_t i = 0; i < rounds; i += 2) {
x[ 4] ^= R(x[ 0] | x[12], 7); x[ 8] ^= R(x[ 4] | x[ 0], 9);
x[12] ^= R(x[ 8] | x[ 4],13); x[ 0] ^= R(x[12] | x[ 8],18);
x[ 9] ^= R(x[ 5] | x[ 1], 7); x[13] ^= R(x[ 9] | x[ 5], 9);
x[ 1] ^= R(x[13] | x[ 9],13); x[ 5] ^= R(x[ 1] | x[13],18);
x[14] ^= R(x[10] | x[ 6], 7); x[ 2] ^= R(x[14] | x[10], 9);
x[ 6] ^= R(x[ 2] | x[14],13); x[10] ^= R(x[ 6] | x[ 2],18);
x[ 3] ^= R(x[15] | x[11], 7); x[ 7] ^= R(x[ 3] | x[15], 9);
x[11] ^= R(x[ 7] | x[ 3],13); x[15] ^= R(x[11] | x[ 7],18);
x[ 1] ^= R(x[ 0] | x[ 3], 7); x[ 2] ^= R(x[ 1] | x[ 0], 9);
x[ 3] ^= R(x[ 2] | x[ 1],13); x[ 0] ^= R(x[ 3] | x[ 2],18);
x[ 6] ^= R(x[ 5] | x[ 4], 7); x[ 7] ^= R(x[ 6] | x[ 5], 9);
x[ 4] ^= R(x[ 7] | x[ 6],13); x[ 5] ^= R(x[ 4] | x[ 7],18);
x[11] ^= R(x[10] | x[ 9], 7); x[ 8] ^= R(x[11] | x[10], 9);
x[ 9] ^= R(x[ 8] | x[11],13); x[10] ^= R(x[ 9] | x[ 8],18);
x[12] ^= R(x[15] | x[14], 7); x[13] ^= R(x[12] | x[15], 9);
x[14] ^= R(x[13] | x[12],13); x[15] ^= R(x[14] | x[13],18);
}
for (size_t i = 0; i < 16; ++i) x[i] ^= in[i];
}
template<typename Function>
static void hamming(Function F) {
static const size_t kSampleSize = 1UL << 20;
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<uint32_t> dist;
std::vector<size_t> v; v.reserve(kSampleSize);
for(size_t i = 0; i < kSampleSize; ++i) {
uint32_t x0[16], x1[16];
size_t pos = dist(rng) % 512;
// size_t pos = dist(rng) % 64 + 6*32; // Nonce words only
for(size_t j = 0; j < 16; ++j)
x0[j] = x1[j] = dist(rng);
// Inject low-weight input difference
x1[(pos / 32)] ^= 1UL << (pos % 32);
F(x0, 20);
F(x1, 20);
// Output difference
for(size_t j = 0; j < 16; ++j)
x0[j] ^= x1[j];
// hamming distance
size_t count = 0;
for(size_t j = 0; j < 16; ++j) {
for(size_t k = 0; k < 32; ++k) {
count += (x0[j] >> k) & 1;
}
}
v.push_back(count);
}
std::cout << "Min = " << *std::min_element(v.begin(), v.end()) << std::endl;
std::cout << "Max = " << *std::max_element(v.begin(), v.end()) << std::endl;
std::cout << "Avg = " << (std::accumulate(v.begin(), v.end(), 0.0) / kSampleSize) << std::endl;
std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
std::cout << "Median = " << v[v.size()/2] << std::endl << std::endl;
}
int main() {
std::cout << "Salsa20" << std::endl;
hamming(salsa_core);
std::cout << "Sorsa20" << std::endl;
hamming(sorsa_core);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment