瀏覽代碼

Prng implementatino

Jayant Krishnamurthy 1 年之前
父節點
當前提交
c7f0b2508c

+ 24 - 0
target_chains/ethereum/contracts/forge-test/Prng.t.sol

@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: Apache 2
+
+pragma solidity ^0.8.0;
+
+import "forge-std/Test.sol";
+import "@pythnetwork/entropy-sdk-solidity/Prng.sol";
+
+contract PrngTest is Test {
+
+    function testBasic() public {
+        PrngState memory state = PrngState(0);
+        (PrngState memory nextState, uint draw) = Prng.next(state);
+
+        assertEq(nextState.rand, keccak256(abi.encodePacked(draw)));
+    }
+
+    // TODO: Test random properties of output
+    function testFuzzDraw(bytes32 seed) public {
+        PrngState memory state = PrngState(seed);
+
+        (PrngState memory nextState, uint draw) = Prng.draw(state, 10);
+        assert(draw < 10);
+    }
+}

+ 0 - 1
target_chains/ethereum/contracts/lib/README.md

@@ -1 +0,0 @@
-Forge installs the dependencies in this folder. They are .gitignored

+ 27 - 0
target_chains/ethereum/entropy_sdk/solidity/Prng.sol

@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.0;
+
+/// A pseudorandom number generator powered by a seed.
+/// This 
+library Prng {
+    uint256 public constant MAX_UINT_256 = (uint256) (~(uint256)(0));
+
+    function next(PrngState memory state) public returns (PrngState memory nextState, uint256 val) {
+        val = (uint256) (state.rand);
+        nextState = PrngState(keccak256(abi.encodePacked((state.rand))));
+    }
+
+    function draw(PrngState memory state, uint256 max) public returns (PrngState memory nextState, uint256 val) {
+        uint256 bits;
+        nextState = state;
+        do {
+            (nextState, bits) = next(nextState);
+            val = bits % max;
+            // FIXME: check boundary condition. this may be off by 1
+        } while (bits - val > MAX_UINT_256 - max);
+    }
+}
+
+struct PrngState {
+    bytes32 rand;
+}