@@ -532,15 +532,53 @@ impl<'a> Arbitrary<'a> for MerkleBlock {
532532mod tests {
533533 use hex:: { DisplayHex , FromHex } ;
534534 use hex_lit:: hex;
535- #[ cfg( all ( feature = "rand" , feature = " std") ) ]
536- use { core:: cmp, secp256k1 :: rand :: prelude :: * } ;
535+ #[ cfg( feature = "std" ) ]
536+ use core:: cmp;
537537
538538 use super :: * ;
539539 use crate :: block:: Unchecked ;
540540 use crate :: consensus:: encode;
541541 use crate :: Txid ;
542542
543- #[ cfg( all( feature = "rand" , feature = "std" ) ) ]
543+ // `bloc` in hex.
544+ #[ cfg( feature = "std" ) ]
545+ const PRNG_SEED : usize = 0x626C6F63 ;
546+
547+ // Simple and deterministic PRNG, not suitable for cryptographic use cases.
548+ #[ cfg( feature = "std" ) ]
549+ struct LcgPrng {
550+ state : usize ,
551+ }
552+
553+ #[ cfg( feature = "std" ) ]
554+ impl LcgPrng {
555+ const P : usize = 1039 ;
556+ const Q : usize = 677 ;
557+
558+ const fn new ( seed : usize ) -> Self {
559+ Self {
560+ state : seed
561+ }
562+ }
563+
564+ #[ inline]
565+ fn next_usize ( & mut self ) -> usize {
566+ self . state = self . state . wrapping_mul ( Self :: P ) . wrapping_add ( Self :: Q ) ;
567+ self . state
568+ }
569+
570+ #[ inline]
571+ fn next_in_range ( & mut self , max : usize ) -> usize {
572+ self . next_usize ( ) % max
573+ }
574+
575+ #[ inline]
576+ fn next_u8 ( & mut self ) -> u8 {
577+ self . next_usize ( ) . to_le_bytes ( ) [ 0 ]
578+ }
579+ }
580+
581+ #[ cfg( feature = "std" ) ]
544582 macro_rules! pmt_tests {
545583 ( $( $name: ident) ,* $( , ) ?) => {
546584 $(
@@ -552,7 +590,7 @@ mod tests {
552590 }
553591 }
554592
555- #[ cfg( all ( feature = "rand" , feature = " std") ) ]
593+ #[ cfg( feature = "std" ) ]
556594 pmt_tests ! (
557595 pmt_test_1,
558596 pmt_test_4,
@@ -569,12 +607,12 @@ mod tests {
569607 ) ;
570608
571609 /// Parses the transaction count out of `name` with form: `pmt_test_$num`.
572- #[ cfg( all ( feature = "rand" , feature = " std") ) ]
610+ #[ cfg( feature = "std" ) ]
573611 fn pmt_test_from_name ( name : & str ) { pmt_test ( name[ 9 ..] . parse ( ) . unwrap ( ) ) }
574612
575- #[ cfg( all ( feature = "rand" , feature = " std") ) ]
613+ #[ cfg( feature = "std" ) ]
576614 fn pmt_test ( tx_count : usize ) {
577- let mut rng = secp256k1 :: rand :: rng ( ) ;
615+ let mut rng = LcgPrng :: new ( PRNG_SEED ^ tx_count ) ;
578616 // Create some fake tx ids
579617 let tx_ids = ( 1 ..=tx_count)
580618 . map ( |i| format ! ( "{:064x}" , i) . parse :: < Txid > ( ) . unwrap ( ) )
@@ -598,7 +636,7 @@ mod tests {
598636 // Generate `att / 2` random bits
599637 let rand_bits = match att / 2 {
600638 0 => 0 ,
601- bits => rng. random :: < u64 > ( ) >> ( 64 - bits) ,
639+ bits => rng. next_usize ( ) . rotate_right ( 64 - bits) ,
602640 } ;
603641 let include = rand_bits == 0 ;
604642 matches[ j] = include;
@@ -742,12 +780,12 @@ mod tests {
742780 assert_eq ! ( index. len( ) , 0 ) ;
743781 }
744782
745- #[ cfg( all ( feature = "rand" , feature = " std") ) ]
783+ #[ cfg( feature = "std" ) ]
746784 impl PartialMerkleTree {
747785 /// Flip one bit in one of the hashes - this should break the authentication
748- fn damage ( & mut self , rng : & mut ThreadRng ) {
749- let n = rng. random_range ( 0 .. self . hashes . len ( ) ) ;
750- let bit = rng. random :: < u8 > ( ) ;
786+ fn damage ( & mut self , rng : & mut LcgPrng ) {
787+ let n = rng. next_in_range ( self . hashes . len ( ) ) ;
788+ let bit = rng. next_u8 ( ) ;
751789 let hashes = & mut self . hashes ;
752790 let mut hash = hashes[ n] . to_byte_array ( ) ;
753791 hash[ ( bit >> 3 ) as usize ] ^= 1 << ( bit & 7 ) ;
0 commit comments