Last active
December 24, 2017 17:50
-
-
Save mcordingley/8244698fac2143f74b77fa15a68dd4bf to your computer and use it in GitHub Desktop.
Message Commitment
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="./styles.css" /> | |
</head> | |
<body> | |
<div class="mx-auto max-width-4"> | |
<h1>Message Commitment</h1> | |
<p> | |
This is the digital equivalent of writing something down onto a slip of paper to reveal it later. Your | |
commitment is your slip of paper and the committed message is what you wrote inside. Just send the | |
commitment code to someone or post it on social media to lay down your slip of paper. Later, post the | |
reveal code to reveal what you had written down. With these two codes in hand, anyone may verify that | |
you revealed what you had committed to reveal. | |
</p> | |
<p> | |
Under the hood, the slip of paper is actually a | |
<a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function" target="_blank">cryptographic hash</a> | |
of your message, padded out with some random data to ensure that your message cannot reasonably be | |
either guessed ahead of time or altered before being revealed. The calculations are done entirely | |
within your browser, so no one else is in possession of your message until its time comes. | |
</p> | |
<div class="clearfix mxn1"> | |
<div class="col col-12 md-col-6 px1"> | |
<h2>Commit to a Message</h2> | |
<label for="message">Message</label> | |
<textarea id="message" class="block border-box col-12 mb2" name="message" rows="4"></textarea> | |
<label for="post_now">Commitment (Post This Now)</label> | |
<textarea id="post_now" class="block border-box col-12 mb2" name="post_now" rows="4" readonly></textarea> | |
<label for="post_later">Committed Message (Post This Later)</label> | |
<textarea id="post_later" class="block border-box col-12 mb2" name="post_later" rows="4" readonly></textarea> | |
<input type="button" id="commit" class="bg-white block blue border border-blue col-12 mb2 p1 pointer" value="Commit" /> | |
</div> | |
<div class="col col-12 md-col-6 px1"> | |
<h2>Verify a Committed Message</h2> | |
<label for="commitment">Commitment</label> | |
<textarea id="commitment" class="block border-box col-12 mb2" name="commitment" rows="4"></textarea> | |
<label for="committed_message">Committed Message</label> | |
<textarea id="committed_message" class="block border-box col-12 mb2" name="committed_message" rows="4"></textarea> | |
<input type="button" id="verify" class="bg-white block blue border border-blue col-12 mb2 p1 pointer" value="Verify" /> | |
<p id="verification"></p> | |
</div> | |
</div> | |
<p class="text-muted">Disclaimer: This has not been reviewed by a professional cryptographer. Use it at your own risk and for your own fun.</p> | |
</div> | |
<script src="./page.js"></script> | |
</body> | |
</html> |
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
(function () { | |
function sha256(str) { | |
return window.crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(str)).then(function (hash) { | |
return base64(hash); | |
}); | |
} | |
function base64(buffer) { | |
var binary = '', | |
bytes = new Uint8Array(buffer), | |
len = bytes.byteLength; | |
for (var i = 0; i < len; i++) { | |
binary += String.fromCharCode(bytes[i]); | |
} | |
return window.btoa(binary); | |
} | |
document.getElementById('commit').addEventListener('click', function () { | |
var prefixBuffer = new Uint8Array(6), | |
suffixBuffer = new Uint8Array(33); | |
window.crypto.getRandomValues(prefixBuffer); | |
window.crypto.getRandomValues(suffixBuffer); | |
var message = document.getElementById('message').value.trim(), | |
prefix = base64(prefixBuffer), | |
suffix = base64(suffixBuffer), | |
post_later = prefix + '|' + message + '|' + suffix; | |
document.getElementById('post_later').value = post_later; | |
sha256(post_later).then(function (hash) { | |
document.getElementById('post_now').value = prefix + '|' + hash; | |
}); | |
}); | |
document.getElementById('verify').addEventListener('click', function () { | |
var commitment = document.getElementById('commitment').value.trim(), | |
commitmentPrefix = commitment.substring(0, commitment.indexOf('|')), | |
committedMessage = document.getElementById('committed_message').value.trim(), | |
prefix = committedMessage.substring(0, committedMessage.indexOf('|')), | |
suffix = committedMessage.substring(committedMessage.lastIndexOf('|') + 1); | |
if (commitmentPrefix !== prefix) { | |
document.getElementById('verification').innerText = 'Unable to verify committed message.'; | |
return; | |
} | |
sha256(committedMessage).then(function (hash) { | |
var calculated = prefix + '|' + hash; | |
document.getElementById('verification').innerText = calculated === commitment ? | |
'Committed message verified.' : | |
'Unable to verify committed message.'; | |
}); | |
}); | |
document.getElementById('commitment').addEventListener('input', function () { | |
document.getElementById('verification').innerText = ''; | |
}); | |
document.getElementById('committed_message').addEventListener('input', function () { | |
document.getElementById('verification').innerText = ''; | |
}); | |
})(); |
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
body { | |
background-color: #fafafa; | |
color: #212121; | |
font-family: "Palatino Linotype", Palatino, Palladio, "URW Palladio L", "Book Antiqua", Baskerville, "Bookman Old Style", "Bitstream Charter", "Nimbus Roman No9 L", Garamond, "Apple Garamond", "ITC Garamond Narrow", "New Century Schoolbook", "Century Schoolbook", "Century Schoolbook L", Georgia, serif; | |
font-size: 18px; | |
} | |
h1, | |
h2, | |
a, | |
.blue { | |
color: #008; | |
} | |
a { | |
text-decoration: none; | |
} | |
h1, | |
h2, | |
label, | |
p { | |
text-shadow: 1px 1px 0 #fff; | |
} | |
input, | |
textarea { | |
font-family: monospace; | |
font-size: 16px; | |
} | |
.block { | |
display: block; | |
} | |
.clearfix:before, | |
.clearfix:after { | |
content: " "; | |
display: table; | |
} | |
.clearfix:after { | |
clear: both; | |
} | |
.max-width-4 { | |
max-width: 64rem; | |
} | |
.border-box { | |
box-sizing: border-box; | |
} | |
.mb2 { | |
margin-bottom: 1rem; | |
} | |
.mxn1 { | |
margin-left: -.5rem; | |
margin-right: -.5rem; | |
} | |
.mx-auto { | |
margin-left: auto; | |
margin-right: auto; | |
} | |
.p1 { | |
padding: .5rem; | |
} | |
.px1 { | |
padding-left: .5rem; | |
padding-right: .5rem; | |
} | |
.col { | |
box-sizing: border-box; | |
float: left; | |
} | |
.col-12 { | |
width: 100%; | |
} | |
@media (min-width: 52em) { | |
.md-col-6 { | |
width: 50%; | |
} | |
} | |
.border { | |
border-style: solid; | |
border-width: 1px; | |
} | |
.bg-white { | |
background-color: #fff; | |
} | |
.border-blue { | |
border-color: #008; | |
} | |
.text-muted { | |
color: #888; | |
} | |
.pointer { | |
cursor: pointer; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment