Browse Source

PIP-0009: fixed pseudo-code changes from prior modifications

Herman Schoenfeld 7 years ago
parent
commit
01524ed93a
1 changed files with 49 additions and 40 deletions
  1. 49 40
      PIP/PIP-0009.md

+ 49 - 40
PIP/PIP-0009.md

@@ -37,12 +37,12 @@ A low-memory, GPU and ASIC-resistant hash algorithm called **Random Hash** is pr
 
 1. Hashing a nonce requires ```N``` iterations (called rounds)
 2. Each round selects a random hash function from a set of 16 well-known hash algorithms
-3. The input at round ```x``` depends on round ```x-1```
-4. The input at round x depends on round ```x-1``` **of a different nonce** determined based on the output from round ```x-1``` for the current nonce
-5. The input at round ```x``` is a compression of the outputs of every contributing stage to ```100 bytes```
+3. The input at round ```x``` is salted with the outputs of all prior rounds
+4. The input at round ```x``` is salted with the output of all prior rounds **of a different nonce**, randomly determined
+5. The input at round ```x``` is a compression of the transitive closure of prior/neighbouring round outputs to the size of ```100 bytes```
 6. The output of every round is expanded for memory-hardness
 7. Randomness is generated using ```Mersenne Twister``` algorithm
-8. Randomness is seeded via ```MurMur3``` checksum of previous round
+8. Randomness is seeded via ```MurMur3``` checksum of current round
 9. The final round is then hashed again via ```SHA2_256```, in keeping with traditional cryptocurrency approaches.
 
 ### RandomHash Design
@@ -56,16 +56,18 @@ A low-memory, GPU and ASIC-resistant hash algorithm called **Random Hash** is pr
             SHA2_256
             SHA2_384
             SHA2_512
-            SHA3,
+            SHA3_256,
+            SHA3_384,
+            SHA3_512,
             RIPEMD160,
             RIPEMD256,
             RIPEMD320,
             Blake2b, 
             Blake2s,
-            Tiger2,
-            Snerfu,
+            Tiger2_5_192,
+            Snefru_8_256,
             Grindahl512,
-            Haval,
+            Haval_5_256,
             MD5
             RadioGatun32
             Whirlpool
@@ -73,54 +75,56 @@ A low-memory, GPU and ASIC-resistant hash algorithm called **Random Hash** is pr
         N = 5           // Number of hashing rounds required to compute a nonce (total rounds = 2^N - 1)
         M = 10KB        // The memory expansion unit (in bytes)
 
-        Function RandomHash(blockHeader : ByteArray)
+        Function RandomHash(blockHeader : ByteArray) : ByteArray
         begin
-            let AllOutputs = RandomHash( blockHeader, N)
-            seed = Checksum(neighborOutputs[Length(AllOutputs) - 1])
-            Result := SHA2_256( Compress(AllOutputs, RandomNumberGenerator(seed)) )
+            let allOutputs = RandomHash( blockHeader, N)
+            Result := SHA2_256( Compress( allOutputs ) )
         end
 
-        Function RandomHash(blockHeader : ByteArray, Round : Integer) : list of ByteArray
+        Function RandomHash(blockHeader : ByteArray, Round : Integer) : List of ByteArray
         begin
-            let RoundOutputs = list of ByteArray;
+            if Round < 1 or Round > N then
+                Error 'Round must be between 0 and N inclusive'
+
+            let roundOutputs = new List of ByteArray;
             
             if Round = 1 then
                 let seed = Checksum(blockHeader)      // can hash blockHeader first, but not required
                 let gen = RandomNumberGenerator(seed)
-                let input = blockHeader
+                let roundInput = blockHeader
             else
                 let parentOutputs = RandomHash(blockHeader, Round - 1)
-                RoundOutputs.addAll(parentOutputs)
-                let seed = Checksum(neighborOutputs[Length(neighborOutputs) - 1])
+                let seed = Checksum(parentOutputs)
                 let gen = RandomNumberGenerator(seed)
+
+                roundOutputs.AddMany(parentOutputs)
                 
                 let otherNonceHeader = ChangeNonce(blockHeader, gen.NextDWord)
                 let neighborOutputs = RandomHash(blockHeader, Round - 1)
