Encryption

使用 sha3 作為 xor 加密的偽隨機字節的確定性來源

  • September 24, 2020

以下程式碼使用 SHA3 生成確定性的偽隨機字節流。

use sha3::{Digest, Sha3_256};

pub struct ShaStream {
   passhash: [u8; 32],
   nonce: [u8; 32],
   index: u64,
   block: [u8; 32],
   hasher: Sha3_256,
}
   
impl ShaStream {
   pub fn new(passhash: [u8; 32], nonce: [u8; 32]) -> ShaStream {
       ShaStream {passhash, nonce, index: 0, block: [0; 32], hasher: Sha3_256::new()}
   }
}

impl Iterator for ShaStream {
   type Item = u8;
   
   fn next(&mut self) -> Option<u8> {
       // make a new block, every 32 bytes
       if self.index % 32 == 0 {
           self.hasher.update(self.index.to_be_bytes());
           self.hasher.update(self.passhash);
           self.hasher.update(self.block);
           self.hasher.update(self.nonce);
           self.block = self.hasher.finalize_reset().into();
       }
       let value = self.block[self.index as usize % 32];
       self.index += 1;
       Some(value)
   }
}

passhash是壓縮的、白化的、長密碼片語的雜湊值。s nonce不得重複使用。)

如果我將此流與文件進行異或,我會得到強加密嗎?

還是有我沒有考慮到的弱點?

PS 頑固派的結果,在 1 MB 的輸出上,看起來很合理 - 但我不知道如何判斷它們。單 WEAK 有問題嗎?

$ dieharder -a -f xor.bin 
#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
  rng_name    |           filename             |rands/second|
       mt19937|                         xor.bin|  1.02e+08  |
#=============================================================================#
       test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
  diehard_birthdays|   0|       100|     100|0.23634314|  PASSED  
     diehard_operm5|   0|   1000000|     100|0.44073675|  PASSED  
 diehard_rank_32x32|   0|     40000|     100|0.09071670|  PASSED  
   diehard_rank_6x8|   0|    100000|     100|0.98413526|  PASSED  
  diehard_bitstream|   0|   2097152|     100|0.80928251|  PASSED  
       diehard_opso|   0|   2097152|     100|0.30077190|  PASSED  
       diehard_oqso|   0|   2097152|     100|0.91046849|  PASSED  
        diehard_dna|   0|   2097152|     100|0.23134815|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.28623905|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.53924476|  PASSED  
diehard_parking_lot|   0|     12000|     100|0.68281092|  PASSED  
   diehard_2dsphere|   2|      8000|     100|0.78529773|  PASSED  
   diehard_3dsphere|   3|      4000|     100|0.31723984|  PASSED  
    diehard_squeeze|   0|    100000|     100|0.96834170|  PASSED  
       diehard_sums|   0|       100|     100|0.48488812|  PASSED  
       diehard_runs|   0|    100000|     100|0.83280719|  PASSED  
       diehard_runs|   0|    100000|     100|0.91027127|  PASSED  
      diehard_craps|   0|    200000|     100|0.37347197|  PASSED  
      diehard_craps|   0|    200000|     100|0.91605252|  PASSED  
