Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Ashitemaru/Sharnn
Browse files Browse the repository at this point in the history
  • Loading branch information
c7w committed May 15, 2022
2 parents aeab039 + 42415b9 commit 45aec43
Show file tree
Hide file tree
Showing 17 changed files with 470 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
cmake-build-*/
bin/
build/
<<<<<<< HEAD
.vscode/*
assess
=======
.vscode/
>>>>>>> origin/master
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ ADD_TEST(test1)
ADD_TEST(test2)
ADD_TEST(test3)
ADD_TEST(test4)

71 changes: 67 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,73 @@ $$

### Security

// TODO
#### Random Number Testing

### Ablation Tests
​ 我们使用NIST提供的 [Statistical Test Suite](https://csrc.nist.gov/Projects/Random-Bit-Generation/Documentation-and-Software) 对哈希结果的随机性进行检测。

我们在实验框架中分模块编写了单元测试,下面列举一下测试的结果。
​ 首先生成哈希序列。在 $[0,2^{31}-1)$ 中从零开始均匀选取 $2^{21}$ 个数字,将数字对应的 $32$ 位整数作为输入进行哈希,得到 $20MB$ 输出。使用 NIST Statistical Test Suite 基于多种度量进行随机性测试。默认参数选择 $n=1,500,000$ 可符合大部分测试的要求,按文档[6] 要求使用其他参数的,在下表最后一列注明。

| 编号 | 测试类型 | 通过率 | p值均匀性 | 非默认参数 |
| ---- | ------------------------------ | ----------- | ------------ | ------------------------------- |
| 01 | Frequency | 111/111 | 0.580520 | - |
| 02 | Block Frequency | 20758/20971 | 0.273558 | $n=8000,M=80$ |
| 03 | Cumulative Sums | 2/2$^1$ | 通过$^1$ | - |
| 04 | Runs | 111/111 | 0.263452 | - |
| 05 | Longest Run of Ones | 109/111 | 0.656043 | - |
| 06 | Rank | 109/111 | 0.328861 | - |
| 07 | Discrete Fourier Transform | 111/111 | 0.674920 | - |
| 08 | Nonperiodic Template Matchings | 0/148$^1$ | 不通过$^1$ | $n=8000$ |
| 09 | Overlapping Template Matchings | 111/111 | 0.003401 | $m=10$ |
| 10 | Universal Statistical | 54/55 | 0.719747 | $n=3,000,000$,此时 $L=8$ |
| 11 | Approximate Entropy | 110/111 | 0.000086$^2$ | $m=\lfloor \log_2 n \rfloor -6$ |
| 12 | Random Excursions | 8/8$^1$ | 通过$^1$ | - |
| 13 | Random Excursions Variant | 18/18$^1$ | 通过$^1$ | - |
| 14 | Serial | 2/2$^1$ | 通过$^1$ | $m=\lfloor \log_2 n \rfloor -3$ |
| 15 | Linear Complexity | 110/111 | 0.818179 | - |

注:

1. 表示该检测度量有多个指标
2. 表示该指标的 $p$ 值过小,表示 $p$ 值分布不提示均匀分布




#### Diffusion Test

为了度量哈希的扩散效果,我们对 $SHA-RNN$ 算法进行了扩散测试

- 输入串 $M$,计算哈希值 $H_1$ ,对于 $M$ 我们选取 Wikipedia 中对海绵结构的介绍

> In cryptography, a sponge function or sponge construction is any of a class of algorithms with finite internal state that take an input bit stream of any length and produce an output bit stream of any desired length. Sponge functions have both theoretical and practical uses. They can be used to model or implement many cryptographic primitives, including cryptographic hashes, message authentication codes, mask generation functions, stream ciphers, pseudo-random number generators, and authenticated encryption.
> Sponge functions have both theoretical and practical uses. In theoretical cryptanalysis, a random sponge function is a sponge construction where f is a random permutation or transformation, as appropriate. Random sponge functions capture more of the practical limitations of cryptographic primitives than does the widely used random oracle model, in particular the finite internal state.
- 对串 $M$ 随机选取一位进行翻转,然后再计算哈希值 $H'$
- 计算 $H$ 和 $H'$ 中不同有位数的数量 $B_i$

将上述过程在 $SHA-RNN$ 算法中重复 $N=10,000$ 次,结果如下图所示

<img src="https://s1.ax1x.com/2022/05/15/ORaSz9.png" style="zoom: 33%;" />

定量计算

1. 改变位数的最小值

​ $B_{\min }=\min \left(\left\{B_{i}\right\}_{i=1, \ldots, N}\right)$

2. 改变位数的最大值
$B_{\max }=\max \left(\left\{B_{i}\right\}_{i=1, \ldots, N}\right)$
3. 改变位数的标准差
$\Delta B=\sqrt{\frac{1}{N-1} \sum_{i=1}^{N}\left(B_{i}-\bar{B}\right)^{2}}$
4. 改变位数的平均值
$\bar{B}=\frac{1}{N} \sum_{i=1}^{N} B_{i}$
5. 每位的改变概率
$P=\left(\frac{\bar{B}}{80}\right) \times 100 \%$


| 最小值 | 最大值 | 标准差 | 平均值 | 每位变化概率 |
| ------ | ------ | ------ | ------ | ------------ |
| 21 | 50 | 4.14 | 35.00 | 43.75% |

#### DSTMap

Expand All @@ -238,9 +300,10 @@ $$

[4] Hasler M, Maistrenko Y L. An introduction to the synchronization of chaotic systems: coupled skew tent maps[J]. IEEE Transactions on Circuits and Systems I: Fundamental Theory and Applications, 1997, 44(10): 856-866.


[5] Penard W, van Werkhoven T. On the secure hash algorithm family[J]. Cryptography in context, 2008: 1-18.

[6] Bassham, L. , Rukhin, A. , Soto, J. , Nechvatal, J. , Smid, M. , Leigh, S. , Levenson, M. , Vangel, M. , Heckert, N. and Banks, D. (2010), A Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications, Special Publication (NIST SP), National Institute of Standards and Technology, Gaithersburg, MD.



## Appendix: Introduction to Codebase
Expand Down
16 changes: 16 additions & 0 deletions src/Bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ class Bitset {
return ss.str();
}

std::string to_bytes() {
std::string ret;
ret.insert(0, (char *)data, n);
return ret;
}

std::size_t one_count() {
std::size_t count {0};
for (int i = 0; i < n; i++) {
for (int j = 0; j < 7; j++) {
if (data[i] & (1 << j)) count++;
}
}
return count;
}

private:
byte data[n]{};
void init_with(const byte *input, int k) {
Expand Down
1 change: 1 addition & 0 deletions src/ChaoticSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "../include/define.h"
#include "ChaoticMap.hpp"
#include "../include/define.h"

class ChaoticSystem {
public:
Expand Down
6 changes: 6 additions & 0 deletions src/NonLinear.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#pragma once

#include <algorithm>
#include <cstdint>
#include "../include/define.h"
#include <type_traits>
#include <bitset>


#include "ChaoticSystem.hpp"

template <int N, int O, typename std::enable_if<N % 5 == 0, bool>::type = true>
Expand Down
12 changes: 3 additions & 9 deletions src/PaddedStream.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include <cstdint>
#include <iostream>

#include "../include/define.h"
using byte = uint8_t;

// multi-rate padding
class PaddedStream {
Expand All @@ -27,14 +29,6 @@ class PaddedStream {
} else {
finished = false;
}

// Debug: print the block[0:block_size] to stdout
// for (int i = 0; i < block_size; ++i) {
// std::cout << std::bitset<8>(block[i]) << " ";
// }
// std::cout << std::endl;


return finished;
}

Expand Down
62 changes: 31 additions & 31 deletions src/RNNHash.hpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
#pragma once

#include "NonLinear.hpp"
#include "RNN.hpp"
#include "SpongeHash.hpp"

class RNNHash : public SpongeHash<136, 64, 10> {
public:
RNNHash() : SpongeHash(HM_t{}) {
}
~RNNHash() override = default;
void sponge_F(HM_t &h, uint32_t km) override {
DSTChaoticSystem cs(cs_q, km, cs_ks, cs_us);
RNN<200> rnn{&cs};
NonLinear<10, 50> nl{nl_nr, &cs};

rnn.forward(h, wo);
nl.forward(wo, out);

for (int i = 0; i < 50; i++) {
h.ptr()[i * 4 + 0] = (out[i] & 0xFF000000) >> 24;
h.ptr()[i * 4 + 1] = (out[i] & 0x00FF0000) >> 16;
h.ptr()[i * 4 + 2] = (out[i] & 0x0000FF00) >> 8;
h.ptr()[i * 4 + 3] = (out[i] & 0x000000FF);
}
}

private:
const static uint32_t cs_q = 0x789ABCDE, cs_ks = 0x10, cs_us = 10,
nl_nr = 8;
uint32_t wo[10]{}, out[50]{};
#pragma once

#include "NonLinear.hpp"
#include "RNN.hpp"
#include "SpongeHash.hpp"

class RNNHash : public SpongeHash<136, 64, 10> {
public:
RNNHash() : SpongeHash(HM_t{}) {
}
~RNNHash() override = default;
void sponge_F(HM_t &h, uint32_t km) override {
DSTChaoticSystem cs(cs_q, km, cs_ks, cs_us);
RNN<200> rnn{&cs};
NonLinear<10, 50> nl{nl_nr, &cs};

rnn.forward(h, wo);
nl.forward(wo, out);

for (int i = 0; i < 50; i++) {
h.ptr()[i * 4 + 0] = (out[i] & 0xFF000000) >> 24;
h.ptr()[i * 4 + 1] = (out[i] & 0x00FF0000) >> 16;
h.ptr()[i * 4 + 2] = (out[i] & 0x0000FF00) >> 8;
h.ptr()[i * 4 + 3] = (out[i] & 0x000000FF);
}
}

private:
const static uint32_t cs_q = 0x789ABCDE, cs_ks = 0x10, cs_us = 10,
nl_nr = 8;
uint32_t wo[10]{}, out[50]{};
};
4 changes: 3 additions & 1 deletion src/SpongeHash.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include "../include/define.h"
#include <chrono>
#include <type_traits>

#include "Bitset.hpp"
#include "PaddedStream.hpp"

Expand Down
3 changes: 3 additions & 0 deletions statistics/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gen:
g++ sample.cpp -o main
# ./main
81 changes: 81 additions & 0 deletions statistics/analyze.ipynb

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions statistics/defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const int block_size {136};
const int filp_count {10000};
72 changes: 72 additions & 0 deletions statistics/diffusion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <fstream>
#include <random>
#include <chrono>
#include <vector>
#include <iostream>
#include <algorithm>

#include "../src/RNNHash.hpp"
#include "../include/define.h"

const int flip_count {10000};


void flip_test() {
std::ifstream s {"text.in", std::ifstream::binary};
std::ofstream record {"diffusion.out"};
std::stringstream ssbuf;
ssbuf << s.rdbuf();
auto stream {ssbuf.str()};

auto buf = new byte[stream.size()];
std::copy(stream.begin(), stream.end(), buf);
std::cerr << buf << std::endl;

std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> byte_dist(0, stream.size() - 1);
std::uniform_int_distribution<std::mt19937::result_type> bit_dist(0, 7);

RNNHash h;
RNNHash::Out_t original = h(ssbuf);
// record << stream << std::endl;
// record << original.to_binary_string() << std::endl << std::endl;


for (int i = 0; i < flip_count; i++) {
auto bit_r {bit_dist(rng)};
auto byte_r {byte_dist(rng)};
auto byte_buf = buf + byte_r;

*byte_buf = ~ ((*byte_buf) | (0xff ^ (1 << bit_r))) | ((*byte_buf) & (0xff ^ (1 << bit_r)));

std::stringstream input;
std::string new_stream {(char *)buf};
input.str(new_stream);

RNNHash hash;
RNNHash::Out_t out = hash(input);
// std::cerr << new_stream << std::endl;
// record << "flip byte: " << byte_r << "; bit: " << bit_r << std::endl;
// record << out.to_binary_string() << std::endl;
out ^= original;
record << out.one_count() << std::endl;
// if (out.one_count() == 0) {
// std::fstream opt {"1.bin"};
// std::ofstream ori{"2.bin"};
// opt << new_stream << std::endl;
// ori << stream << std::endl;
// exit(0);
// }

*byte_buf = ~ ((*byte_buf) | (0xff ^ (1 << bit_r))) | ((*byte_buf) & (0xff ^ (1 << bit_r)));
}

}

int main() {

flip_test();

return 0;
}
Loading

0 comments on commit 45aec43

Please sign in to comment.