The following code generates a deterministic stream of pseudo-random bytes, using 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
is the hash of a compressed, whitened, long passphrase. nonce
s must not be reused.)
If I XOR this stream with a file, will I get strong encryption?
Or are there weaknesses which I haven't considered?
P.S. The results of dieharder, on 1 MB of output, look reasonable - but I am not sure how to judge them. Is a single WEAK a problem?
$ 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