marsaglia_tsang_gcd|   0|  10000000|     100|0.67400210|  PASSED  
marsaglia_tsang_gcd|   0|  10000000|     100|0.36182964|  PASSED  
        sts_monobit|   1|    100000|     100|0.04375935|  PASSED  
           sts_runs|   2|    100000|     100|0.99425607|  PASSED  
         sts_serial|   1|    100000|     100|0.82838574|  PASSED  
         sts_serial|   2|    100000|     100|0.86544431|  PASSED  
         sts_serial|   3|    100000|     100|0.82113526|  PASSED  
         sts_serial|   3|    100000|     100|0.99367519|  PASSED  
         sts_serial|   4|    100000|     100|0.43314255|  PASSED  
         sts_serial|   4|    100000|     100|0.81866202|  PASSED  
         sts_serial|   5|    100000|     100|0.50034343|  PASSED  
         sts_serial|   5|    100000|     100|0.64324459|  PASSED  
         sts_serial|   6|    100000|     100|0.88971853|  PASSED  
         sts_serial|   6|    100000|     100|0.97804225|  PASSED  
         sts_serial|   7|    100000|     100|0.82763353|  PASSED  
         sts_serial|   7|    100000|     100|0.73522587|  PASSED  
         sts_serial|   8|    100000|     100|0.99950104|   WEAK
         sts_serial|   8|    100000|     100|0.50056257|  PASSED  
         sts_serial|   9|    100000|     100|0.17834420|  PASSED  
         sts_serial|   9|    100000|     100|0.81670387|  PASSED  
         sts_serial|  10|    100000|     100|0.06053301|  PASSED  
         sts_serial|  10|    100000|     100|0.16833877|  PASSED  
         sts_serial|  11|    100000|     100|0.45143111|  PASSED  
         sts_serial|  11|    100000|     100|0.90007517|  PASSED  
         sts_serial|  12|    100000|     100|0.29181206|  PASSED  
         sts_serial|  12|    100000|     100|0.23372932|  PASSED  
         sts_serial|  13|    100000|     100|0.26269445|  PASSED  
         sts_serial|  13|    100000|     100|0.39691685|  PASSED  
         sts_serial|  14|    100000|     100|0.27804065|  PASSED  
         sts_serial|  14|    100000|     100|0.55210331|  PASSED  
         sts_serial|  15|    100000|     100|0.02302363|  PASSED  
         sts_serial|  15|    100000|     100|0.04573078|  PASSED  
         sts_serial|  16|    100000|     100|0.03990599|  PASSED  
         sts_serial|  16|    100000|     100|0.96326029|  PASSED  
        rgb_bitdist|   1|    100000|     100|0.84215365|  PASSED  
        rgb_bitdist|   2|    100000|     100|0.49349609|  PASSED  
        rgb_bitdist|   3|    100000|     100|0.18203352|  PASSED  
        rgb_bitdist|   4|    100000|     100|0.42475472|  PASSED  
        rgb_bitdist|   5|    100000|     100|0.24511091|  PASSED  
        rgb_bitdist|   6|    100000|     100|0.92089949|  PASSED  
        rgb_bitdist|   7|    100000|     100|0.84628916|  PASSED  
        rgb_bitdist|   8|    100000|     100|0.22711540|  PASSED  
        rgb_bitdist|   9|    100000|     100|0.34303650|  PASSED  
        rgb_bitdist|  10|    100000|     100|0.59588524|  PASSED  
        rgb_bitdist|  11|    100000|     100|0.91612653|  PASSED  
        rgb_bitdist|  12|    100000|     100|0.27207545|  PASSED  
