Created
August 14, 2022 23:14
-
-
Save amiller/d74d74d035207c29e7d6686a53adbf93 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.8.0; | |
// "SPDX-License-Identifier: UNLICENSED" | |
/* | |
Honey Object as an Oasis Sapphire contract | |
Could be used to demonstrate side channels | |
*/ | |
abstract contract Sapphire { | |
function randomBytes(uint256 numWords) public virtual returns (bytes memory c) ; | |
function publicKey(uint256 privKey) public pure virtual returns(uint256 qx, uint256 qy); | |
} | |
contract SapphireHoneypot { | |
Sapphire public env; | |
uint256 privKey; | |
uint256 qx; | |
uint256 qy; | |
bytes32[] myArr; | |
constructor (Sapphire _env) payable { | |
env = _env; | |
// 32 byte key | |
privKey = randomUint256(); | |
(qx, qy) = env.publicKey(uint256(privKey)); | |
// Storage is a big empty array (1 gigabyte) | |
myArr = new bytes32[](1*1E30); | |
} | |
function randomUint256() internal returns(uint256 x) { | |
bytes memory b = env.randomBytes(32); | |
require(b.length == 32); | |
assembly { | |
x := mload(add(b, 32)) | |
} | |
} | |
// If you know the secret key, you can drain its contents | |
function drain(uint256 _privKey /* encrypted */) public { | |
require(_privKey == privKey); | |
payable(msg.sender).transfer(address(this).balance); | |
} | |
// Carry out a nominally safe query, that exhibits a likely side channel | |
function querySideChannelOracle(uint256 bitsel) public view { | |
// Access one bit of the secret key | |
require ((1<<bitsel) < myArr.length); | |
uint secretBit = privKey & (1 << bitsel) >> bitsel; | |
// The access pattern is either | |
// get(0); get(0); ... get(0); // 30 times | |
// or | |
// get(0); get(1); ... get(29); | |
// According to the documentation, since these are encrypted, | |
// it shouldn't reveal information about the bit. | |
uint REPS = 30; | |
for (uint i = 0; i < REPS; i++) { | |
uint idx = (secretBit > 0) ? i : 0; | |
myArr[idx]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment