diff --git a/contracts/BinaryRelated.sol b/contracts/BinaryRelated.sol index fb48fdd..39afdf5 100644 --- a/contracts/BinaryRelated.sol +++ b/contracts/BinaryRelated.sol @@ -20,4 +20,15 @@ library BinaryRelated { while ((n & (n - 1) != 0)) n = n & (n - 1); return n << 1; } + + function reverseBits(uint256 bits, uint256 input) internal pure returns (uint256) { + assert(input < (1 << bits)); + uint256 n = input; + uint256 r = 0; + for (uint256 k = 0; k < bits; k++) { + r = (r * 2) | (n % 2); + n = n / 2; + } + return r; + } } diff --git a/contracts/EthStorageContract.sol b/contracts/EthStorageContract.sol index b271b37..3907ca9 100644 --- a/contracts/EthStorageContract.sol +++ b/contracts/EthStorageContract.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import "./StorageContract.sol"; import "./Decoder.sol"; +import "./BinaryRelated.sol"; contract EthStorageContract is StorageContract, Decoder { event PutBlob(uint256 indexed kvIdx, uint256 indexed kvSize, bytes32 indexed dataHash); @@ -86,46 +87,16 @@ contract EthStorageContract is StorageContract, Decoder { uint256 ruBls = 0x564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d36306; uint256 modulusBls = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001; // peInput includes an input point that comes from bit reversed sampleIdxInKv - uint256 sampleIdxInKvRev = reverse12Bits(sampleIdxInKv); + uint256 sampleIdxInKvRev = BinaryRelated.reverseBits(12, sampleIdxInKv); uint256 xBls = modExp(ruBls, sampleIdxInKvRev, modulusBls); - // xBls uses big-endian but the format according to the specs is little-endian, so we need to reverse it. - uint256 xBlsReversed = reverseBytes(xBls); (uint256 versionedHash, uint256 evalX, uint256 evalY) = pointEvaluation(peInput); - if (evalX != xBlsReversed || bytes24(bytes32(versionedHash)) != dataHash) { + if (evalX != xBls || bytes24(bytes32(versionedHash)) != dataHash) { return false; } return evalY == decodedData; } - function reverse12Bits(uint256 input) internal pure returns (uint256) { - assert(input < 4096); - uint256 n = input; - uint256 r = 0; - for (uint256 k = 0; k < 12; k++) { - r = (r * 2) | (n % 2); - n = n / 2; - } - return r; - } - - function reverseBytes(uint256 input) internal pure returns (uint256 v) { - v = input; - v = - ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | - ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8); - v = - ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | - ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16); - v = - ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) | - ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32); - v = - ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) | - ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64); - v = (v >> 128) | (v << 128); - } - /* * Decode the sample and check the decoded sample is included in the BLOB corresponding to on-chain datahashes. */ @@ -151,7 +122,7 @@ contract EthStorageContract is StorageContract, Decoder { } // Write a large value to KV store. If the KV pair exists, overrides it. Otherwise, will append the KV to the KV array. - function putBlob(bytes32 key, uint256 blobIdx, uint256 length) virtual public payable { + function putBlob(bytes32 key, uint256 blobIdx, uint256 length) public payable virtual { bytes32 dataHash = bytes32(0); uint256 kvIdx = _putInternal(key, dataHash, length);