rgb_minimum_distance|   2|     10000|    1000|0.75765186|  PASSED  
rgb_minimum_distance|   3|     10000|    1000|0.34765391|  PASSED  
rgb_minimum_distance|   4|     10000|    1000|0.56023937|  PASSED  
rgb_minimum_distance|   5|     10000|    1000|0.79620902|  PASSED  
   rgb_permutations|   2|    100000|     100|0.99300316|  PASSED  
   rgb_permutations|   3|    100000|     100|0.28066491|  PASSED  
   rgb_permutations|   4|    100000|     100|0.36539121|  PASSED  
   rgb_permutations|   5|    100000|     100|0.33314486|  PASSED  
     rgb_lagged_sum|   0|   1000000|     100|0.15207425|  PASSED  
     rgb_lagged_sum|   1|   1000000|     100|0.07013932|  PASSED  
     rgb_lagged_sum|   2|   1000000|     100|0.27477884|  PASSED  
     rgb_lagged_sum|   3|   1000000|     100|0.95111023|  PASSED  
     rgb_lagged_sum|   4|   1000000|     100|0.02796184|  PASSED  
     rgb_lagged_sum|   5|   1000000|     100|0.45874461|  PASSED  
     rgb_lagged_sum|   6|   1000000|     100|0.18328909|  PASSED  
     rgb_lagged_sum|   7|   1000000|     100|0.02821152|  PASSED  
     rgb_lagged_sum|   8|   1000000|     100|0.16271011|  PASSED  
     rgb_lagged_sum|   9|   1000000|     100|0.63672591|  PASSED  
     rgb_lagged_sum|  10|   1000000|     100|0.97828167|  PASSED  
     rgb_lagged_sum|  11|   1000000|     100|0.71885077|  PASSED  
     rgb_lagged_sum|  12|   1000000|     100|0.75394600|  PASSED  
     rgb_lagged_sum|  13|   1000000|     100|0.61132545|  PASSED  
     rgb_lagged_sum|  14|   1000000|     100|0.36991248|  PASSED  
     rgb_lagged_sum|  15|   1000000|     100|0.98795179|  PASSED  
     rgb_lagged_sum|  16|   1000000|     100|0.39086917|  PASSED  
     rgb_lagged_sum|  17|   1000000|     100|0.72342485|  PASSED  
     rgb_lagged_sum|  18|   1000000|     100|0.32210912|  PASSED  
     rgb_lagged_sum|  19|   1000000|     100|0.23889372|  PASSED  
     rgb_lagged_sum|  20|   1000000|     100|0.02979572|  PASSED  
     rgb_lagged_sum|  21|   1000000|     100|0.99132612|  PASSED  
     rgb_lagged_sum|  22|   1000000|     100|0.63051091|  PASSED  
     rgb_lagged_sum|  23|   1000000|     100|0.40911221|  PASSED  
     rgb_lagged_sum|  24|   1000000|     100|0.95798515|  PASSED  
     rgb_lagged_sum|  25|   1000000|     100|0.81390689|  PASSED  
     rgb_lagged_sum|  26|   1000000|     100|0.21471266|  PASSED  
     rgb_lagged_sum|  27|   1000000|     100|0.97590860|  PASSED  
     rgb_lagged_sum|  28|   1000000|     100|0.65097372|  PASSED  
     rgb_lagged_sum|  29|   1000000|     100|0.40351426|  PASSED  
     rgb_lagged_sum|  30|   1000000|     100|0.67212314|  PASSED  
     rgb_lagged_sum|  31|   1000000|     100|0.36602753|  PASSED  
     rgb_lagged_sum|  32|   1000000|     100|0.54699284|  PASSED  
    rgb_kstest_test|   0|     10000|    1000|0.47824082|  PASSED  
    dab_bytedistrib|   0|  51200000|       1|0.27617055|  PASSED  
            dab_dct| 256|     50000|       1|0.06378066|  PASSED  
Preparing to run test 207.  ntuple = 0
       dab_filltree|  32|  15000000|       1|0.51156512|  PASSED  
       dab_filltree|  32|  15000000|       1|0.77505955|  PASSED  
Preparing to run test 208.  ntuple = 0
      dab_filltree2|   0|   5000000|       1|0.92507779|  PASSED  
      dab_filltree2|   1|   5000000|       1|0.86783259|  PASSED  
Preparing to run test 209.  ntuple = 0
       dab_monobit2|  12|  65000000|       1|0.39811014|  PASSED  

我認為大家的共識是,這並沒有什麼明顯的不安全之處,而且我可以安全地用我的扳手敲入釘子。

只要使用的散列也可以用作 CSPRNG,就可以了。任何(安全)散列算法都會在這個模型中創建一個安全的流密碼。

應該注意的是,並非所有散列算法都必須充當 CSPRNG。這不是安全散列的要求,並且在沒有此屬性的情況下構造了安全散列。然而,我在說明這一點時引用的散列算法很少使用,也很少為人所知。SHA-3 充當 CSPRNG,因此此註釋與您的情況無關。

在雜湊的狀態重複後,密文確實變得可與隨機區分開來。例如,一個 512 位的散列在 $ 512 * 2^{512} $ 位。之後的 384 位雜湊 $ 384 * 2^{384} $ 位…你明白了。

引用自:https://crypto.stackexchange.com/questions/84035