-                RoundOutputs.addAll(neighborOutput)
+                roundOutputs.AddMany(neighborOutputs)
                 
-                // re-seed RNG based on random other nonce output
-                seed = Checksum(neighborOutputs[Length(neighborOutputs) - 1])
-                gen = RandomNumberGenerator(seed)
-                let input = Compress(RoundOutputs, gen)
+                let roundInput = Compress(roundOutputs)
             
-            let hashFunc = HASH_ALGO[gen.NextDWord % 16]   
-            let output = hashFunc(input)                
-            output = Expand( output, N - i, gen )
-            RoundOutputs.add(output)
+            let hashFunc = HASH_ALGO[gen.NextDWord % 18]   
+            let output = hashFunc(roundInput)                
+            output = Expand( output, N - Round )
+            roundOutputs.Add(output)
 
-            Result := RoundOutputs
+            Result := roundOutputs
         end
 
 
-        function Expand(input : ByteArray, ExpansionFactor : Integer, gen : RandomNumberGenerator) : ByteArray
+        function Expand(input : ByteArray, ExpansionFactor : Integer) : ByteArray
         begin
-            let Size = Length(input) + ExpansionFactor*M;
+            let seed = Checksum(input)
+            let gen = RandomNumberGenerator(seed)
+            let size = Length(input) + ExpansionFactor*M;
             let output = input.Clone
-            let bytesToAdd = Size - Length(input)
-            while output < Size do
+            let bytesToAdd = size - Length(input)
+            while bytesToAdd > 0 do
                 let nextChunk = output.Clone
-                if Length(output) + Length(nextChunk) > Size then
-                    SetLength(nextChunk, Size - Length(output))
+                if Length(nextChunk) > bytesToAdd then
+                    SetLength(nextChunk, bytesToAdd)
 
                 let random = gen.NextDWord
                 case random % 8 do
@@ -130,31 +134,35 @@ A low-memory, GPU and ASIC-resistant hash algorithm called **Random Hash** is pr
                                 .
                                 .
                     7: output = output ++ MemTransform8(nextChunk)
-
+                bytesToAdd = bytesToAdd - Length(nextChunk)
             Result = output
         end
 
-        function Compress(inputs : list of ByteArray, gen : RandomNumberGenerator) : ByteArray
+        function Compress(inputs : list of ByteArray) : ByteArray
         begin
+            let seed = Checksum(inputs)
+            let gen = RandomNumberGenerator(seed)
             let output = Byte[0..99]
-
             for i = 0 to 99 do
                 let source = inputs[ gen.NextDWord % Length(inputs) ]
                 output[i] = source[ gen.NextDWord % Length(source) ]
-
             Result := output
         end 
 
         function ChangeNonce(blockHeader : ByteArray, nonce : Integer) : ByteArray
         begin
-            // changes nonce in blockHeader by knowing offset of nonce
+            // clones and changes nonce in blockHeader (by determining offset of nonce)
         end
 
-
         Function Checksum(input : ByteArray) : DWord
         begin
             // standard MurMu3 algorithm
         end
+    
+        Function Checksum(inputs : List of ByteArray) : DWord
+        begin
+            // standard MurMu3 algorithm run over list of inputs
+        end
 
         Function RandomNumberGenerator(seed : DWord) : TMersenneTwister
             // standard Mersenne Twister random number generator (or other suitably chosen algorithm)
@@ -163,7 +171,7 @@ A low-memory, GPU and ASIC-resistant hash algorithm called **Random Hash** is pr
 
 #### Memory transform methods
 
-These methods are iteratively and randomly applied to a hash output in order to rapidly expand it for compression in the next round
+These methods are iteratively and randomly applied to a hash output in order to rapidly expand it for compression in the next round. **Note**: the length of the output is always the same as the length of the input.
 ```
      - Method 1: No-Op         (e.g. input = 123456   output = 123456)
      - Method 2: Swap-LR       (e.g. input = 123456   output = 456123)   
@@ -341,6 +349,7 @@ This PIP is not backwards compatible and requires a hard-fork activation. Previo
 A reference implementation will be provided in the coming weeks.
  
 ## Acknowledgements
+
 Refinements to improve GPU-hardness were provided by Ian Muldoon.
  
 ## Links