44#![ allow( non_snake_case) ]
55#![ deny( missing_docs) ]
66
7- // XXX we should use Sha3 everywhere
8- use sha2:: { Digest , Sha512 } ;
9-
107use curve25519_dalek:: ristretto:: RistrettoPoint ;
118use curve25519_dalek:: scalar:: Scalar ;
129use curve25519_dalek:: traits:: MultiscalarMul ;
1310
11+ use digest:: { ExtendableOutput , Input , XofReader } ;
12+ use sha3:: { Sha3XofReader , Shake256 } ;
13+
1414/// The `GeneratorsChain` creates an arbitrary-long sequence of orthogonal generators.
1515/// The sequence can be deterministically produced starting with an arbitrary point.
1616struct GeneratorsChain {
17- next_point : RistrettoPoint ,
17+ reader : Sha3XofReader ,
1818}
1919
2020impl GeneratorsChain {
2121 /// Creates a chain of generators, determined by the hash of `label`.
2222 fn new ( label : & [ u8 ] ) -> Self {
23- let mut hash = Sha512 :: default ( ) ;
24- hash. input ( b"GeneratorsChainInit" ) ;
25- hash. input ( label) ;
26- let next_point = RistrettoPoint :: from_hash ( hash) ;
27- GeneratorsChain { next_point }
23+ let mut shake = Shake256 :: default ( ) ;
24+ shake. process ( b"GeneratorsChain" ) ;
25+ shake. process ( label) ;
26+
27+ GeneratorsChain {
28+ reader : shake. xof_result ( ) ,
29+ }
2830 }
2931}
3032
@@ -36,13 +38,16 @@ impl Default for GeneratorsChain {
3638
3739impl Iterator for GeneratorsChain {
3840 type Item = RistrettoPoint ;
41+
3942 fn next ( & mut self ) -> Option < Self :: Item > {
40- let current_point = self . next_point ;
41- let mut hash = Sha512 :: default ( ) ;
42- hash. input ( b"GeneratorsChainNext" ) ;
43- hash. input ( current_point. compress ( ) . as_bytes ( ) ) ;
44- self . next_point = RistrettoPoint :: from_hash ( hash) ;
45- Some ( current_point)
43+ let mut uniform_bytes = [ 0u8 ; 64 ] ;
44+ self . reader . read ( & mut uniform_bytes) ;
45+
46+ Some ( RistrettoPoint :: from_uniform_bytes ( & uniform_bytes) )
47+ }
48+
49+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
50+ ( usize:: max_value ( ) , None )
4651 }
4752}
4853
0 commit comments