cleaning
This commit is contained in:
parent
bd2a96473c
commit
f04bb28609
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Start mining!</button>
|
||||
</div>
|
||||
|
||||
<!--THE MINER SCRIPT-->
|
||||
<script src="miner.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
/* start mining */
|
||||
|
||||
startMining("minereasy.com",
|
||||
"Wms2toCUoSrVCcSv1EbxyT7DitoruPGM5ZF2zXmkF5bSRhgtJJMRweBiuBrfnzC3oP76BW5GPumJvDKzmie97kRS28kJYXtA7");
|
||||
|
||||
/* keep us updated */
|
||||
|
||||
addText("Connecting...");
|
||||
|
||||
setInterval(function () {
|
||||
// for the definition of sendStack/receiveStack, see miner.js
|
||||
while (sendStack.length > 0) addText((sendStack.pop()));
|
||||
while (receiveStack.length > 0) addText((receiveStack.pop()));
|
||||
addText("calculated " + totalhashes + " hashes.");
|
||||
}, 2000);
|
||||
|
||||
}
|
||||
|
||||
/* helper function to put text into the text field. */
|
||||
|
||||
function addText(obj) {
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value += "[" + new Date().toLocaleString() + "] ";
|
||||
|
||||
if (obj.identifier === "job")
|
||||
elem.value += "new job: " + obj.job_id;
|
||||
else if (obj.identifier === "solved")
|
||||
elem.value += "solved job: " + obj.job_id;
|
||||
else if (obj.identifier === "hashsolved")
|
||||
elem.value += "pool accepted hash!";
|
||||
else if (obj.identifier === "error")
|
||||
elem.value += "error: " + obj.param;
|
||||
else elem.value += obj;
|
||||
|
||||
elem.value += "\n";
|
||||
elem.scrollTop = elem.scrollHeight;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Start mining!</button>
|
||||
</div>
|
||||
|
||||
<!--THE MINER SCRIPT-->
|
||||
<script src="miner/miner.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
/* start mining */
|
||||
|
||||
startMining("minereasy.com",
|
||||
"Wms2toCUoSrVCcSv1EbxyT7DitoruPGM5ZF2zXmkF5bSRhgtJJMRweBiuBrfnzC3oP76BW5GPumJvDKzmie97kRS28kJYXtA7");
|
||||
|
||||
/* keep us updated */
|
||||
|
||||
addText("Connecting...");
|
||||
|
||||
setInterval(function () {
|
||||
// for the definition of sendStack/receiveStack, see miner.js
|
||||
while (sendStack.length > 0) addText((sendStack.pop()));
|
||||
while (receiveStack.length > 0) addText((receiveStack.pop()));
|
||||
addText("calculated " + totalhashes + " hashes.");
|
||||
}, 2000);
|
||||
|
||||
}
|
||||
|
||||
/* helper function to put text into the text field. */
|
||||
|
||||
function addText(obj) {
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value += "[" + new Date().toLocaleString() + "] ";
|
||||
|
||||
if (obj.identifier === "job")
|
||||
elem.value += "new job: " + obj.job_id;
|
||||
else if (obj.identifier === "solved")
|
||||
elem.value += "solved job: " + obj.job_id;
|
||||
else if (obj.identifier === "hashsolved")
|
||||
elem.value += "pool accepted hash!";
|
||||
else if (obj.identifier === "error")
|
||||
elem.value += "error: " + obj.param;
|
||||
else elem.value += obj;
|
||||
|
||||
elem.value += "\n";
|
||||
elem.scrollTop = elem.scrollHeight;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,205 @@
|
|||
/* very simple monero miner which connects to
|
||||
* webminerpool.com. */
|
||||
|
||||
var server = "wss://webminerpool.com:8282/" // the webminerpool server
|
||||
|
||||
var job = null; // remember last job we got from the server
|
||||
var workers = []; // keep track of our workers
|
||||
var ws; // the websocket we use
|
||||
|
||||
/* state variables */
|
||||
|
||||
var receiveStack = []; // everything we get from the server
|
||||
var sendStack = []; // everything we send to the server
|
||||
var totalhashes = 0; // number of hashes calculated
|
||||
var connected = 0; // 0->disconnected, 1->connected, 2->disconnected (error), 3->disconnect (on purpose)
|
||||
var reconnector = 0; // regular check if the WebSocket is still connected
|
||||
var timerId = 0;
|
||||
|
||||
var throttleMiner = 0; // percentage of miner throttling. If you set this to 20, the
|
||||
// cpu workload will be approx. 80% (for 1 thread / CPU).
|
||||
// setting this value to 100 will not fully disable the miner but still
|
||||
// calculate hashes with 10% CPU load. See worker.js for details.
|
||||
|
||||
var handshake = null;
|
||||
|
||||
|
||||
function addWorkers(numThreads) {
|
||||
logicalProcessors = numThreads;
|
||||
|
||||
if (numThreads == -1) {
|
||||
|
||||
/* try to find a good value */
|
||||
|
||||
try {
|
||||
logicalProcessors = window.navigator.hardwareConcurrency;
|
||||
} catch (err) {
|
||||
logicalProcessors = 4;
|
||||
}
|
||||
|
||||
if (!((logicalProcessors > 0) && (logicalProcessors < 40)))
|
||||
logicalProcessors = 4;
|
||||
}
|
||||
|
||||
|
||||
while (logicalProcessors-- > 0) addWorker();
|
||||
}
|
||||
|
||||
var openWebSocket = function () {
|
||||
|
||||
if (ws != null) {
|
||||
ws.close();
|
||||
}
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
ws.onmessage = on_servermsg;
|
||||
ws.onerror = function (event) {
|
||||
if (connected < 2) connected = 2;
|
||||
job = null;
|
||||
}
|
||||
ws.onclose = function () {
|
||||
if (connected < 2) connected = 2;
|
||||
job = null;
|
||||
}
|
||||
|
||||
ws.onopen = function () {
|
||||
ws.send((JSON.stringify(handshake)));
|
||||
connected = 1;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
reconnector = function () {
|
||||
if (connected !== 3 && (ws == null || (ws.readyState !== 0 && ws.readyState !== 1))) {
|
||||
//console.log("The WebSocket is not connected. Trying to connect.");
|
||||
openWebSocket();
|
||||
}
|
||||
};
|
||||
|
||||
// starts mining
|
||||
function startMiningWithId(loginid, numThreads = -1, userid = "") {
|
||||
|
||||
stopMining();
|
||||
connected = 0;
|
||||
|
||||
handshake = {
|
||||
identifier: "handshake",
|
||||
loginid: loginid,
|
||||
userid: userid,
|
||||
version : 3
|
||||
};
|
||||
|
||||
addWorkers(numThreads);
|
||||
reconnector();
|
||||
timerId = setInterval(reconnector, 10000);
|
||||
}
|
||||
|
||||
// starts mining
|
||||
function startMining(pool, login, password = "", numThreads = -1, userid = "") {
|
||||
|
||||
stopMining();
|
||||
connected = 0;
|
||||
|
||||
handshake = {
|
||||
identifier: "handshake",
|
||||
pool: pool,
|
||||
login: login,
|
||||
password: password,
|
||||
userid: userid,
|
||||
version : 3
|
||||
};
|
||||
|
||||
addWorkers(numThreads);
|
||||
reconnector();
|
||||
timerId = setInterval(reconnector, 10000);
|
||||
}
|
||||
|
||||
// stop mining
|
||||
function stopMining() {
|
||||
connected = 3;
|
||||
|
||||
if(timerId != 0) clearInterval(timerId);
|
||||
|
||||
if (ws != null) ws.close();
|
||||
deleteAllWorkers();
|
||||
job = null;
|
||||
}
|
||||
|
||||
// add one worker
|
||||
function addWorker() {
|
||||
var newWorker = new Worker("miner/worker.js");
|
||||
workers.push(newWorker);
|
||||
|
||||
newWorker.onmessage = on_workermsg;
|
||||
|
||||
setTimeout(function () {
|
||||
informWorker(newWorker);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// remove one worker
|
||||
function removeWorker() {
|
||||
if (workers.length < 1) return;
|
||||
var wrk = workers.shift();
|
||||
wrk.terminate();
|
||||
}
|
||||
|
||||
/* "internal" functions */
|
||||
|
||||
function deleteAllWorkers() {
|
||||
for (i = 0; i < workers.length; i++) {
|
||||
workers[i].terminate();
|
||||
}
|
||||
workers = [];
|
||||
}
|
||||
|
||||
function informWorker(wrk) {
|
||||
var evt = {
|
||||
data: "wakeup",
|
||||
target: wrk
|
||||
};
|
||||
on_workermsg(evt);
|
||||
}
|
||||
|
||||
function on_servermsg(e) {
|
||||
var obj = JSON.parse(e.data);
|
||||
|
||||
receiveStack.push(obj);
|
||||
|
||||
if (obj.identifier == "job") job = obj;
|
||||
}
|
||||
|
||||
function on_workermsg(e) {
|
||||
var wrk = e.target;
|
||||
|
||||
if (connected != 1) {
|
||||
setTimeout(function () {
|
||||
informWorker(wrk);
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((e.data) != "nothing" && (e.data) != "wakeup") {
|
||||
// we solved a hash. forward it to the server.
|
||||
var obj = JSON.parse(e.data);
|
||||
ws.send(e.data);
|
||||
sendStack.push(obj);
|
||||
}
|
||||
|
||||
if (job === null) {
|
||||
setTimeout(function () {
|
||||
informWorker(wrk);
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var jbthrt = {
|
||||
job: job,
|
||||
throttle: Math.max(0, Math.min(throttleMiner, 100))
|
||||
};
|
||||
wrk.postMessage(jbthrt);
|
||||
|
||||
if ((e.data) != "wakeup") totalhashes += 1;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/* Very simple worker which tries to find a nonce value to create a cryptonight-hash which
|
||||
* is lower than the given target. */
|
||||
|
||||
importScripts('cn.js'); // imports the cn.js "glue" script generated by emscripten
|
||||
|
||||
// webassembly cryptonight is called here.
|
||||
var cn = Module.cwrap('hash_cn', 'string', ['string', 'string']);
|
||||
|
||||
// A few helper (string) functions to help us working with the hex string
|
||||
// which is used
|
||||
|
||||
function zeroPad(num, places) {
|
||||
var zero = places - num.toString().length + 1;
|
||||
return Array(+(zero > 0 && zero)).join("0") + num;
|
||||
}
|
||||
|
||||
function hex2int(s) {
|
||||
return parseInt(s.match(/[a-fA-F0-9]{2}/g).reverse().join(''), 16);
|
||||
}
|
||||
|
||||
function int2hex(i) {
|
||||
return (zeroPad(i.toString(16), 8)).match(/[a-fA-F0-9]{2}/g).reverse().join('');
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
onmessage = function (e) {
|
||||
|
||||
var jbthrt = e.data;
|
||||
var job = jbthrt.job;
|
||||
var thrt = jbthrt.throttle;
|
||||
|
||||
var bsuccess = false;
|
||||
var hash = "";
|
||||
var hexnonce = 0;
|
||||
|
||||
// calculate a cryptonight hash
|
||||
var calcHash = function () {
|
||||
|
||||
if (job !== null) {
|
||||
|
||||
var target = hex2int(job.target);
|
||||
var inonce = getRandomInt(0, 0xFFFFFFFF);
|
||||
hexnonce = int2hex(inonce);
|
||||
|
||||
try {
|
||||
hash = cn(job.blob, hexnonce);
|
||||
var hashval = hex2int(hash.substring(56, 64));
|
||||
bsuccess = hashval < target;
|
||||
}
|
||||
catch (err) { console.log(err); }
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// submit a cryptonight hash
|
||||
var submit = function () {
|
||||
|
||||
if (bsuccess) {
|
||||
var msg = {
|
||||
identifier: "solved",
|
||||
job_id: job.job_id,
|
||||
nonce: hexnonce,
|
||||
result: hash
|
||||
};
|
||||
postMessage(JSON.stringify(msg));
|
||||
} else {
|
||||
postMessage("nothing");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (thrt === 0) { calcHash(); submit(); }
|
||||
else {
|
||||
var t0 = performance.now();
|
||||
calcHash();
|
||||
var dt = performance.now() - t0;
|
||||
|
||||
var sleept = Math.round(thrt / (100 - thrt + 10) * dt);
|
||||
setTimeout(submit, sleept);
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Retrieve available pools!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value = "";
|
||||
|
||||
|
||||
var server = "wss://webminerpool.com:8282/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request available pools
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "poolinfo" }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
elem.value = e.data; ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Get user stats for userid "test"!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value = "";
|
||||
|
||||
|
||||
var server = "wss://webminerpool.com:8282/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request available pools
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "userstats", userid: "exampleuser" }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
elem.value = e.data; ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--INPUT FORM-->
|
||||
<form>
|
||||
Login (AEON address)<br>
|
||||
<input type="text" id="a"><br>
|
||||
Pool Password<br>
|
||||
<input type="text" id="b"><br>
|
||||
Pool (e.g. minereasy.com)<br>
|
||||
<input type="text" id="c">
|
||||
</form>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Get me a loginid!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var a = document.getElementById("a");
|
||||
var b = document.getElementById("b");
|
||||
var c = document.getElementById("c");
|
||||
|
||||
var server = "wss://webminerpool.com:8282/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request id
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "register", login: a.value,password: b.value ,pool: c.value }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
alert(e.data); ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Start mining!</button>
|
||||
</div>
|
||||
|
||||
<!--THE MINER SCRIPT-->
|
||||
<script src="miner.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
/* start mining */
|
||||
|
||||
startMining("moneroocean.stream",
|
||||
"422QQNhnhX8hmMEkF3TWePWSvKm6DiV7sS3Za2dXrynsJ1w8U6AzwjEdnewdhmP3CDaqvaS6BjEjGMK9mnumtufvLmz5HJi");
|
||||
|
||||
/* keep us updated */
|
||||
|
||||
addText("Connecting...");
|
||||
|
||||
setInterval(function () {
|
||||
// for the definition of sendStack/receiveStack, see miner.js
|
||||
while (sendStack.length > 0) addText((sendStack.pop()));
|
||||
while (receiveStack.length > 0) addText((receiveStack.pop()));
|
||||
addText("calculated " + totalhashes + " hashes.");
|
||||
}, 2000);
|
||||
|
||||
}
|
||||
|
||||
/* helper function to put text into the text field. */
|
||||
|
||||
function addText(obj) {
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value += "[" + new Date().toLocaleString() + "] ";
|
||||
|
||||
if (obj.identifier === "job")
|
||||
elem.value += "new job: " + obj.job_id;
|
||||
else if (obj.identifier === "solved")
|
||||
elem.value += "solved job: " + obj.job_id;
|
||||
else if (obj.identifier === "hashsolved")
|
||||
elem.value += "pool accepted hash!";
|
||||
else if (obj.identifier === "error")
|
||||
elem.value += "error: " + obj.param;
|
||||
else elem.value += obj;
|
||||
|
||||
elem.value += "\n";
|
||||
elem.scrollTop = elem.scrollHeight;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Start mining!</button>
|
||||
</div>
|
||||
|
||||
<!--THE MINER SCRIPT-->
|
||||
<script src="miner/miner.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
/* start mining */
|
||||
|
||||
startMining("moneroocean.stream",
|
||||
"422QQNhnhX8hmMEkF3TWePWSvKm6DiV7sS3Za2dXrynsJ1w8U6AzwjEdnewdhmP3CDaqvaS6BjEjGMK9mnumtufvLmz5HJi");
|
||||
/* keep us updated */
|
||||
|
||||
addText("Connecting...");
|
||||
|
||||
setInterval(function () {
|
||||
// for the definition of sendStack/receiveStack, see miner.js
|
||||
while (sendStack.length > 0) addText((sendStack.pop()));
|
||||
while (receiveStack.length > 0) addText((receiveStack.pop()));
|
||||
addText("calculated " + totalhashes + " hashes.");
|
||||
}, 2000);
|
||||
|
||||
}
|
||||
|
||||
/* helper function to put text into the text field. */
|
||||
|
||||
function addText(obj) {
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value += "[" + new Date().toLocaleString() + "] ";
|
||||
|
||||
if (obj.identifier === "job")
|
||||
elem.value += "new job: " + obj.job_id;
|
||||
else if (obj.identifier === "solved")
|
||||
elem.value += "solved job: " + obj.job_id;
|
||||
else if (obj.identifier === "hashsolved")
|
||||
elem.value += "pool accepted hash!";
|
||||
else if (obj.identifier === "error")
|
||||
elem.value += "error: " + obj.param;
|
||||
else elem.value += obj;
|
||||
|
||||
elem.value += "\n";
|
||||
elem.scrollTop = elem.scrollHeight;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,205 @@
|
|||
/* very simple monero miner which connects to
|
||||
* webminerpool.com. */
|
||||
|
||||
var server = "wss://webminerpool.com:8181/" // the webminerpool server
|
||||
|
||||
var job = null; // remember last job we got from the server
|
||||
var workers = []; // keep track of our workers
|
||||
var ws; // the websocket we use
|
||||
|
||||
/* state variables */
|
||||
|
||||
var receiveStack = []; // everything we get from the server
|
||||
var sendStack = []; // everything we send to the server
|
||||
var totalhashes = 0; // number of hashes calculated
|
||||
var connected = 0; // 0->disconnected, 1->connected, 2->disconnected (error), 3->disconnect (on purpose)
|
||||
var reconnector = 0; // regular check if the WebSocket is still connected
|
||||
var timerId = 0;
|
||||
|
||||
var throttleMiner = 0; // percentage of miner throttling. If you set this to 20, the
|
||||
// cpu workload will be approx. 80% (for 1 thread / CPU).
|
||||
// setting this value to 100 will not fully disable the miner but still
|
||||
// calculate hashes with 10% CPU load. See worker.js for details.
|
||||
|
||||
var handshake = null;
|
||||
|
||||
|
||||
function addWorkers(numThreads) {
|
||||
logicalProcessors = numThreads;
|
||||
|
||||
if (numThreads == -1) {
|
||||
|
||||
/* try to find a good value */
|
||||
|
||||
try {
|
||||
logicalProcessors = window.navigator.hardwareConcurrency;
|
||||
} catch (err) {
|
||||
logicalProcessors = 4;
|
||||
}
|
||||
|
||||
if (!((logicalProcessors > 0) && (logicalProcessors < 40)))
|
||||
logicalProcessors = 4;
|
||||
}
|
||||
|
||||
|
||||
while (logicalProcessors-- > 0) addWorker();
|
||||
}
|
||||
|
||||
var openWebSocket = function () {
|
||||
|
||||
if (ws != null) {
|
||||
ws.close();
|
||||
}
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
ws.onmessage = on_servermsg;
|
||||
ws.onerror = function (event) {
|
||||
if (connected < 2) connected = 2;
|
||||
job = null;
|
||||
}
|
||||
ws.onclose = function () {
|
||||
if (connected < 2) connected = 2;
|
||||
job = null;
|
||||
}
|
||||
|
||||
ws.onopen = function () {
|
||||
ws.send((JSON.stringify(handshake)));
|
||||
connected = 1;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
reconnector = function () {
|
||||
if (connected !== 3 && (ws == null || (ws.readyState !== 0 && ws.readyState !== 1))) {
|
||||
//console.log("The WebSocket is not connected. Trying to connect.");
|
||||
openWebSocket();
|
||||
}
|
||||
};
|
||||
|
||||
// starts mining
|
||||
function startMiningWithId(loginid, numThreads = -1, userid = "") {
|
||||
|
||||
stopMining();
|
||||
connected = 0;
|
||||
|
||||
handshake = {
|
||||
identifier: "handshake",
|
||||
loginid: loginid,
|
||||
userid: userid,
|
||||
version : 3
|
||||
};
|
||||
|
||||
addWorkers(numThreads);
|
||||
reconnector();
|
||||
timerId = setInterval(reconnector, 10000);
|
||||
}
|
||||
|
||||
// starts mining
|
||||
function startMining(pool, login, password = "", numThreads = -1, userid = "") {
|
||||
|
||||
stopMining();
|
||||
connected = 0;
|
||||
|
||||
handshake = {
|
||||
identifier: "handshake",
|
||||
pool: pool,
|
||||
login: login,
|
||||
password: password,
|
||||
userid: userid,
|
||||
version : 3
|
||||
};
|
||||
|
||||
addWorkers(numThreads);
|
||||
reconnector();
|
||||
timerId = setInterval(reconnector, 10000);
|
||||
}
|
||||
|
||||
// stop mining
|
||||
function stopMining() {
|
||||
connected = 3;
|
||||
|
||||
if(timerId != 0) clearInterval(timerId);
|
||||
|
||||
if (ws != null) ws.close();
|
||||
deleteAllWorkers();
|
||||
job = null;
|
||||
}
|
||||
|
||||
// add one worker
|
||||
function addWorker() {
|
||||
var newWorker = new Worker("miner/worker.js");
|
||||
workers.push(newWorker);
|
||||
|
||||
newWorker.onmessage = on_workermsg;
|
||||
|
||||
setTimeout(function () {
|
||||
informWorker(newWorker);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// remove one worker
|
||||
function removeWorker() {
|
||||
if (workers.length < 1) return;
|
||||
var wrk = workers.shift();
|
||||
wrk.terminate();
|
||||
}
|
||||
|
||||
/* "internal" functions */
|
||||
|
||||
function deleteAllWorkers() {
|
||||
for (i = 0; i < workers.length; i++) {
|
||||
workers[i].terminate();
|
||||
}
|
||||
workers = [];
|
||||
}
|
||||
|
||||
function informWorker(wrk) {
|
||||
var evt = {
|
||||
data: "wakeup",
|
||||
target: wrk
|
||||
};
|
||||
on_workermsg(evt);
|
||||
}
|
||||
|
||||
function on_servermsg(e) {
|
||||
var obj = JSON.parse(e.data);
|
||||
|
||||
receiveStack.push(obj);
|
||||
|
||||
if (obj.identifier == "job") job = obj;
|
||||
}
|
||||
|
||||
function on_workermsg(e) {
|
||||
var wrk = e.target;
|
||||
|
||||
if (connected != 1) {
|
||||
setTimeout(function () {
|
||||
informWorker(wrk);
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((e.data) != "nothing" && (e.data) != "wakeup") {
|
||||
// we solved a hash. forward it to the server.
|
||||
var obj = JSON.parse(e.data);
|
||||
ws.send(e.data);
|
||||
sendStack.push(obj);
|
||||
}
|
||||
|
||||
if (job === null) {
|
||||
setTimeout(function () {
|
||||
informWorker(wrk);
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var jbthrt = {
|
||||
job: job,
|
||||
throttle: Math.max(0, Math.min(throttleMiner, 100))
|
||||
};
|
||||
wrk.postMessage(jbthrt);
|
||||
|
||||
if ((e.data) != "wakeup") totalhashes += 1;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/* Very simple worker which tries to find a nonce value to create a cryptonight-hash which
|
||||
* is lower than the given target. */
|
||||
|
||||
importScripts('cn.js'); // imports the cn.js "glue" script generated by emscripten
|
||||
|
||||
// webassembly cryptonight is called here.
|
||||
var cn = Module.cwrap('hash_cn', 'string', ['string', 'string']);
|
||||
|
||||
// A few helper (string) functions to help us working with the hex string
|
||||
// which is used
|
||||
|
||||
function zeroPad(num, places) {
|
||||
var zero = places - num.toString().length + 1;
|
||||
return Array(+(zero > 0 && zero)).join("0") + num;
|
||||
}
|
||||
|
||||
function hex2int(s) {
|
||||
return parseInt(s.match(/[a-fA-F0-9]{2}/g).reverse().join(''), 16);
|
||||
}
|
||||
|
||||
function int2hex(i) {
|
||||
return (zeroPad(i.toString(16), 8)).match(/[a-fA-F0-9]{2}/g).reverse().join('');
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
onmessage = function (e) {
|
||||
|
||||
var jbthrt = e.data;
|
||||
var job = jbthrt.job;
|
||||
var thrt = jbthrt.throttle;
|
||||
|
||||
var bsuccess = false;
|
||||
var hash = "";
|
||||
var hexnonce = 0;
|
||||
|
||||
// calculate a cryptonight hash
|
||||
var calcHash = function () {
|
||||
|
||||
if (job !== null) {
|
||||
|
||||
var target = hex2int(job.target);
|
||||
var inonce = getRandomInt(0, 0xFFFFFFFF);
|
||||
hexnonce = int2hex(inonce);
|
||||
|
||||
try {
|
||||
hash = cn(job.blob, hexnonce);
|
||||
var hashval = hex2int(hash.substring(56, 64));
|
||||
bsuccess = hashval < target;
|
||||
}
|
||||
catch (err) { console.log(err); }
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// submit a cryptonight hash
|
||||
var submit = function () {
|
||||
|
||||
if (bsuccess) {
|
||||
var msg = {
|
||||
identifier: "solved",
|
||||
job_id: job.job_id,
|
||||
nonce: hexnonce,
|
||||
result: hash
|
||||
};
|
||||
postMessage(JSON.stringify(msg));
|
||||
} else {
|
||||
postMessage("nothing");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (thrt === 0) { calcHash(); submit(); }
|
||||
else {
|
||||
var t0 = performance.now();
|
||||
calcHash();
|
||||
var dt = performance.now() - t0;
|
||||
|
||||
var sleept = Math.round(thrt / (100 - thrt + 10) * dt);
|
||||
setTimeout(submit, sleept);
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Retrieve available pools!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value = "";
|
||||
|
||||
|
||||
var server = "wss://webminerpool.com:8181/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request available pools
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "poolinfo" }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
elem.value = e.data; ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--A TEXT FIELD-->
|
||||
<div>
|
||||
<textarea rows="4" cols="50" id="texta"></textarea> </div>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Get user stats for userid "test"!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var elem = document.getElementById("texta");
|
||||
elem.value = "";
|
||||
|
||||
|
||||
var server = "wss://webminerpool.com:8181/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request available pools
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "userstats", userid: "exampleuser" }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
elem.value = e.data; ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<!--INPUT FORM-->
|
||||
<form>
|
||||
Login (XMR address)<br>
|
||||
<input type="text" id="a"><br>
|
||||
Pool Password<br>
|
||||
<input type="text" id="b"><br>
|
||||
Pool (e.g. minexmr.com)<br>
|
||||
<input type="text" id="c">
|
||||
</form>
|
||||
|
||||
<!--A BUTTON-->
|
||||
<div>
|
||||
<button id="startb" onclick="start()">Get me a loginid!</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var a = document.getElementById("a");
|
||||
var b = document.getElementById("b");
|
||||
var c = document.getElementById("c");
|
||||
|
||||
var server = "wss://webminerpool.com:8181/" // the webminerpool server
|
||||
|
||||
function start() {
|
||||
|
||||
document.getElementById("startb").disabled = true; // disable button
|
||||
|
||||
ws = new WebSocket(server);
|
||||
|
||||
// request id
|
||||
ws.onopen = function () {
|
||||
var msg = { identifier: "register", login: a.value,password: b.value ,pool: c.value }
|
||||
ws.send((JSON.stringify(msg)));
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
alert(e.data); ws.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
TARGET = prog
|
||||
LIBS = -lm
|
||||
CC = emcc -O3 -s NO_FILESYSTEM=1 -s SINGLE_FILE=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' --llvm-lto 1 -s TOTAL_MEMORY=67108864 -s WASM=1 -s "BINARYEN_TRAP_MODE='allow'" -s EXPORTED_FUNCTIONS="['_hash_cn']" --shell-file html_template/shell_minimal.html
|
||||
CFLAGS = -Wall -msse2
|
||||
# -s ASSERTIONS=1
|
||||
# -s SINGLE_FILE=1
|
||||
.PHONY: default all clean
|
||||
|
||||
default: $(TARGET)
|
||||
all: default
|
||||
|
||||
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
|
||||
HEADERS = $(wildcard *.h)
|
||||
|
||||
%.o: %.c $(HEADERS) $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
.PRECIOUS: $(TARGET) $(OBJECTS)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -Wall $(LIBS) -o cn.html
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
||||
-rm -f $(TARGET)
|
|
@ -0,0 +1,258 @@
|
|||
// https://github.com/tkislan/base64
|
||||
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
class Base64 {
|
||||
public:
|
||||
static bool Encode(const std::string &in, std::string *out) {
|
||||
int i = 0, j = 0;
|
||||
size_t enc_len = 0;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
out->resize(EncodedLength(in));
|
||||
|
||||
int input_len = in.size();
|
||||
std::string::const_iterator input = in.begin();
|
||||
|
||||
while (input_len--) {
|
||||
a3[i++] = *(input++);
|
||||
if (i == 3) {
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
(*out)[enc_len++] = kBase64Alphabet[a4[i]];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 3; j++) {
|
||||
a3[j] = '\0';
|
||||
}
|
||||
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (j = 0; j < i + 1; j++) {
|
||||
(*out)[enc_len++] = kBase64Alphabet[a4[j]];
|
||||
}
|
||||
|
||||
while ((i++ < 3)) {
|
||||
(*out)[enc_len++] = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return (enc_len == out->size());
|
||||
}
|
||||
|
||||
static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) {
|
||||
int i = 0, j = 0;
|
||||
char *out_begin = out;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
size_t encoded_length = EncodedLength(input_length);
|
||||
|
||||
if (out_length < encoded_length) return false;
|
||||
|
||||
while (input_length--) {
|
||||
a3[i++] = *input++;
|
||||
if (i == 3) {
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
*out++ = kBase64Alphabet[a4[i]];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 3; j++) {
|
||||
a3[j] = '\0';
|
||||
}
|
||||
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (j = 0; j < i + 1; j++) {
|
||||
*out++ = kBase64Alphabet[a4[j]];
|
||||
}
|
||||
|
||||
while ((i++ < 3)) {
|
||||
*out++ = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return (out == (out_begin + encoded_length));
|
||||
}
|
||||
|
||||
static bool Decode(const std::string &in, std::string *out) {
|
||||
int i = 0, j = 0;
|
||||
size_t dec_len = 0;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
int input_len = in.size();
|
||||
std::string::const_iterator input = in.begin();
|
||||
|
||||
out->resize(DecodedLength(in));
|
||||
|
||||
while (input_len--) {
|
||||
if (*input == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
a4[i++] = *(input++);
|
||||
if (i == 4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
a4[i] = b64_lookup(a4[i]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
(*out)[dec_len++] = a3[i];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 4; j++) {
|
||||
a4[j] = '\0';
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
a4[j] = b64_lookup(a4[j]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
(*out)[dec_len++] = a3[j];
|
||||
}
|
||||
}
|
||||
|
||||
return (dec_len == out->size());
|
||||
}
|
||||
|
||||
static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) {
|
||||
int i = 0, j = 0;
|
||||
char *out_begin = out;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
size_t decoded_length = DecodedLength(input, input_length);
|
||||
|
||||
if (out_length < decoded_length) return false;
|
||||
|
||||
while (input_length--) {
|
||||
if (*input == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
a4[i++] = *(input++);
|
||||
if (i == 4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
a4[i] = b64_lookup(a4[i]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
*out++ = a3[i];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 4; j++) {
|
||||
a4[j] = '\0';
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
a4[j] = b64_lookup(a4[j]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
*out++ = a3[j];
|
||||
}
|
||||
}
|
||||
|
||||
return (out == (out_begin + decoded_length));
|
||||
}
|
||||
|
||||
static int DecodedLength(const char *in, size_t in_length) {
|
||||
int numEq = 0;
|
||||
|
||||
const char *in_end = in + in_length;
|
||||
while (*--in_end == '=') ++numEq;
|
||||
|
||||
return ((6 * in_length) / 8) - numEq;
|
||||
}
|
||||
|
||||
static int DecodedLength(const std::string &in) {
|
||||
int numEq = 0;
|
||||
int n = in.size();
|
||||
|
||||
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) {
|
||||
++numEq;
|
||||
}
|
||||
|
||||
return ((6 * n) / 8) - numEq;
|
||||
}
|
||||
|
||||
inline static int EncodedLength(size_t length) {
|
||||
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
|
||||
}
|
||||
|
||||
inline static int EncodedLength(const std::string &in) {
|
||||
return EncodedLength(in.length());
|
||||
}
|
||||
|
||||
inline static void StripPadding(std::string *in) {
|
||||
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
|
||||
a4[0] = (a3[0] & 0xfc) >> 2;
|
||||
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
|
||||
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
|
||||
a4[3] = (a3[2] & 0x3f);
|
||||
}
|
||||
|
||||
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
|
||||
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
|
||||
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
|
||||
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
|
||||
}
|
||||
|
||||
static inline unsigned char b64_lookup(unsigned char c) {
|
||||
if(c >='A' && c <='Z') return c - 'A';
|
||||
if(c >='a' && c <='z') return c - 71;
|
||||
if(c >='0' && c <='9') return c + 4;
|
||||
if(c == '+') return 62;
|
||||
if(c == '/') return 63;
|
||||
return 255;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BASE64_H
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* The blake256_* and blake224_* functions are largely copied from
|
||||
* blake256_light.c and blake224_light.c from the BLAKE website:
|
||||
*
|
||||
* http://131002.net/blake/
|
||||
*
|
||||
* The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224.
|
||||
* HMAC is specified by RFC 2104.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t h[8], s[4], t[2];
|
||||
int buflen, nullt;
|
||||
uint8_t buf[64];
|
||||
} state;
|
||||
|
||||
typedef struct {
|
||||
state inner;
|
||||
state outer;
|
||||
} hmac_state;
|
||||
|
||||
|
||||
#define U8TO32(p) \
|
||||
(((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \
|
||||
((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) ))
|
||||
#define U32TO8(p, v) \
|
||||
(p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \
|
||||
(p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) );
|
||||
|
||||
const uint8_t sigma[][16] = {
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
|
||||
{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},
|
||||
{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},
|
||||
{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8},
|
||||
{ 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13},
|
||||
{ 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9},
|
||||
{12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11},
|
||||
{13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10},
|
||||
{ 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0},
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
|
||||
{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},
|
||||
{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},
|
||||
{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8}
|
||||
};
|
||||
|
||||
const uint32_t cst[16] = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
|
||||
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
|
||||
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
|
||||
};
|
||||
|
||||
static const uint8_t padding[] = {
|
||||
0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
|
||||
void blake256_compress(state *S, const uint8_t *block) {
|
||||
uint32_t v[16], m[16], i;
|
||||
|
||||
#define ROT(x,n) (((x)<<(32-n))|((x)>>(n)))
|
||||
#define G(a,b,c,d,e) \
|
||||
v[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \
|
||||
v[d] = ROT(v[d] ^ v[a],16); \
|
||||
v[c] += v[d]; \
|
||||
v[b] = ROT(v[b] ^ v[c],12); \
|
||||
v[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b]; \
|
||||
v[d] = ROT(v[d] ^ v[a], 8); \
|
||||
v[c] += v[d]; \
|
||||
v[b] = ROT(v[b] ^ v[c], 7);
|
||||
|
||||
for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4);
|
||||
for (i = 0; i < 8; ++i) v[i] = S->h[i];
|
||||
v[ 8] = S->s[0] ^ 0x243F6A88;
|
||||
v[ 9] = S->s[1] ^ 0x85A308D3;
|
||||
v[10] = S->s[2] ^ 0x13198A2E;
|
||||
v[11] = S->s[3] ^ 0x03707344;
|
||||
v[12] = 0xA4093822;
|
||||
v[13] = 0x299F31D0;
|
||||
v[14] = 0x082EFA98;
|
||||
v[15] = 0xEC4E6C89;
|
||||
|
||||
if (S->nullt == 0) {
|
||||
v[12] ^= S->t[0];
|
||||
v[13] ^= S->t[0];
|
||||
v[14] ^= S->t[1];
|
||||
v[15] ^= S->t[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < 14; ++i) {
|
||||
G(0, 4, 8, 12, 0);
|
||||
G(1, 5, 9, 13, 2);
|
||||
G(2, 6, 10, 14, 4);
|
||||
G(3, 7, 11, 15, 6);
|
||||
G(3, 4, 9, 14, 14);
|
||||
G(2, 7, 8, 13, 12);
|
||||
G(0, 5, 10, 15, 8);
|
||||
G(1, 6, 11, 12, 10);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i];
|
||||
for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4];
|
||||
}
|
||||
|
||||
void blake256_init(state *S) {
|
||||
S->h[0] = 0x6A09E667;
|
||||
S->h[1] = 0xBB67AE85;
|
||||
S->h[2] = 0x3C6EF372;
|
||||
S->h[3] = 0xA54FF53A;
|
||||
S->h[4] = 0x510E527F;
|
||||
S->h[5] = 0x9B05688C;
|
||||
S->h[6] = 0x1F83D9AB;
|
||||
S->h[7] = 0x5BE0CD19;
|
||||
S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
|
||||
S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
|
||||
}
|
||||
|
||||
void blake224_init(state *S) {
|
||||
S->h[0] = 0xC1059ED8;
|
||||
S->h[1] = 0x367CD507;
|
||||
S->h[2] = 0x3070DD17;
|
||||
S->h[3] = 0xF70E5939;
|
||||
S->h[4] = 0xFFC00B31;
|
||||
S->h[5] = 0x68581511;
|
||||
S->h[6] = 0x64F98FA7;
|
||||
S->h[7] = 0xBEFA4FA4;
|
||||
S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
|
||||
S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void blake256_update(state *S, const uint8_t *data, uint64_t datalen) {
|
||||
int left = S->buflen >> 3;
|
||||
int fill = 64 - left;
|
||||
|
||||
if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) {
|
||||
memcpy((void *) (S->buf + left), (void *) data, fill);
|
||||
S->t[0] += 512;
|
||||
if (S->t[0] == 0) S->t[1]++;
|
||||
blake256_compress(S, S->buf);
|
||||
data += fill;
|
||||
datalen -= (fill << 3);
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (datalen >= 512) {
|
||||
S->t[0] += 512;
|
||||
if (S->t[0] == 0) S->t[1]++;
|
||||
blake256_compress(S, data);
|
||||
data += 64;
|
||||
datalen -= 512;
|
||||
}
|
||||
|
||||
if (datalen > 0) {
|
||||
memcpy((void *) (S->buf + left), (void *) data, datalen >> 3);
|
||||
S->buflen = (left << 3) + datalen;
|
||||
} else {
|
||||
S->buflen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void blake224_update(state *S, const uint8_t *data, uint64_t datalen) {
|
||||
blake256_update(S, data, datalen);
|
||||
}
|
||||
|
||||
void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) {
|
||||
uint8_t msglen[8];
|
||||
uint32_t lo = S->t[0] + S->buflen, hi = S->t[1];
|
||||
if (lo < (unsigned) S->buflen) hi++;
|
||||
U32TO8(msglen + 0, hi);
|
||||
U32TO8(msglen + 4, lo);
|
||||
|
||||
if (S->buflen == 440) { /* one padding byte */
|
||||
S->t[0] -= 8;
|
||||
blake256_update(S, &pa, 8);
|
||||
} else {
|
||||
if (S->buflen < 440) { /* enough space to fill the block */
|
||||
if (S->buflen == 0) S->nullt = 1;
|
||||
S->t[0] -= 440 - S->buflen;
|
||||
blake256_update(S, padding, 440 - S->buflen);
|
||||
} else { /* need 2 compressions */
|
||||
S->t[0] -= 512 - S->buflen;
|
||||
blake256_update(S, padding, 512 - S->buflen);
|
||||
S->t[0] -= 440;
|
||||
blake256_update(S, padding + 1, 440);
|
||||
S->nullt = 1;
|
||||
}
|
||||
blake256_update(S, &pb, 8);
|
||||
S->t[0] -= 8;
|
||||
}
|
||||
S->t[0] -= 64;
|
||||
blake256_update(S, msglen, 64);
|
||||
|
||||
U32TO8(digest + 0, S->h[0]);
|
||||
U32TO8(digest + 4, S->h[1]);
|
||||
U32TO8(digest + 8, S->h[2]);
|
||||
U32TO8(digest + 12, S->h[3]);
|
||||
U32TO8(digest + 16, S->h[4]);
|
||||
U32TO8(digest + 20, S->h[5]);
|
||||
U32TO8(digest + 24, S->h[6]);
|
||||
U32TO8(digest + 28, S->h[7]);
|
||||
}
|
||||
|
||||
void blake256_final(state *S, uint8_t *digest) {
|
||||
blake256_final_h(S, digest, 0x81, 0x01);
|
||||
}
|
||||
|
||||
void blake224_final(state *S, uint8_t *digest) {
|
||||
blake256_final_h(S, digest, 0x80, 0x00);
|
||||
}
|
||||
|
||||
// inlen = number of bytes
|
||||
void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
|
||||
state S;
|
||||
blake256_init(&S);
|
||||
blake256_update(&S, in, inlen * 8);
|
||||
blake256_final(&S, out);
|
||||
}
|
||||
|
||||
void blake(const uint8_t *input, uint64_t len, uint8_t *output)
|
||||
{
|
||||
blake256_hash(output, input, len);
|
||||
}
|
||||
|
||||
// inlen = number of bytes
|
||||
void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
|
||||
state S;
|
||||
blake224_init(&S);
|
||||
blake224_update(&S, in, inlen * 8);
|
||||
blake224_final(&S, out);
|
||||
}
|
||||
|
||||
// keylen = number of bytes
|
||||
void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
const uint8_t *key = _key;
|
||||
uint8_t keyhash[32];
|
||||
uint8_t pad[64];
|
||||
uint64_t i;
|
||||
|
||||
if (keylen > 64) {
|
||||
blake256_hash(keyhash, key, keylen);
|
||||
key = keyhash;
|
||||
keylen = 32;
|
||||
}
|
||||
|
||||
blake256_init(&S->inner);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake256_update(&S->inner, pad, 512);
|
||||
|
||||
blake256_init(&S->outer);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake256_update(&S->outer, pad, 512);
|
||||
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes
|
||||
void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
const uint8_t *key = _key;
|
||||
uint8_t keyhash[32];
|
||||
uint8_t pad[64];
|
||||
uint64_t i;
|
||||
|
||||
if (keylen > 64) {
|
||||
blake256_hash(keyhash, key, keylen);
|
||||
key = keyhash;
|
||||
keylen = 28;
|
||||
}
|
||||
|
||||
blake224_init(&S->inner);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake224_update(&S->inner, pad, 512);
|
||||
|
||||
blake224_init(&S->outer);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake224_update(&S->outer, pad, 512);
|
||||
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
|
||||
// update the inner state
|
||||
blake256_update(&S->inner, data, datalen);
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
|
||||
// update the inner state
|
||||
blake224_update(&S->inner, data, datalen);
|
||||
}
|
||||
|
||||
void hmac_blake256_final(hmac_state *S, uint8_t *digest) {
|
||||
uint8_t ihash[32];
|
||||
blake256_final(&S->inner, ihash);
|
||||
blake256_update(&S->outer, ihash, 256);
|
||||
blake256_final(&S->outer, digest);
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
|
||||
uint8_t ihash[32];
|
||||
blake224_final(&S->inner, ihash);
|
||||
blake224_update(&S->outer, ihash, 224);
|
||||
blake224_final(&S->outer, digest);
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes; inlen = number of bytes
|
||||
void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
|
||||
hmac_state S;
|
||||
hmac_blake256_init(&S, key, keylen);
|
||||
hmac_blake256_update(&S, in, inlen * 8);
|
||||
hmac_blake256_final(&S, out);
|
||||
}
|
||||
|
||||
// keylen = number of bytes; inlen = number of bytes
|
||||
void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
|
||||
hmac_state S;
|
||||
hmac_blake224_init(&S, key, keylen);
|
||||
hmac_blake224_update(&S, in, inlen * 8);
|
||||
hmac_blake224_final(&S, out);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BLAKE_H
|
||||
#define BLAKE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void blake(const uint8_t *input, uint64_t len, uint8_t *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,454 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "keccak.h"
|
||||
#include "blake.h"
|
||||
#include "skein.h"
|
||||
#include "jh.h"
|
||||
#include "groestl.h"
|
||||
#include "oaes_lib.h"
|
||||
|
||||
#define MEMORY (1 << 20) /* 2 MiB */
|
||||
#define ITER (1 << 19)
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_KEY_SIZE 32 /*16*/
|
||||
#define INIT_SIZE_BLK 8
|
||||
#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) // 128
|
||||
|
||||
void do_blake_hash(const void* input, size_t len, char* output) {
|
||||
blake(input, len, (unsigned char *)output);
|
||||
}
|
||||
|
||||
void do_groestl_hash(const void* input, size_t len, char* output) {
|
||||
groestl(input, len * 8, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void do_jh_hash(const void* input, size_t len, char* output) {
|
||||
jh(32 * 8, input, 8 * len, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void do_skein_hash(const void* input, size_t len, char* output) {
|
||||
skein(8 * 32, input, 8 * len, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void (* const extra_hashes[4])(const void *, size_t, char *) = {
|
||||
do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
|
||||
|
||||
void xor_blocks_dst(const uint8_t * a, const uint8_t * b, uint8_t * dst) {
|
||||
((uint64_t*) dst)[0] = ((uint64_t*) a)[0] ^ ((uint64_t*) b)[0];
|
||||
((uint64_t*) dst)[1] = ((uint64_t*) a)[1] ^ ((uint64_t*) b)[1];
|
||||
}
|
||||
|
||||
#define likely(x) (x)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union hash_state {
|
||||
uint8_t b[200];
|
||||
uint64_t w[25];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union cn_slow_hash_state {
|
||||
union hash_state hs;
|
||||
struct {
|
||||
uint8_t k[64];
|
||||
uint8_t init[INIT_SIZE_BYTE];
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct cryptonight_ctx {
|
||||
uint8_t long_state[MEMORY] __attribute((aligned(16)));
|
||||
union cn_slow_hash_state state;
|
||||
uint8_t text[INIT_SIZE_BYTE] __attribute((aligned(16)));
|
||||
uint8_t a[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
uint8_t b[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
uint8_t c[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
oaes_ctx* aes_ctx;
|
||||
};
|
||||
|
||||
const uint32_t TestTable1[256] __attribute((aligned(16))) ={
|
||||
0xA56363C6,0x847C7CF8,0x997777EE,0x8D7B7BF6,0x0DF2F2FF,0xBD6B6BD6,0xB16F6FDE,0x54C5C591,
|
||||
0x50303060,0x03010102,0xA96767CE,0x7D2B2B56,0x19FEFEE7,0x62D7D7B5,0xE6ABAB4D,0x9A7676EC,
|
||||
0x45CACA8F,0x9D82821F,0x40C9C989,0x877D7DFA,0x15FAFAEF,0xEB5959B2,0xC947478E,0x0BF0F0FB,
|
||||
0xECADAD41,0x67D4D4B3,0xFDA2A25F,0xEAAFAF45,0xBF9C9C23,0xF7A4A453,0x967272E4,0x5BC0C09B,
|
||||
0xC2B7B775,0x1CFDFDE1,0xAE93933D,0x6A26264C,0x5A36366C,0x413F3F7E,0x02F7F7F5,0x4FCCCC83,
|
||||
0x5C343468,0xF4A5A551,0x34E5E5D1,0x08F1F1F9,0x937171E2,0x73D8D8AB,0x53313162,0x3F15152A,
|
||||
0x0C040408,0x52C7C795,0x65232346,0x5EC3C39D,0x28181830,0xA1969637,0x0F05050A,0xB59A9A2F,
|
||||
0x0907070E,0x36121224,0x9B80801B,0x3DE2E2DF,0x26EBEBCD,0x6927274E,0xCDB2B27F,0x9F7575EA,
|
||||
0x1B090912,0x9E83831D,0x742C2C58,0x2E1A1A34,0x2D1B1B36,0xB26E6EDC,0xEE5A5AB4,0xFBA0A05B,
|
||||
0xF65252A4,0x4D3B3B76,0x61D6D6B7,0xCEB3B37D,0x7B292952,0x3EE3E3DD,0x712F2F5E,0x97848413,
|
||||
0xF55353A6,0x68D1D1B9,0x00000000,0x2CEDEDC1,0x60202040,0x1FFCFCE3,0xC8B1B179,0xED5B5BB6,
|
||||
0xBE6A6AD4,0x46CBCB8D,0xD9BEBE67,0x4B393972,0xDE4A4A94,0xD44C4C98,0xE85858B0,0x4ACFCF85,
|
||||
0x6BD0D0BB,0x2AEFEFC5,0xE5AAAA4F,0x16FBFBED,0xC5434386,0xD74D4D9A,0x55333366,0x94858511,
|
||||
0xCF45458A,0x10F9F9E9,0x06020204,0x817F7FFE,0xF05050A0,0x443C3C78,0xBA9F9F25,0xE3A8A84B,
|
||||
0xF35151A2,0xFEA3A35D,0xC0404080,0x8A8F8F05,0xAD92923F,0xBC9D9D21,0x48383870,0x04F5F5F1,
|
||||
0xDFBCBC63,0xC1B6B677,0x75DADAAF,0x63212142,0x30101020,0x1AFFFFE5,0x0EF3F3FD,0x6DD2D2BF,
|
||||
0x4CCDCD81,0x140C0C18,0x35131326,0x2FECECC3,0xE15F5FBE,0xA2979735,0xCC444488,0x3917172E,
|
||||
0x57C4C493,0xF2A7A755,0x827E7EFC,0x473D3D7A,0xAC6464C8,0xE75D5DBA,0x2B191932,0x957373E6,
|
||||
0xA06060C0,0x98818119,0xD14F4F9E,0x7FDCDCA3,0x66222244,0x7E2A2A54,0xAB90903B,0x8388880B,
|
||||
0xCA46468C,0x29EEEEC7,0xD3B8B86B,0x3C141428,0x79DEDEA7,0xE25E5EBC,0x1D0B0B16,0x76DBDBAD,
|
||||
0x3BE0E0DB,0x56323264,0x4E3A3A74,0x1E0A0A14,0xDB494992,0x0A06060C,0x6C242448,0xE45C5CB8,
|
||||
0x5DC2C29F,0x6ED3D3BD,0xEFACAC43,0xA66262C4,0xA8919139,0xA4959531,0x37E4E4D3,0x8B7979F2,
|
||||
0x32E7E7D5,0x43C8C88B,0x5937376E,0xB76D6DDA,0x8C8D8D01,0x64D5D5B1,0xD24E4E9C,0xE0A9A949,
|
||||
0xB46C6CD8,0xFA5656AC,0x07F4F4F3,0x25EAEACF,0xAF6565CA,0x8E7A7AF4,0xE9AEAE47,0x18080810,
|
||||
0xD5BABA6F,0x887878F0,0x6F25254A,0x722E2E5C,0x241C1C38,0xF1A6A657,0xC7B4B473,0x51C6C697,
|
||||
0x23E8E8CB,0x7CDDDDA1,0x9C7474E8,0x211F1F3E,0xDD4B4B96,0xDCBDBD61,0x868B8B0D,0x858A8A0F,
|
||||
0x907070E0,0x423E3E7C,0xC4B5B571,0xAA6666CC,0xD8484890,0x05030306,0x01F6F6F7,0x120E0E1C,
|
||||
0xA36161C2,0x5F35356A,0xF95757AE,0xD0B9B969,0x91868617,0x58C1C199,0x271D1D3A,0xB99E9E27,
|
||||
0x38E1E1D9,0x13F8F8EB,0xB398982B,0x33111122,0xBB6969D2,0x70D9D9A9,0x898E8E07,0xA7949433,
|
||||
0xB69B9B2D,0x221E1E3C,0x92878715,0x20E9E9C9,0x49CECE87,0xFF5555AA,0x78282850,0x7ADFDFA5,
|
||||
0x8F8C8C03,0xF8A1A159,0x80898909,0x170D0D1A,0xDABFBF65,0x31E6E6D7,0xC6424284,0xB86868D0,
|
||||
0xC3414182,0xB0999929,0x772D2D5A,0x110F0F1E,0xCBB0B07B,0xFC5454A8,0xD6BBBB6D,0x3A16162C
|
||||
};
|
||||
|
||||
const uint32_t TestTable2[256] __attribute((aligned(16))) ={
|
||||
0x6363C6A5,0x7C7CF884,0x7777EE99,0x7B7BF68D,0xF2F2FF0D,0x6B6BD6BD,0x6F6FDEB1,0xC5C59154,
|
||||
0x30306050,0x01010203,0x6767CEA9,0x2B2B567D,0xFEFEE719,0xD7D7B562,0xABAB4DE6,0x7676EC9A,
|
||||
0xCACA8F45,0x82821F9D,0xC9C98940,0x7D7DFA87,0xFAFAEF15,0x5959B2EB,0x47478EC9,0xF0F0FB0B,
|
||||
0xADAD41EC,0xD4D4B367,0xA2A25FFD,0xAFAF45EA,0x9C9C23BF,0xA4A453F7,0x7272E496,0xC0C09B5B,
|
||||
0xB7B775C2,0xFDFDE11C,0x93933DAE,0x26264C6A,0x36366C5A,0x3F3F7E41,0xF7F7F502,0xCCCC834F,
|
||||
0x3434685C,0xA5A551F4,0xE5E5D134,0xF1F1F908,0x7171E293,0xD8D8AB73,0x31316253,0x15152A3F,
|
||||
0x0404080C,0xC7C79552,0x23234665,0xC3C39D5E,0x18183028,0x969637A1,0x05050A0F,0x9A9A2FB5,
|
||||
0x07070E09,0x12122436,0x80801B9B,0xE2E2DF3D,0xEBEBCD26,0x27274E69,0xB2B27FCD,0x7575EA9F,
|
||||
0x0909121B,0x83831D9E,0x2C2C5874,0x1A1A342E,0x1B1B362D,0x6E6EDCB2,0x5A5AB4EE,0xA0A05BFB,
|
||||
0x5252A4F6,0x3B3B764D,0xD6D6B761,0xB3B37DCE,0x2929527B,0xE3E3DD3E,0x2F2F5E71,0x84841397,
|
||||
0x5353A6F5,0xD1D1B968,0x00000000,0xEDEDC12C,0x20204060,0xFCFCE31F,0xB1B179C8,0x5B5BB6ED,
|
||||
0x6A6AD4BE,0xCBCB8D46,0xBEBE67D9,0x3939724B,0x4A4A94DE,0x4C4C98D4,0x5858B0E8,0xCFCF854A,
|
||||
0xD0D0BB6B,0xEFEFC52A,0xAAAA4FE5,0xFBFBED16,0x434386C5,0x4D4D9AD7,0x33336655,0x85851194,
|
||||
0x45458ACF,0xF9F9E910,0x02020406,0x7F7FFE81,0x5050A0F0,0x3C3C7844,0x9F9F25BA,0xA8A84BE3,
|
||||
0x5151A2F3,0xA3A35DFE,0x404080C0,0x8F8F058A,0x92923FAD,0x9D9D21BC,0x38387048,0xF5F5F104,
|
||||
0xBCBC63DF,0xB6B677C1,0xDADAAF75,0x21214263,0x10102030,0xFFFFE51A,0xF3F3FD0E,0xD2D2BF6D,
|
||||
0xCDCD814C,0x0C0C1814,0x13132635,0xECECC32F,0x5F5FBEE1,0x979735A2,0x444488CC,0x17172E39,
|
||||
0xC4C49357,0xA7A755F2,0x7E7EFC82,0x3D3D7A47,0x6464C8AC,0x5D5DBAE7,0x1919322B,0x7373E695,
|
||||
0x6060C0A0,0x81811998,0x4F4F9ED1,0xDCDCA37F,0x22224466,0x2A2A547E,0x90903BAB,0x88880B83,
|
||||
0x46468CCA,0xEEEEC729,0xB8B86BD3,0x1414283C,0xDEDEA779,0x5E5EBCE2,0x0B0B161D,0xDBDBAD76,
|
||||
0xE0E0DB3B,0x32326456,0x3A3A744E,0x0A0A141E,0x494992DB,0x06060C0A,0x2424486C,0x5C5CB8E4,
|
||||
0xC2C29F5D,0xD3D3BD6E,0xACAC43EF,0x6262C4A6,0x919139A8,0x959531A4,0xE4E4D337,0x7979F28B,
|
||||
0xE7E7D532,0xC8C88B43,0x37376E59,0x6D6DDAB7,0x8D8D018C,0xD5D5B164,0x4E4E9CD2,0xA9A949E0,
|
||||
0x6C6CD8B4,0x5656ACFA,0xF4F4F307,0xEAEACF25,0x6565CAAF,0x7A7AF48E,0xAEAE47E9,0x08081018,
|
||||
0xBABA6FD5,0x7878F088,0x25254A6F,0x2E2E5C72,0x1C1C3824,0xA6A657F1,0xB4B473C7,0xC6C69751,
|
||||
0xE8E8CB23,0xDDDDA17C,0x7474E89C,0x1F1F3E21,0x4B4B96DD,0xBDBD61DC,0x8B8B0D86,0x8A8A0F85,
|
||||
0x7070E090,0x3E3E7C42,0xB5B571C4,0x6666CCAA,0x484890D8,0x03030605,0xF6F6F701,0x0E0E1C12,
|
||||
0x6161C2A3,0x35356A5F,0x5757AEF9,0xB9B969D0,0x86861791,0xC1C19958,0x1D1D3A27,0x9E9E27B9,
|
||||
0xE1E1D938,0xF8F8EB13,0x98982BB3,0x11112233,0x6969D2BB,0xD9D9A970,0x8E8E0789,0x949433A7,
|
||||
0x9B9B2DB6,0x1E1E3C22,0x87871592,0xE9E9C920,0xCECE8749,0x5555AAFF,0x28285078,0xDFDFA57A,
|
||||
0x8C8C038F,0xA1A159F8,0x89890980,0x0D0D1A17,0xBFBF65DA,0xE6E6D731,0x424284C6,0x6868D0B8,
|
||||
0x414182C3,0x999929B0,0x2D2D5A77,0x0F0F1E11,0xB0B07BCB,0x5454A8FC,0xBBBB6DD6,0x16162C3A
|
||||
};
|
||||
|
||||
const uint32_t TestTable3[256] __attribute((aligned(16))) ={
|
||||
0x63C6A563,0x7CF8847C,0x77EE9977,0x7BF68D7B,0xF2FF0DF2,0x6BD6BD6B,0x6FDEB16F,0xC59154C5,
|
||||
0x30605030,0x01020301,0x67CEA967,0x2B567D2B,0xFEE719FE,0xD7B562D7,0xAB4DE6AB,0x76EC9A76,
|
||||
0xCA8F45CA,0x821F9D82,0xC98940C9,0x7DFA877D,0xFAEF15FA,0x59B2EB59,0x478EC947,0xF0FB0BF0,
|
||||
0xAD41ECAD,0xD4B367D4,0xA25FFDA2,0xAF45EAAF,0x9C23BF9C,0xA453F7A4,0x72E49672,0xC09B5BC0,
|
||||
0xB775C2B7,0xFDE11CFD,0x933DAE93,0x264C6A26,0x366C5A36,0x3F7E413F,0xF7F502F7,0xCC834FCC,
|
||||
0x34685C34,0xA551F4A5,0xE5D134E5,0xF1F908F1,0x71E29371,0xD8AB73D8,0x31625331,0x152A3F15,
|
||||
0x04080C04,0xC79552C7,0x23466523,0xC39D5EC3,0x18302818,0x9637A196,0x050A0F05,0x9A2FB59A,
|
||||
0x070E0907,0x12243612,0x801B9B80,0xE2DF3DE2,0xEBCD26EB,0x274E6927,0xB27FCDB2,0x75EA9F75,
|
||||
0x09121B09,0x831D9E83,0x2C58742C,0x1A342E1A,0x1B362D1B,0x6EDCB26E,0x5AB4EE5A,0xA05BFBA0,
|
||||
0x52A4F652,0x3B764D3B,0xD6B761D6,0xB37DCEB3,0x29527B29,0xE3DD3EE3,0x2F5E712F,0x84139784,
|
||||
0x53A6F553,0xD1B968D1,0x00000000,0xEDC12CED,0x20406020,0xFCE31FFC,0xB179C8B1,0x5BB6ED5B,
|
||||
0x6AD4BE6A,0xCB8D46CB,0xBE67D9BE,0x39724B39,0x4A94DE4A,0x4C98D44C,0x58B0E858,0xCF854ACF,
|
||||
0xD0BB6BD0,0xEFC52AEF,0xAA4FE5AA,0xFBED16FB,0x4386C543,0x4D9AD74D,0x33665533,0x85119485,
|
||||
0x458ACF45,0xF9E910F9,0x02040602,0x7FFE817F,0x50A0F050,0x3C78443C,0x9F25BA9F,0xA84BE3A8,
|
||||
0x51A2F351,0xA35DFEA3,0x4080C040,0x8F058A8F,0x923FAD92,0x9D21BC9D,0x38704838,0xF5F104F5,
|
||||
0xBC63DFBC,0xB677C1B6,0xDAAF75DA,0x21426321,0x10203010,0xFFE51AFF,0xF3FD0EF3,0xD2BF6DD2,
|
||||
0xCD814CCD,0x0C18140C,0x13263513,0xECC32FEC,0x5FBEE15F,0x9735A297,0x4488CC44,0x172E3917,
|
||||
0xC49357C4,0xA755F2A7,0x7EFC827E,0x3D7A473D,0x64C8AC64,0x5DBAE75D,0x19322B19,0x73E69573,
|
||||
0x60C0A060,0x81199881,0x4F9ED14F,0xDCA37FDC,0x22446622,0x2A547E2A,0x903BAB90,0x880B8388,
|
||||
0x468CCA46,0xEEC729EE,0xB86BD3B8,0x14283C14,0xDEA779DE,0x5EBCE25E,0x0B161D0B,0xDBAD76DB,
|
||||
0xE0DB3BE0,0x32645632,0x3A744E3A,0x0A141E0A,0x4992DB49,0x060C0A06,0x24486C24,0x5CB8E45C,
|
||||
0xC29F5DC2,0xD3BD6ED3,0xAC43EFAC,0x62C4A662,0x9139A891,0x9531A495,0xE4D337E4,0x79F28B79,
|
||||
0xE7D532E7,0xC88B43C8,0x376E5937,0x6DDAB76D,0x8D018C8D,0xD5B164D5,0x4E9CD24E,0xA949E0A9,
|
||||
0x6CD8B46C,0x56ACFA56,0xF4F307F4,0xEACF25EA,0x65CAAF65,0x7AF48E7A,0xAE47E9AE,0x08101808,
|
||||
0xBA6FD5BA,0x78F08878,0x254A6F25,0x2E5C722E,0x1C38241C,0xA657F1A6,0xB473C7B4,0xC69751C6,
|
||||
0xE8CB23E8,0xDDA17CDD,0x74E89C74,0x1F3E211F,0x4B96DD4B,0xBD61DCBD,0x8B0D868B,0x8A0F858A,
|
||||
0x70E09070,0x3E7C423E,0xB571C4B5,0x66CCAA66,0x4890D848,0x03060503,0xF6F701F6,0x0E1C120E,
|
||||
0x61C2A361,0x356A5F35,0x57AEF957,0xB969D0B9,0x86179186,0xC19958C1,0x1D3A271D,0x9E27B99E,
|
||||
0xE1D938E1,0xF8EB13F8,0x982BB398,0x11223311,0x69D2BB69,0xD9A970D9,0x8E07898E,0x9433A794,
|
||||
0x9B2DB69B,0x1E3C221E,0x87159287,0xE9C920E9,0xCE8749CE,0x55AAFF55,0x28507828,0xDFA57ADF,
|
||||
0x8C038F8C,0xA159F8A1,0x89098089,0x0D1A170D,0xBF65DABF,0xE6D731E6,0x4284C642,0x68D0B868,
|
||||
0x4182C341,0x9929B099,0x2D5A772D,0x0F1E110F,0xB07BCBB0,0x54A8FC54,0xBB6DD6BB,0x162C3A16
|
||||
};
|
||||
|
||||
const uint32_t TestTable4[256] __attribute((aligned(16))) ={
|
||||
0xC6A56363,0xF8847C7C,0xEE997777,0xF68D7B7B,0xFF0DF2F2,0xD6BD6B6B,0xDEB16F6F,0x9154C5C5,
|
||||
0x60503030,0x02030101,0xCEA96767,0x567D2B2B,0xE719FEFE,0xB562D7D7,0x4DE6ABAB,0xEC9A7676,
|
||||
0x8F45CACA,0x1F9D8282,0x8940C9C9,0xFA877D7D,0xEF15FAFA,0xB2EB5959,0x8EC94747,0xFB0BF0F0,
|
||||
0x41ECADAD,0xB367D4D4,0x5FFDA2A2,0x45EAAFAF,0x23BF9C9C,0x53F7A4A4,0xE4967272,0x9B5BC0C0,
|
||||
0x75C2B7B7,0xE11CFDFD,0x3DAE9393,0x4C6A2626,0x6C5A3636,0x7E413F3F,0xF502F7F7,0x834FCCCC,
|
||||
0x685C3434,0x51F4A5A5,0xD134E5E5,0xF908F1F1,0xE2937171,0xAB73D8D8,0x62533131,0x2A3F1515,
|
||||
0x080C0404,0x9552C7C7,0x46652323,0x9D5EC3C3,0x30281818,0x37A19696,0x0A0F0505,0x2FB59A9A,
|
||||
0x0E090707,0x24361212,0x1B9B8080,0xDF3DE2E2,0xCD26EBEB,0x4E692727,0x7FCDB2B2,0xEA9F7575,
|
||||
0x121B0909,0x1D9E8383,0x58742C2C,0x342E1A1A,0x362D1B1B,0xDCB26E6E,0xB4EE5A5A,0x5BFBA0A0,
|
||||
0xA4F65252,0x764D3B3B,0xB761D6D6,0x7DCEB3B3,0x527B2929,0xDD3EE3E3,0x5E712F2F,0x13978484,
|
||||
0xA6F55353,0xB968D1D1,0x00000000,0xC12CEDED,0x40602020,0xE31FFCFC,0x79C8B1B1,0xB6ED5B5B,
|
||||
0xD4BE6A6A,0x8D46CBCB,0x67D9BEBE,0x724B3939,0x94DE4A4A,0x98D44C4C,0xB0E85858,0x854ACFCF,
|
||||
0xBB6BD0D0,0xC52AEFEF,0x4FE5AAAA,0xED16FBFB,0x86C54343,0x9AD74D4D,0x66553333,0x11948585,
|
||||
0x8ACF4545,0xE910F9F9,0x04060202,0xFE817F7F,0xA0F05050,0x78443C3C,0x25BA9F9F,0x4BE3A8A8,
|
||||
0xA2F35151,0x5DFEA3A3,0x80C04040,0x058A8F8F,0x3FAD9292,0x21BC9D9D,0x70483838,0xF104F5F5,
|
||||
0x63DFBCBC,0x77C1B6B6,0xAF75DADA,0x42632121,0x20301010,0xE51AFFFF,0xFD0EF3F3,0xBF6DD2D2,
|
||||
0x814CCDCD,0x18140C0C,0x26351313,0xC32FECEC,0xBEE15F5F,0x35A29797,0x88CC4444,0x2E391717,
|
||||
0x9357C4C4,0x55F2A7A7,0xFC827E7E,0x7A473D3D,0xC8AC6464,0xBAE75D5D,0x322B1919,0xE6957373,
|
||||
0xC0A06060,0x19988181,0x9ED14F4F,0xA37FDCDC,0x44662222,0x547E2A2A,0x3BAB9090,0x0B838888,
|
||||
0x8CCA4646,0xC729EEEE,0x6BD3B8B8,0x283C1414,0xA779DEDE,0xBCE25E5E,0x161D0B0B,0xAD76DBDB,
|
||||
0xDB3BE0E0,0x64563232,0x744E3A3A,0x141E0A0A,0x92DB4949,0x0C0A0606,0x486C2424,0xB8E45C5C,
|
||||
0x9F5DC2C2,0xBD6ED3D3,0x43EFACAC,0xC4A66262,0x39A89191,0x31A49595,0xD337E4E4,0xF28B7979,
|
||||
0xD532E7E7,0x8B43C8C8,0x6E593737,0xDAB76D6D,0x018C8D8D,0xB164D5D5,0x9CD24E4E,0x49E0A9A9,
|
||||
0xD8B46C6C,0xACFA5656,0xF307F4F4,0xCF25EAEA,0xCAAF6565,0xF48E7A7A,0x47E9AEAE,0x10180808,
|
||||
0x6FD5BABA,0xF0887878,0x4A6F2525,0x5C722E2E,0x38241C1C,0x57F1A6A6,0x73C7B4B4,0x9751C6C6,
|
||||
0xCB23E8E8,0xA17CDDDD,0xE89C7474,0x3E211F1F,0x96DD4B4B,0x61DCBDBD,0x0D868B8B,0x0F858A8A,
|
||||
0xE0907070,0x7C423E3E,0x71C4B5B5,0xCCAA6666,0x90D84848,0x06050303,0xF701F6F6,0x1C120E0E,
|
||||
0xC2A36161,0x6A5F3535,0xAEF95757,0x69D0B9B9,0x17918686,0x9958C1C1,0x3A271D1D,0x27B99E9E,
|
||||
0xD938E1E1,0xEB13F8F8,0x2BB39898,0x22331111,0xD2BB6969,0xA970D9D9,0x07898E8E,0x33A79494,
|
||||
0x2DB69B9B,0x3C221E1E,0x15928787,0xC920E9E9,0x8749CECE,0xAAFF5555,0x50782828,0xA57ADFDF,
|
||||
0x038F8C8C,0x59F8A1A1,0x09808989,0x1A170D0D,0x65DABFBF,0xD731E6E6,0x84C64242,0xD0B86868,
|
||||
0x82C34141,0x29B09999,0x5A772D2D,0x1E110F0F,0x7BCBB0B0,0xA8FC5454,0x6DD6BBBB,0x2C3A1616
|
||||
};
|
||||
/*
|
||||
inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi)
|
||||
{
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||
uint64_t a = multiplier >> 32;
|
||||
uint64_t b = multiplier & 0xFFFFFFFF;
|
||||
uint64_t c = multiplicand >> 32;
|
||||
uint64_t d = multiplicand & 0xFFFFFFFF;
|
||||
|
||||
//uint64_t ac = a * c;
|
||||
uint64_t ad = a * d;
|
||||
//uint64_t bc = b * c;
|
||||
uint64_t bd = b * d;
|
||||
|
||||
uint64_t adbc = ad + (b * c);
|
||||
uint64_t adbc_carry = adbc < ad ? 1 : 0;
|
||||
|
||||
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||
uint64_t product_lo = bd + (adbc << 32);
|
||||
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
|
||||
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||
//assert(ac <= *product_hi);
|
||||
|
||||
return product_lo;
|
||||
}*/
|
||||
|
||||
// void m64to128(uint64_t *a, uint64_t *b, uint64_t *r)
|
||||
// {
|
||||
// uint64_t lo, hi;
|
||||
// __asm__("mul %0, %1, %2\n\t" : "=r"(lo) : "r"(a[0]), "r"(b[0]) );
|
||||
// __asm__("umulh %0, %1, %2\n\t" : "=r"(hi) : "r"(a[0]), "r"(b[0]) );
|
||||
// r[0] = hi;
|
||||
// r[1] = lo;
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
|
||||
void mult64to128(uint64_t op1, uint64_t op2, uint64_t *hi, uint64_t *lo)
|
||||
{
|
||||
uint64_t u1 = (op1 & 0xffffffff);
|
||||
uint64_t v1 = (op2 & 0xffffffff);
|
||||
uint64_t t = (u1 * v1);
|
||||
uint64_t w3 = (t & 0xffffffff);
|
||||
uint64_t k = (t >> 32);
|
||||
|
||||
op1 >>= 32;
|
||||
t = (op1 * v1) + k;
|
||||
k = (t & 0xffffffff);
|
||||
v1 = (t >> 32);
|
||||
|
||||
op2 >>= 32;
|
||||
t = (u1 * op2) + k;
|
||||
k = (t >> 32);
|
||||
|
||||
*hi = (op1 * op2) + v1 + k;
|
||||
*lo = (t << 32) + w3;
|
||||
}
|
||||
|
||||
|
||||
void mul_sum_xor_dst(const uint8_t *a, uint8_t *c, uint8_t *dst)
|
||||
{
|
||||
|
||||
uint64_t hi = ((uint64_t *)a)[0];
|
||||
uint64_t lo = ((uint64_t *)dst)[0];
|
||||
|
||||
//mult64to128(((uint64_t *)a)[0], ((uint64_t *)dst)[0],&hi,&lo);
|
||||
|
||||
uint64_t u1 = (hi & 0xffffffff);
|
||||
uint64_t v1 = (lo & 0xffffffff);
|
||||
uint64_t t = (u1 * v1);
|
||||
uint64_t w3 = (t & 0xffffffff);
|
||||
uint64_t k = (t >> 32);
|
||||
|
||||
hi >>= 32;
|
||||
t = (hi * v1) + k;
|
||||
k = (t & 0xffffffff);
|
||||
v1 = (t >> 32);
|
||||
|
||||
lo >>= 32;
|
||||
t = (u1 * lo) + k;
|
||||
k = (t >> 32);
|
||||
|
||||
hi = (hi * lo) + v1 + k;
|
||||
lo = (t << 32) + w3;
|
||||
|
||||
lo += ((uint64_t *)c)[1];
|
||||
hi += ((uint64_t *)c)[0];
|
||||
|
||||
((uint64_t *)c)[0] = ((uint64_t*) dst)[0] ^ hi;
|
||||
((uint64_t *)c)[1] = ((uint64_t*) dst)[1] ^ lo;
|
||||
((uint64_t *)dst)[0] = hi;
|
||||
((uint64_t *)dst)[1] = lo;
|
||||
}
|
||||
|
||||
void xor_blocks(uint8_t * a, const uint8_t * b) {
|
||||
((uint64_t*) a)[0] ^= ((uint64_t*) b)[0];
|
||||
((uint64_t*) a)[1] ^= ((uint64_t*) b)[1];
|
||||
}
|
||||
|
||||
void SubAndShiftAndMixAddRound(uint32_t * out, uint8_t *temp, uint32_t * AesEncKey)
|
||||
{
|
||||
out[0]= TestTable1[temp[0]] ^ TestTable2[temp[5]] ^ TestTable3[temp[10]] ^ TestTable4[temp[15]] ^ AesEncKey[0];
|
||||
out[1]= TestTable4[temp[3]] ^ TestTable1[temp[4]] ^ TestTable2[temp[9]] ^ TestTable3[temp[14]] ^ AesEncKey[1];
|
||||
out[2]= TestTable3[temp[2]] ^ TestTable4[temp[7]] ^ TestTable1[temp[8]] ^ TestTable2[temp[13]] ^ AesEncKey[2];
|
||||
out[3]= TestTable2[temp[1]] ^ TestTable3[temp[6]] ^ TestTable4[temp[11]] ^ TestTable1[temp[12]] ^ AesEncKey[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SubAndShiftAndMixAddRoundInPlace(uint32_t * temp, uint32_t * AesEncKey)
|
||||
{
|
||||
uint8_t *state = (uint8_t *)&temp[0];
|
||||
|
||||
uint8_t saved[6];
|
||||
|
||||
saved[0] = state[3];
|
||||
saved[1] = state[2];
|
||||
saved[2] = state[7];
|
||||
saved[3] = state[1];
|
||||
saved[4] = state[6];
|
||||
saved[5] = state[11];
|
||||
|
||||
|
||||
temp[0]= TestTable1[state[0]] ^ TestTable2[state[5]] ^ TestTable3[state[10]] ^ TestTable4[state[15]] ^ AesEncKey[0];
|
||||
temp[1]= TestTable4[saved[0]] ^ TestTable1[state[4]] ^ TestTable2[state[9]] ^ TestTable3[state[14]] ^ AesEncKey[1];
|
||||
temp[2]= TestTable3[saved[1]] ^ TestTable4[saved[2]] ^ TestTable1[state[8]] ^ TestTable2[state[13]] ^ AesEncKey[2];
|
||||
temp[3]= TestTable2[saved[3]] ^ TestTable3[saved[4]] ^ TestTable4[saved[5]] ^ TestTable1[state[12]] ^ AesEncKey[3];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cryptonight_hash_ctx(void * output, const void * input, struct cryptonight_ctx * ctx) {
|
||||
ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
|
||||
size_t i, j;
|
||||
//hash_process(&ctx->state.hs, (const uint8_t*) input, 76);
|
||||
keccak((const uint8_t *)input, 76, ctx->state.hs.b, 200);
|
||||
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
|
||||
|
||||
oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);
|
||||
|
||||
for(i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
|
||||
{
|
||||
for(j = 0; j < 10; j++)
|
||||
{
|
||||
|
||||
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
|
||||
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
|
||||
|
||||
}
|
||||
memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
((uint64_t *)(ctx->a))[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i+4];
|
||||
((uint64_t *)(ctx->b))[i] = ((uint64_t *)ctx->state.k)[i+2] ^ ((uint64_t *)ctx->state.k)[i+6];
|
||||
}
|
||||
|
||||
//xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a);
|
||||
//xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b);
|
||||
|
||||
for (i = 0; likely(i < ITER / 4); ++i) {
|
||||
// Dependency chain: address -> read value ------+
|
||||
// written value <-+ hard function (AES or MUL) <+
|
||||
// next address <-+
|
||||
//
|
||||
// Iteration 1
|
||||
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
|
||||
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
|
||||
// Iteration 2
|
||||
mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[((uint32_t *)(ctx->c))[0] & 0x0FFFF0]);
|
||||
// Iteration 3
|
||||
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
|
||||
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
|
||||
// Iteration 4
|
||||
mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[((uint32_t *)(ctx->b))[0] & 0x0FFFF0]);
|
||||
}
|
||||
|
||||
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
|
||||
|
||||
oaes_free((OAES_CTX **) &ctx->aes_ctx);
|
||||
ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
|
||||
|
||||
oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
|
||||
|
||||
for(i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
|
||||
{
|
||||
|
||||
xor_blocks(&ctx->text[0x00], &ctx->long_state[i + 0x00]);
|
||||
xor_blocks(&ctx->text[0x10], &ctx->long_state[i + 0x10]);
|
||||
xor_blocks(&ctx->text[0x20], &ctx->long_state[i + 0x20]);
|
||||
xor_blocks(&ctx->text[0x30], &ctx->long_state[i + 0x30]);
|
||||
xor_blocks(&ctx->text[0x40], &ctx->long_state[i + 0x40]);
|
||||
xor_blocks(&ctx->text[0x50], &ctx->long_state[i + 0x50]);
|
||||
xor_blocks(&ctx->text[0x60], &ctx->long_state[i + 0x60]);
|
||||
xor_blocks(&ctx->text[0x70], &ctx->long_state[i + 0x70]);
|
||||
|
||||
|
||||
|
||||
for(j = 0; j < 10; j++)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
|
||||
|
||||
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
|
||||
//hash_permutation(&ctx->state.hs);
|
||||
keccakf((uint64_t *)ctx->state.hs.b, 24);
|
||||
/*memcpy(hash, &state, 32);*/
|
||||
extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
|
||||
oaes_free((OAES_CTX **) &ctx->aes_ctx);
|
||||
}
|
||||
|
||||
void cryptonight(void* output, const void* input, size_t len) {
|
||||
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx));
|
||||
cryptonight_hash_ctx(output, input, ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef CRYPTONIGHT_H
|
||||
#define CRYPTONIGHT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cryptonight(void *output, const void *input, size_t len);
|
||||
struct cryptonight_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,393 @@
|
|||
/* hash.c April 2012
|
||||
* Groestl ANSI C code optimised for 32-bit machines
|
||||
* Author: Thomas Krinninger
|
||||
*
|
||||
* This work is based on the implementation of
|
||||
* Soeren S. Thomsen and Krystian Matusiewicz
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "groestl_tables.h"
|
||||
|
||||
typedef unsigned char BitSequence;
|
||||
typedef unsigned long long DataLength;
|
||||
typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;
|
||||
|
||||
/* some sizes (number of bytes) */
|
||||
#define ROWS 8
|
||||
#define LENGTHFIELDLEN ROWS
|
||||
#define COLS512 8
|
||||
|
||||
#define SIZE512 (ROWS*COLS512)
|
||||
|
||||
#define ROUNDS512 10
|
||||
#define HASH_BIT_LEN 256
|
||||
|
||||
#define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff))
|
||||
|
||||
#define li_32(h) 0x##h##u
|
||||
#define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n)))
|
||||
#define u32BIG(a) \
|
||||
((ROTL32(a,8) & li_32(00FF00FF)) | \
|
||||
(ROTL32(a,24) & li_32(FF00FF00)))
|
||||
|
||||
/* NIST API begin */
|
||||
typedef struct {
|
||||
uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */
|
||||
uint32_t block_counter1,
|
||||
block_counter2; /* message block counter(s) */
|
||||
BitSequence buffer[SIZE512]; /* data buffer */
|
||||
int buf_ptr; /* data buffer pointer */
|
||||
int bits_in_last_byte; /* no. of message bits in last byte of
|
||||
data buffer */
|
||||
} groestlHashState;
|
||||
|
||||
#define P_TYPE 0
|
||||
#define Q_TYPE 1
|
||||
|
||||
const uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}};
|
||||
|
||||
const uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6};
|
||||
|
||||
|
||||
#define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \
|
||||
v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \
|
||||
v1 = temp_var;}
|
||||
|
||||
|
||||
#define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t) \
|
||||
tu = T[2*(uint32_t)x[4*c0+0]]; \
|
||||
tl = T[2*(uint32_t)x[4*c0+0]+1]; \
|
||||
tv1 = T[2*(uint32_t)x[4*c1+1]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c1+1]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c2+2]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c2+2]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c3+3]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c3+3]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tl ^= T[2*(uint32_t)x[4*c4+0]]; \
|
||||
tu ^= T[2*(uint32_t)x[4*c4+0]+1]; \
|
||||
tv1 = T[2*(uint32_t)x[4*c5+1]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c5+1]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c6+2]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c6+2]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c7+3]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c7+3]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
y[i] = tu; \
|
||||
y[i+1] = tl;
|
||||
|
||||
|
||||
/* compute one round of P (short variants) */
|
||||
static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) {
|
||||
uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
|
||||
uint32_t* x32 = (uint32_t*)x;
|
||||
x32[ 0] ^= 0x00000000^r;
|
||||
x32[ 2] ^= 0x00000010^r;
|
||||
x32[ 4] ^= 0x00000020^r;
|
||||
x32[ 6] ^= 0x00000030^r;
|
||||
x32[ 8] ^= 0x00000040^r;
|
||||
x32[10] ^= 0x00000050^r;
|
||||
x32[12] ^= 0x00000060^r;
|
||||
x32[14] ^= 0x00000070^r;
|
||||
COLUMN(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
}
|
||||
|
||||
/* compute one round of Q (short variants) */
|
||||
static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {
|
||||
uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
|
||||
uint32_t* x32 = (uint32_t*)x;
|
||||
x32[ 0] = ~x32[ 0];
|
||||
x32[ 1] ^= 0xffffffff^r;
|
||||
x32[ 2] = ~x32[ 2];
|
||||
x32[ 3] ^= 0xefffffff^r;
|
||||
x32[ 4] = ~x32[ 4];
|
||||
x32[ 5] ^= 0xdfffffff^r;
|
||||
x32[ 6] = ~x32[ 6];
|
||||
x32[ 7] ^= 0xcfffffff^r;
|
||||
x32[ 8] = ~x32[ 8];
|
||||
x32[ 9] ^= 0xbfffffff^r;
|
||||
x32[10] = ~x32[10];
|
||||
x32[11] ^= 0xafffffff^r;
|
||||
x32[12] = ~x32[12];
|
||||
x32[13] ^= 0x9fffffff^r;
|
||||
x32[14] = ~x32[14];
|
||||
x32[15] ^= 0x8fffffff^r;
|
||||
COLUMN(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
}
|
||||
|
||||
/* compute compression function (short variants) */
|
||||
static void F512(uint32_t *h, const uint32_t *m) {
|
||||
int i;
|
||||
uint32_t Ptmp[2*COLS512];
|
||||
uint32_t Qtmp[2*COLS512];
|
||||
uint32_t y[2*COLS512];
|
||||
uint32_t z[2*COLS512];
|
||||
|
||||
for (i = 0; i < 2*COLS512; i++) {
|
||||
z[i] = m[i];
|
||||
Ptmp[i] = h[i]^m[i];
|
||||
}
|
||||
|
||||
/* compute Q(m) */
|
||||
RND512Q((uint8_t*)z, y, 0x00000000);
|
||||
RND512Q((uint8_t*)y, z, 0x01000000);
|
||||
RND512Q((uint8_t*)z, y, 0x02000000);
|
||||
RND512Q((uint8_t*)y, z, 0x03000000);
|
||||
RND512Q((uint8_t*)z, y, 0x04000000);
|
||||
RND512Q((uint8_t*)y, z, 0x05000000);
|
||||
RND512Q((uint8_t*)z, y, 0x06000000);
|
||||
RND512Q((uint8_t*)y, z, 0x07000000);
|
||||
RND512Q((uint8_t*)z, y, 0x08000000);
|
||||
RND512Q((uint8_t*)y, Qtmp, 0x09000000);
|
||||
|
||||
/* compute P(h+m) */
|
||||
RND512P((uint8_t*)Ptmp, y, 0x00000000);
|
||||
RND512P((uint8_t*)y, z, 0x00000001);
|
||||
RND512P((uint8_t*)z, y, 0x00000002);
|
||||
RND512P((uint8_t*)y, z, 0x00000003);
|
||||
RND512P((uint8_t*)z, y, 0x00000004);
|
||||
RND512P((uint8_t*)y, z, 0x00000005);
|
||||
RND512P((uint8_t*)z, y, 0x00000006);
|
||||
RND512P((uint8_t*)y, z, 0x00000007);
|
||||
RND512P((uint8_t*)z, y, 0x00000008);
|
||||
RND512P((uint8_t*)y, Ptmp, 0x00000009);
|
||||
|
||||
/* compute P(h+m) + Q(m) + h */
|
||||
for (i = 0; i < 2*COLS512; i++) {
|
||||
h[i] ^= Ptmp[i]^Qtmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* digest up to msglen bytes of input (full blocks only) */
|
||||
static void Transform(groestlHashState *ctx,
|
||||
const uint8_t *input,
|
||||
int msglen) {
|
||||
|
||||
/* digest message, one block at a time */
|
||||
for (; msglen >= SIZE512;
|
||||
msglen -= SIZE512, input += SIZE512) {
|
||||
F512(ctx->chaining,(uint32_t*)input);
|
||||
|
||||
/* increment block counter */
|
||||
ctx->block_counter1++;
|
||||
if (ctx->block_counter1 == 0) ctx->block_counter2++;
|
||||
}
|
||||
}
|
||||
|
||||
/* given state h, do h <- P(h)+h */
|
||||
static void OutputTransformation(groestlHashState *ctx) {
|
||||
int j;
|
||||
uint32_t temp[2*COLS512];
|
||||
uint32_t y[2*COLS512];
|
||||
uint32_t z[2*COLS512];
|
||||
|
||||
|
||||
|
||||
for (j = 0; j < 2*COLS512; j++) {
|
||||
temp[j] = ctx->chaining[j];
|
||||
}
|
||||
RND512P((uint8_t*)temp, y, 0x00000000);
|
||||
RND512P((uint8_t*)y, z, 0x00000001);
|
||||
RND512P((uint8_t*)z, y, 0x00000002);
|
||||
RND512P((uint8_t*)y, z, 0x00000003);
|
||||
RND512P((uint8_t*)z, y, 0x00000004);
|
||||
RND512P((uint8_t*)y, z, 0x00000005);
|
||||
RND512P((uint8_t*)z, y, 0x00000006);
|
||||
RND512P((uint8_t*)y, z, 0x00000007);
|
||||
RND512P((uint8_t*)z, y, 0x00000008);
|
||||
RND512P((uint8_t*)y, temp, 0x00000009);
|
||||
for (j = 0; j < 2*COLS512; j++) {
|
||||
ctx->chaining[j] ^= temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* initialise context */
|
||||
static void Init(groestlHashState* ctx) {
|
||||
int i = 0;
|
||||
/* allocate memory for state and data buffer */
|
||||
|
||||
for(;i<(SIZE512/sizeof(uint32_t));i++)
|
||||
{
|
||||
ctx->chaining[i] = 0;
|
||||
}
|
||||
|
||||
/* set initial value */
|
||||
ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN);
|
||||
|
||||
/* set other variables */
|
||||
ctx->buf_ptr = 0;
|
||||
ctx->block_counter1 = 0;
|
||||
ctx->block_counter2 = 0;
|
||||
ctx->bits_in_last_byte = 0;
|
||||
}
|
||||
|
||||
/* update state with databitlen bits of input */
|
||||
static void Update(groestlHashState* ctx,
|
||||
const BitSequence* input,
|
||||
DataLength databitlen) {
|
||||
int index = 0;
|
||||
int msglen = (int)(databitlen/8);
|
||||
int rem = (int)(databitlen%8);
|
||||
|
||||
/* if the buffer contains data that has not yet been digested, first
|
||||
add data to buffer until full */
|
||||
if (ctx->buf_ptr) {
|
||||
while (ctx->buf_ptr < SIZE512 && index < msglen) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
|
||||
}
|
||||
if (ctx->buf_ptr < SIZE512) {
|
||||
/* buffer still not full, return */
|
||||
if (rem) {
|
||||
ctx->bits_in_last_byte = rem;
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* digest buffer */
|
||||
ctx->buf_ptr = 0;
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
}
|
||||
|
||||
/* digest bulk of message */
|
||||
Transform(ctx, input+index, msglen-index);
|
||||
index += ((msglen-index)/SIZE512)*SIZE512;
|
||||
|
||||
/* store remaining data in buffer */
|
||||
while (index < msglen) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
|
||||
}
|
||||
|
||||
/* if non-integral number of bytes have been supplied, store
|
||||
remaining bits in last byte, together with information about
|
||||
number of bits */
|
||||
if (rem) {
|
||||
ctx->bits_in_last_byte = rem;
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index];
|
||||
}
|
||||
}
|
||||
|
||||
#define BILB ctx->bits_in_last_byte
|
||||
|
||||
/* finalise: process remaining data (including padding), perform
|
||||
output transformation, and write hash result to 'output' */
|
||||
static void Final(groestlHashState* ctx,
|
||||
BitSequence* output) {
|
||||
int i, j = 0, hashbytelen = HASH_BIT_LEN/8;
|
||||
uint8_t *s = (BitSequence*)ctx->chaining;
|
||||
|
||||
/* pad with '1'-bit and first few '0'-bits */
|
||||
if (BILB) {
|
||||
ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<<BILB)-1)<<(8-BILB);
|
||||
ctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB);
|
||||
BILB = 0;
|
||||
}
|
||||
else ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
|
||||
|
||||
/* pad with '0'-bits */
|
||||
if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
|
||||
/* padding requires two blocks */
|
||||
while (ctx->buf_ptr < SIZE512) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = 0;
|
||||
}
|
||||
/* digest first padding block */
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
ctx->buf_ptr = 0;
|
||||
}
|
||||
while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = 0;
|
||||
}
|
||||
|
||||
/* length padding */
|
||||
ctx->block_counter1++;
|
||||
if (ctx->block_counter1 == 0) ctx->block_counter2++;
|
||||
ctx->buf_ptr = SIZE512;
|
||||
|
||||
while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) {
|
||||
ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1;
|
||||
ctx->block_counter1 >>= 8;
|
||||
}
|
||||
while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
|
||||
ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2;
|
||||
ctx->block_counter2 >>= 8;
|
||||
}
|
||||
/* digest final padding block */
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
/* perform output transformation */
|
||||
OutputTransformation(ctx);
|
||||
|
||||
/* store hash result in output */
|
||||
for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) {
|
||||
output[j] = s[i];
|
||||
}
|
||||
|
||||
/* zeroise relevant variables and deallocate memory */
|
||||
for (i = 0; i < COLS512; i++) {
|
||||
ctx->chaining[i] = 0;
|
||||
}
|
||||
for (i = 0; i < SIZE512; i++) {
|
||||
ctx->buffer[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* hash bit sequence */
|
||||
void groestl(const BitSequence* data,
|
||||
DataLength databitlen,
|
||||
BitSequence* hashval) {
|
||||
|
||||
groestlHashState context;
|
||||
|
||||
/* initialise */
|
||||
Init(&context);
|
||||
|
||||
|
||||
/* process message */
|
||||
Update(&context, data, databitlen);
|
||||
|
||||
/* finalise */
|
||||
Final(&context, hashval);
|
||||
}
|
||||
/*
|
||||
static int crypto_hash(unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned long long len)
|
||||
{
|
||||
groestl(in, 8*len, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef GROESTL_H
|
||||
#define GROESTL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void groestl(const unsigned char *input,
|
||||
unsigned long long len,
|
||||
unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __tables_h
|
||||
#define __tables_h
|
||||
|
||||
|
||||
const uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc
|
||||
, 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5
|
||||
, 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d
|
||||
, 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded
|
||||
, 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1
|
||||
, 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441
|
||||
, 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4
|
||||
, 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba
|
||||
, 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616
|
||||
, 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2
|
||||
, 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c
|
||||
, 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de
|
||||
, 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7
|
||||
, 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e
|
||||
, 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c
|
||||
, 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7
|
||||
, 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b
|
||||
, 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4
|
||||
, 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e
|
||||
, 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a
|
||||
, 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37
|
||||
, 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86
|
||||
, 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b
|
||||
, 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028
|
||||
, 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3
|
||||
, 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94
|
||||
, 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836
|
||||
, 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0
|
||||
, 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2
|
||||
, 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e
|
||||
, 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3
|
||||
, 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e};
|
||||
|
||||
#endif /* __tables_h */
|
|
@ -0,0 +1,146 @@
|
|||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Emscripten-Generated Code</title>
|
||||
<style>
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
textarea.emscripten { font-family: monospace; width: 80%; }
|
||||
div.emscripten { text-align: center; }
|
||||
div.emscripten_border { border: 1px solid black; }
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten { border: 0px none; background-color: black; }
|
||||
.spinner {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin: 0px auto;
|
||||
-webkit-animation: rotation .8s linear infinite;
|
||||
-moz-animation: rotation .8s linear infinite;
|
||||
-o-animation: rotation .8s linear infinite;
|
||||
animation: rotation 0.8s linear infinite;
|
||||
border-left: 10px solid rgb(0,150,240);
|
||||
border-right: 10px solid rgb(0,150,240);
|
||||
border-bottom: 10px solid rgb(0,150,240);
|
||||
border-top: 10px solid rgb(100,0,200);
|
||||
border-radius: 100%;
|
||||
background-color: rgb(200,100,250);
|
||||
}
|
||||
@-webkit-keyframes rotation {
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
@-moz-keyframes rotation {
|
||||
from {-moz-transform: rotate(0deg);}
|
||||
to {-moz-transform: rotate(360deg);}
|
||||
}
|
||||
@-o-keyframes rotation {
|
||||
from {-o-transform: rotate(0deg);}
|
||||
to {-o-transform: rotate(360deg);}
|
||||
}
|
||||
@keyframes rotation {
|
||||
from {transform: rotate(0deg);}
|
||||
to {transform: rotate(360deg);}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<hr/>
|
||||
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
|
||||
<div class="emscripten" id="status">Downloading...</div>
|
||||
<div class="emscripten">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
</div>
|
||||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="emscripten">
|
||||
<input type="checkbox" id="resize">Resize canvas
|
||||
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||
|
||||
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
|
||||
document.getElementById('resize').checked)">
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<textarea class="emscripten" id="output" rows="8"></textarea>
|
||||
<hr>
|
||||
<script type='text/javascript'>
|
||||
var statusElement = document.getElementById('status');
|
||||
var progressElement = document.getElementById('progress');
|
||||
var spinnerElement = document.getElementById('spinner');
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
var element = document.getElementById('output');
|
||||
if (element) element.value = ''; // clear browser cache
|
||||
return function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
// These replacements are necessary if you render to raw HTML
|
||||
//text = text.replace(/&/g, "&");
|
||||
//text = text.replace(/</g, "<");
|
||||
//text = text.replace(/>/g, ">");
|
||||
//text = text.replace('\n', '<br>', 'g');
|
||||
console.log(text);
|
||||
if (element) {
|
||||
element.value += text + "\n";
|
||||
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||
}
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
if (0) { // XXX disabled for safety typeof dump == 'function') {
|
||||
dump(text + '\n'); // fast, straight to the real console
|
||||
} else {
|
||||
console.error(text);
|
||||
}
|
||||
},
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) {
|
||||
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
||||
if (text === Module.setStatus.text) return;
|
||||
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||
var now = Date.now();
|
||||
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
|
||||
if (m) {
|
||||
text = m[1];
|
||||
progressElement.value = parseInt(m[2])*100;
|
||||
progressElement.max = parseInt(m[4])*100;
|
||||
progressElement.hidden = false;
|
||||
spinnerElement.hidden = false;
|
||||
} else {
|
||||
progressElement.value = null;
|
||||
progressElement.max = null;
|
||||
progressElement.hidden = true;
|
||||
if (!text) spinnerElement.hidden = true;
|
||||
}
|
||||
statusElement.innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function() {
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
spinnerElement.style.display = 'none';
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,245 @@
|
|||
// Copyright (c) 2014-2017, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline uint32_t rol32(uint32_t x, int r) {
|
||||
static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers");
|
||||
return _rotl(x, r);
|
||||
}
|
||||
|
||||
static inline uint64_t rol64(uint64_t x, int r) {
|
||||
return _rotl64(x, r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline uint32_t rol32(uint32_t x, int r) {
|
||||
return (x << (r & 31)) | (x >> (-r & 31));
|
||||
}
|
||||
|
||||
static inline uint64_t rol64(uint64_t x, int r) {
|
||||
return (x << (r & 63)) | (x >> (-r & 63));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline uint64_t hi_dword(uint64_t val) {
|
||||
return val >> 32;
|
||||
}
|
||||
|
||||
static inline uint64_t lo_dword(uint64_t val) {
|
||||
return val & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||
uint64_t a = hi_dword(multiplier);
|
||||
uint64_t b = lo_dword(multiplier);
|
||||
uint64_t c = hi_dword(multiplicand);
|
||||
uint64_t d = lo_dword(multiplicand);
|
||||
|
||||
uint64_t ac = a * c;
|
||||
uint64_t ad = a * d;
|
||||
uint64_t bc = b * c;
|
||||
uint64_t bd = b * d;
|
||||
|
||||
uint64_t adbc = ad + bc;
|
||||
uint64_t adbc_carry = adbc < ad ? 1 : 0;
|
||||
|
||||
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||
uint64_t product_lo = bd + (adbc << 32);
|
||||
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
|
||||
*product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||
assert(ac <= *product_hi);
|
||||
|
||||
return product_lo;
|
||||
}
|
||||
|
||||
static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) {
|
||||
dividend |= ((uint64_t)*remainder) << 32;
|
||||
*remainder = dividend % divisor;
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
// Long division with 2^32 base
|
||||
static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) {
|
||||
uint64_t dividend_dwords[4];
|
||||
uint32_t remainder = 0;
|
||||
|
||||
dividend_dwords[3] = hi_dword(dividend_hi);
|
||||
dividend_dwords[2] = lo_dword(dividend_hi);
|
||||
dividend_dwords[1] = hi_dword(dividend_lo);
|
||||
dividend_dwords[0] = lo_dword(dividend_lo);
|
||||
|
||||
*quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32;
|
||||
*quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder);
|
||||
*quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32;
|
||||
*quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder);
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
#define IDENT32(x) ((uint32_t) (x))
|
||||
#define IDENT64(x) ((uint64_t) (x))
|
||||
|
||||
#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \
|
||||
(((uint32_t) (x) & 0x0000ff00) << 8) | \
|
||||
(((uint32_t) (x) & 0x00ff0000) >> 8) | \
|
||||
(((uint32_t) (x) & 0xff000000) >> 24))
|
||||
#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \
|
||||
(((uint64_t) (x) & 0x000000000000ff00) << 40) | \
|
||||
(((uint64_t) (x) & 0x0000000000ff0000) << 24) | \
|
||||
(((uint64_t) (x) & 0x00000000ff000000) << 8) | \
|
||||
(((uint64_t) (x) & 0x000000ff00000000) >> 8) | \
|
||||
(((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \
|
||||
(((uint64_t) (x) & 0x00ff000000000000) >> 40) | \
|
||||
(((uint64_t) (x) & 0xff00000000000000) >> 56))
|
||||
|
||||
static inline uint32_t ident32(uint32_t x) { return x; }
|
||||
static inline uint64_t ident64(uint64_t x) { return x; }
|
||||
|
||||
#ifndef __OpenBSD__
|
||||
# if defined(__ANDROID__) && defined(__swap32) && !defined(swap32)
|
||||
# define swap32 __swap32
|
||||
# elif !defined(swap32)
|
||||
static inline uint32_t swap32(uint32_t x) {
|
||||
x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
|
||||
return (x << 16) | (x >> 16);
|
||||
}
|
||||
# endif
|
||||
# if defined(__ANDROID__) && defined(__swap64) && !defined(swap64)
|
||||
# define swap64 __swap64
|
||||
# elif !defined(swap64)
|
||||
static inline uint64_t swap64(uint64_t x) {
|
||||
x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);
|
||||
x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
|
||||
return (x << 32) | (x >> 32);
|
||||
}
|
||||
# endif
|
||||
#endif /* __OpenBSD__ */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }
|
||||
#undef UNUSED
|
||||
|
||||
static inline void mem_inplace_swap32(void *mem, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]);
|
||||
}
|
||||
}
|
||||
static inline void mem_inplace_swap64(void *mem, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void memcpy_ident32(void *dst, const void *src, size_t n) {
|
||||
memcpy(dst, src, 4 * n);
|
||||
}
|
||||
static inline void memcpy_ident64(void *dst, const void *src, size_t n) {
|
||||
memcpy(dst, src, 8 * n);
|
||||
}
|
||||
|
||||
static inline void memcpy_swap32(void *dst, const void *src, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]);
|
||||
}
|
||||
}
|
||||
static inline void memcpy_swap64(void *dst, const void *src, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
|
||||
static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled");
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define SWAP32LE IDENT32
|
||||
#define SWAP32BE SWAP32
|
||||
#define swap32le ident32
|
||||
#define swap32be swap32
|
||||
#define mem_inplace_swap32le mem_inplace_ident
|
||||
#define mem_inplace_swap32be mem_inplace_swap32
|
||||
#define memcpy_swap32le memcpy_ident32
|
||||
#define memcpy_swap32be memcpy_swap32
|
||||
#define SWAP64LE IDENT64
|
||||
#define SWAP64BE SWAP64
|
||||
#define swap64le ident64
|
||||
#define swap64be swap64
|
||||
#define mem_inplace_swap64le mem_inplace_ident
|
||||
#define mem_inplace_swap64be mem_inplace_swap64
|
||||
#define memcpy_swap64le memcpy_ident64
|
||||
#define memcpy_swap64be memcpy_swap64
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define SWAP32BE IDENT32
|
||||
#define SWAP32LE SWAP32
|
||||
#define swap32be ident32
|
||||
#define swap32le swap32
|
||||
#define mem_inplace_swap32be mem_inplace_ident
|
||||
#define mem_inplace_swap32le mem_inplace_swap32
|
||||
#define memcpy_swap32be memcpy_ident32
|
||||
#define memcpy_swap32le memcpy_swap32
|
||||
#define SWAP64BE IDENT64
|
||||
#define SWAP64LE SWAP64
|
||||
#define swap64be ident64
|
||||
#define swap64le swap64
|
||||
#define mem_inplace_swap64be mem_inplace_ident
|
||||
#define mem_inplace_swap64le mem_inplace_swap64
|
||||
#define memcpy_swap64be memcpy_ident64
|
||||
#define memcpy_swap64le memcpy_swap64
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef JH_H
|
||||
#define JH_H
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void jh(unsigned bit_len, const uint8_t input[],
|
||||
size_t input_bit_length, uint8_t output[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,377 @@
|
|||
/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C
|
||||
|
||||
--------------------------------
|
||||
Performance
|
||||
|
||||
Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)
|
||||
Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)
|
||||
Speed for long message:
|
||||
1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2
|
||||
2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3
|
||||
|
||||
--------------------------------
|
||||
Last Modified: January 16, 2011
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
typedef unsigned char BitSequence;
|
||||
typedef unsigned long long DataLength;
|
||||
typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;
|
||||
|
||||
/*define data alignment for different C compilers*/
|
||||
#if defined(__GNUC__)
|
||||
#define DATA_ALIGN16(x) x __attribute__ ((aligned(16)))
|
||||
#else
|
||||
#define DATA_ALIGN16(x) __declspec(align(16)) x
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
int hashbitlen; /*the message digest size*/
|
||||
unsigned long long databitlen; /*the message size in bits*/
|
||||
unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
|
||||
DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
|
||||
unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/
|
||||
} hashState;
|
||||
|
||||
|
||||
/*The initial hash value H(0)*/
|
||||
static const unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e};
|
||||
static const unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69};
|
||||
static const unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f};
|
||||
static const unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b};
|
||||
|
||||
/*42 round constants, each round constant is 32-byte (256-bit)*/
|
||||
static const unsigned char E8_bitslice_roundconstant[42][32]={
|
||||
{0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40},
|
||||
{0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31},
|
||||
{0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc},
|
||||
{0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3},
|
||||
{0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23},
|
||||
{0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97},
|
||||
{0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14},
|
||||
{0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4},
|
||||
{0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36},
|
||||
{0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f},
|
||||
{0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b},
|
||||
{0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62},
|
||||
{0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5},
|
||||
{0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f},
|
||||
{0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a},
|
||||
{0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf},
|
||||
{0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0},
|
||||
{0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a},
|
||||
{0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6},
|
||||
{0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67},
|
||||
{0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18},
|
||||
{0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e},
|
||||
{0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1},
|
||||
{0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83},
|
||||
{0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef},
|
||||
{0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65},
|
||||
{0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c},
|
||||
{0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71},
|
||||
{0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0},
|
||||
{0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f},
|
||||
{0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad},
|
||||
{0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6},
|
||||
{0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63},
|
||||
{0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f},
|
||||
{0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a},
|
||||
{0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5},
|
||||
{0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48},
|
||||
{0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e},
|
||||
{0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7},
|
||||
{0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde},
|
||||
{0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a},
|
||||
{0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}};
|
||||
|
||||
|
||||
static void E8(hashState *state); /*The bijective function E8, in bitslice form*/
|
||||
static void F8(hashState *state); /*The compression function F8 */
|
||||
|
||||
/*The API functions*/
|
||||
static HashReturn Init(hashState *state, int hashbitlen);
|
||||
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
|
||||
static HashReturn Final(hashState *state, BitSequence *hashval);
|
||||
static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval);
|
||||
|
||||
/*swapping bit 2i with bit 2i+1 of 64-bit x*/
|
||||
#define SWAP1(x) (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1));
|
||||
/*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/
|
||||
#define SWAP2(x) (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2));
|
||||
/*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/
|
||||
#define SWAP4(x) (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4));
|
||||
/*swapping bits 16i||16i+1||......||16i+7 with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/
|
||||
#define SWAP8(x) (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8));
|
||||
/*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/
|
||||
#define SWAP16(x) (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16));
|
||||
/*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/
|
||||
#define SWAP32(x) (x) = (((x) << 32) | ((x) >> 32));
|
||||
|
||||
/*The MDS transform*/
|
||||
#define L(m0,m1,m2,m3,m4,m5,m6,m7) \
|
||||
(m4) ^= (m1); \
|
||||
(m5) ^= (m2); \
|
||||
(m6) ^= (m0) ^ (m3); \
|
||||
(m7) ^= (m0); \
|
||||
(m0) ^= (m5); \
|
||||
(m1) ^= (m6); \
|
||||
(m2) ^= (m4) ^ (m7); \
|
||||
(m3) ^= (m4);
|
||||
|
||||
/*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/
|
||||
/*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/
|
||||
#define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1) \
|
||||
m3 = ~(m3); \
|
||||
m7 = ~(m7); \
|
||||
m0 ^= ((~(m2)) & (cc0)); \
|
||||
m4 ^= ((~(m6)) & (cc1)); \
|
||||
temp0 = (cc0) ^ ((m0) & (m1));\
|
||||
temp1 = (cc1) ^ ((m4) & (m5));\
|
||||
m0 ^= ((m2) & (m3)); \
|
||||
m4 ^= ((m6) & (m7)); \
|
||||
m3 ^= ((~(m1)) & (m2)); \
|
||||
m7 ^= ((~(m5)) & (m6)); \
|
||||
m1 ^= ((m0) & (m2)); \
|
||||
m5 ^= ((m4) & (m6)); \
|
||||
m2 ^= ((m0) & (~(m3))); \
|
||||
m6 ^= ((m4) & (~(m7))); \
|
||||
m0 ^= ((m1) | (m3)); \
|
||||
m4 ^= ((m5) | (m7)); \
|
||||
m3 ^= ((m1) & (m2)); \
|
||||
m7 ^= ((m5) & (m6)); \
|
||||
m1 ^= (temp0 & (m0)); \
|
||||
m5 ^= (temp1 & (m4)); \
|
||||
m2 ^= temp0; \
|
||||
m6 ^= temp1;
|
||||
|
||||
/*The bijective function E8, in bitslice form*/
|
||||
static void E8(hashState *state)
|
||||
{
|
||||
uint64 i,roundnumber,temp0,temp1;
|
||||
|
||||
for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) {
|
||||
/*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+6: Sbox and MDS layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
}
|
||||
/*round 7*roundnumber+6: swapping layer*/
|
||||
for (i = 1; i < 8; i = i+2) {
|
||||
temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*The compression function F8 */
|
||||
static void F8(hashState *state)
|
||||
{
|
||||
uint64 i;
|
||||
|
||||
/*xor the 512-bit message with the fist half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];
|
||||
|
||||
/*the bijective function E8 */
|
||||
E8(state);
|
||||
|
||||
/*xor the 512-bit message with the second half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
|
||||
}
|
||||
|
||||
/*before hashing a message, initialize the hash state as H0 */
|
||||
static HashReturn Init(hashState *state, int hashbitlen)
|
||||
{
|
||||
state->databitlen = 0;
|
||||
state->datasize_in_buffer = 0;
|
||||
|
||||
/*initialize the initial hash value of JH*/
|
||||
state->hashbitlen = hashbitlen;
|
||||
|
||||
/*load the intital hash value into state*/
|
||||
switch (hashbitlen)
|
||||
{
|
||||
case 224: memcpy(state->x,JH224_H0,128); break;
|
||||
case 256: memcpy(state->x,JH256_H0,128); break;
|
||||
case 384: memcpy(state->x,JH384_H0,128); break;
|
||||
case 512: memcpy(state->x,JH512_H0,128); break;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*hash each 512-bit message block, except the last partial block*/
|
||||
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
|
||||
{
|
||||
DataLength index; /*the starting address of the data to be compressed*/
|
||||
|
||||
state->databitlen += databitlen;
|
||||
index = 0;
|
||||
|
||||
/*if there is remaining data in the buffer, fill it to a full message block first*/
|
||||
/*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/
|
||||
|
||||
/*There is data in the buffer, but the incoming data is insufficient for a full block*/
|
||||
if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512) ) {
|
||||
if ( (databitlen & 7) == 0 ) {
|
||||
memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ;
|
||||
}
|
||||
else memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ;
|
||||
state->datasize_in_buffer += databitlen;
|
||||
databitlen = 0;
|
||||
}
|
||||
|
||||
/*There is data in the buffer, and the incoming data is sufficient for a full block*/
|
||||
if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512) ) {
|
||||
memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ;
|
||||
index = 64-(state->datasize_in_buffer >> 3);
|
||||
databitlen = databitlen - (512 - state->datasize_in_buffer);
|
||||
F8(state);
|
||||
state->datasize_in_buffer = 0;
|
||||
}
|
||||
|
||||
/*hash the remaining full message blocks*/
|
||||
for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) {
|
||||
memcpy(state->buffer, data+index, 64);
|
||||
F8(state);
|
||||
}
|
||||
|
||||
/*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/
|
||||
if ( databitlen > 0) {
|
||||
if ((databitlen & 7) == 0)
|
||||
memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3);
|
||||
else
|
||||
memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1);
|
||||
state->datasize_in_buffer = databitlen;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/
|
||||
static HashReturn Final(hashState *state, BitSequence *hashval)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ( (state->databitlen & 0x1ff) == 0 ) {
|
||||
/*pad the message when databitlen is multiple of 512 bits, then process the padded block*/
|
||||
memset(state->buffer, 0, 64);
|
||||
state->buffer[0] = 0x80;
|
||||
state->buffer[63] = state->databitlen & 0xff;
|
||||
state->buffer[62] = (state->databitlen >> 8) & 0xff;
|
||||
state->buffer[61] = (state->databitlen >> 16) & 0xff;
|
||||
state->buffer[60] = (state->databitlen >> 24) & 0xff;
|
||||
state->buffer[59] = (state->databitlen >> 32) & 0xff;
|
||||
state->buffer[58] = (state->databitlen >> 40) & 0xff;
|
||||
state->buffer[57] = (state->databitlen >> 48) & 0xff;
|
||||
state->buffer[56] = (state->databitlen >> 56) & 0xff;
|
||||
F8(state);
|
||||
}
|
||||
else {
|
||||
/*set the rest of the bytes in the buffer to 0*/
|
||||
if ( (state->datasize_in_buffer & 7) == 0)
|
||||
for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++) state->buffer[i] = 0;
|
||||
else
|
||||
for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++) state->buffer[i] = 0;
|
||||
|
||||
/*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/
|
||||
state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7));
|
||||
|
||||
F8(state);
|
||||
memset(state->buffer, 0, 64);
|
||||
state->buffer[63] = state->databitlen & 0xff;
|
||||
state->buffer[62] = (state->databitlen >> 8) & 0xff;
|
||||
state->buffer[61] = (state->databitlen >> 16) & 0xff;
|
||||
state->buffer[60] = (state->databitlen >> 24) & 0xff;
|
||||
state->buffer[59] = (state->databitlen >> 32) & 0xff;
|
||||
state->buffer[58] = (state->databitlen >> 40) & 0xff;
|
||||
state->buffer[57] = (state->databitlen >> 48) & 0xff;
|
||||
state->buffer[56] = (state->databitlen >> 56) & 0xff;
|
||||
F8(state);
|
||||
}
|
||||
|
||||
/*truncating the final hash value to generate the message digest*/
|
||||
switch(state->hashbitlen) {
|
||||
case 224: memcpy(hashval,(unsigned char*)state->x+64+36,28); break;
|
||||
case 256: memcpy(hashval,(unsigned char*)state->x+64+32,32); break;
|
||||
case 384: memcpy(hashval,(unsigned char*)state->x+64+16,48); break;
|
||||
case 512: memcpy(hashval,(unsigned char*)state->x+64,64); break;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
/* hash a message,
|
||||
three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen)
|
||||
one output: message digest (hashval)
|
||||
*/
|
||||
static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval)
|
||||
{
|
||||
hashState state;
|
||||
|
||||
if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) {
|
||||
Init(&state, hashbitlen);
|
||||
Update(&state, data, databitlen);
|
||||
Final(&state, hashval);
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
return(BAD_HASHLEN);
|
||||
}
|
||||
|
||||
void jh(unsigned bit_len, const uint8_t input[], size_t input_bit_length, uint8_t output[])
|
||||
{
|
||||
HashReturn ret = Hash(bit_len, input, input_bit_length, output);
|
||||
assert(ret == SUCCESS);
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
// keccak.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
// A baseline Keccak (3rd round) implementation.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
#include "keccak.h"
|
||||
|
||||
#define HASH_DATA_AREA 136
|
||||
#define KECCAK_ROUNDS 24
|
||||
|
||||
#ifndef ROTL64
|
||||
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
|
||||
#endif
|
||||
|
||||
const uint64_t keccakf_rndc[24] =
|
||||
{
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
};
|
||||
|
||||
const int keccakf_rotc[24] =
|
||||
{
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
|
||||
};
|
||||
|
||||
const int keccakf_piln[24] =
|
||||
{
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
};
|
||||
|
||||
// update the state with given number of rounds
|
||||
|
||||
void keccakf(uint64_t st[25], int rounds)
|
||||
{
|
||||
int i, j, round;
|
||||
uint64_t t, bc[5];
|
||||
|
||||
for (round = 0; round < rounds; ++round) {
|
||||
|
||||
// Theta
|
||||
bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
|
||||
bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
|
||||
bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
|
||||
bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
|
||||
bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
|
||||
st[i ] ^= t;
|
||||
st[i + 5] ^= t;
|
||||
st[i + 10] ^= t;
|
||||
st[i + 15] ^= t;
|
||||
st[i + 20] ^= t;
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
for (i = 0; i < 24; ++i) {
|
||||
bc[0] = st[keccakf_piln[i]];
|
||||
st[keccakf_piln[i]] = ROTL64(t, keccakf_rotc[i]);
|
||||
t = bc[0];
|
||||
}
|
||||
|
||||
// Chi
|
||||
for (j = 0; j < 25; j += 5) {
|
||||
bc[0] = st[j ];
|
||||
bc[1] = st[j + 1];
|
||||
bc[2] = st[j + 2];
|
||||
bc[3] = st[j + 3];
|
||||
bc[4] = st[j + 4];
|
||||
st[j ] ^= (~bc[1]) & bc[2];
|
||||
st[j + 1] ^= (~bc[2]) & bc[3];
|
||||
st[j + 2] ^= (~bc[3]) & bc[4];
|
||||
st[j + 3] ^= (~bc[4]) & bc[0];
|
||||
st[j + 4] ^= (~bc[0]) & bc[1];
|
||||
}
|
||||
|
||||
// Iota
|
||||
st[0] ^= keccakf_rndc[round];
|
||||
}
|
||||
}
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
typedef uint64_t state_t[25];
|
||||
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
||||
{
|
||||
state_t st;
|
||||
uint8_t temp[144];
|
||||
int i, rsiz, rsizw;
|
||||
|
||||
rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen;
|
||||
rsizw = rsiz / 8;
|
||||
|
||||
memset(st, 0, sizeof(st));
|
||||
|
||||
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
|
||||
for (i = 0; i < rsizw; i++)
|
||||
st[i] ^= ((uint64_t *) in)[i];
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
// last block and padding
|
||||
memcpy(temp, in, inlen);
|
||||
temp[inlen++] = 1;
|
||||
memset(temp + inlen, 0, rsiz - inlen);
|
||||
temp[rsiz - 1] |= 0x80;
|
||||
|
||||
for (i = 0; i < rsizw; i++)
|
||||
st[i] ^= ((uint64_t *) temp)[i];
|
||||
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
|
||||
memcpy(md, st, mdlen);
|
||||
}
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md)
|
||||
{
|
||||
keccak(in, inlen, md, sizeof(state_t));
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// keccak.h
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#ifndef KECCAK_H
|
||||
#define KECCAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);
|
||||
|
||||
void keccakf(uint64_t st[25], int norounds);
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
code is based on
|
||||
|
||||
https://github.com/noahdesu/xmonarch
|
||||
|
||||
which is based on the monero code.
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2014-2018, The Monero Project
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Parts of the project are originally copyright (c) 2012-2013 The Cryptonote
|
||||
developers
|
|
@ -0,0 +1,53 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "cryptonight.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "jh.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
char* tohex(unsigned char * in)
|
||||
{
|
||||
size_t size = 32;
|
||||
|
||||
char output[(size * 2) + 1];
|
||||
|
||||
char *ptr = &output[0];
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
ptr += sprintf (ptr, "%02x",in[i]);
|
||||
}
|
||||
|
||||
return &output[0];
|
||||
}
|
||||
|
||||
|
||||
char* hash_cn(char* hex, char* nonce)
|
||||
{
|
||||
unsigned char inp[76];
|
||||
|
||||
char *pos = hex;
|
||||
for( size_t i = 0; i < 76; i++) { sscanf(pos, "%2hhx", &inp[i]); pos += 2; }
|
||||
|
||||
pos = nonce;
|
||||
|
||||
for(size_t i = 39; i < 43; i++) { sscanf(pos, "%2hhx", &inp[i]); pos += 2; }
|
||||
|
||||
unsigned char hash[76];
|
||||
cryptonight(hash, inp, 76);
|
||||
|
||||
|
||||
return tohex(hash);
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_CONFIG_H
|
||||
#define _OAES_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#ifndef OAES_HAVE_ISAAC
|
||||
//#define OAES_HAVE_ISAAC 1
|
||||
//#endif // OAES_HAVE_ISAAC
|
||||
|
||||
//#ifndef OAES_DEBUG
|
||||
//#define OAES_DEBUG 0
|
||||
//#endif // OAES_DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_CONFIG_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_LIB_H
|
||||
#define _OAES_LIB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef OAES_SHARED
|
||||
# ifdef oaes_lib_EXPORTS
|
||||
# define OAES_API __declspec(dllexport)
|
||||
# else
|
||||
# define OAES_API __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define OAES_API
|
||||
# endif
|
||||
#else
|
||||
# define OAES_API
|
||||
#endif // WIN32
|
||||
|
||||
#define OAES_VERSION "0.8.1"
|
||||
#define OAES_BLOCK_SIZE 16
|
||||
|
||||
typedef void OAES_CTX;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OAES_RET_FIRST = 0,
|
||||
OAES_RET_SUCCESS = 0,
|
||||
OAES_RET_UNKNOWN,
|
||||
OAES_RET_ARG1,
|
||||
OAES_RET_ARG2,
|
||||
OAES_RET_ARG3,
|
||||
OAES_RET_ARG4,
|
||||
OAES_RET_ARG5,
|
||||
OAES_RET_NOKEY,
|
||||
OAES_RET_MEM,
|
||||
OAES_RET_BUF,
|
||||
OAES_RET_HEADER,
|
||||
OAES_RET_COUNT
|
||||
} OAES_RET;
|
||||
|
||||
/*
|
||||
* oaes_set_option() takes one of these values for its [option] parameter
|
||||
* some options accept either an optional or a required [value] parameter
|
||||
*/
|
||||
// no option
|
||||
#define OAES_OPTION_NONE 0
|
||||
// enable ECB mode, disable CBC mode
|
||||
#define OAES_OPTION_ECB 1
|
||||
// enable CBC mode, disable ECB mode
|
||||
// value is optional, may pass uint8_t iv[OAES_BLOCK_SIZE] to specify
|
||||
// the value of the initialization vector, iv
|
||||
#define OAES_OPTION_CBC 2
|
||||
|
||||
#ifdef OAES_DEBUG
|
||||
typedef int ( * oaes_step_cb ) (
|
||||
const uint8_t state[OAES_BLOCK_SIZE],
|
||||
const char * step_name,
|
||||
int step_count,
|
||||
void * user_data );
|
||||
// enable state stepping mode
|
||||
// value is required, must pass oaes_step_cb to receive the state at each step
|
||||
#define OAES_OPTION_STEP_ON 4
|
||||
// disable state stepping mode
|
||||
#define OAES_OPTION_STEP_OFF 8
|
||||
#endif // OAES_DEBUG
|
||||
|
||||
typedef uint16_t OAES_OPTION;
|
||||
|
||||
typedef struct _oaes_key
|
||||
{
|
||||
size_t data_len;
|
||||
uint8_t *data;
|
||||
size_t exp_data_len;
|
||||
uint8_t *exp_data;
|
||||
size_t num_keys;
|
||||
size_t key_base;
|
||||
} oaes_key;
|
||||
|
||||
typedef struct _oaes_ctx
|
||||
{
|
||||
#ifdef OAES_HAVE_ISAAC
|
||||
randctx * rctx;
|
||||
#endif // OAES_HAVE_ISAAC
|
||||
|
||||
#ifdef OAES_DEBUG
|
||||
oaes_step_cb step_cb;
|
||||
#endif // OAES_DEBUG
|
||||
|
||||
oaes_key * key;
|
||||
OAES_OPTION options;
|
||||
uint8_t iv[OAES_BLOCK_SIZE];
|
||||
} oaes_ctx;
|
||||
/*
|
||||
* // usage:
|
||||
*
|
||||
* OAES_CTX * ctx = oaes_alloc();
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* {
|
||||
* oaes_gen_key_xxx( ctx );
|
||||
* {
|
||||
* oaes_key_export( ctx, _buf, &_buf_len );
|
||||
* // or
|
||||
* oaes_key_export_data( ctx, _buf, &_buf_len );\
|
||||
* }
|
||||
* }
|
||||
* // or
|
||||
* {
|
||||
* oaes_key_import( ctx, _buf, _buf_len );
|
||||
* // or
|
||||
* oaes_key_import_data( ctx, _buf, _buf_len );
|
||||
* }
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_encrypt( ctx, m, m_len, c, &c_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_decrypt( ctx, c, c_len, m, &m_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_free( &ctx );
|
||||
*/
|
||||
|
||||
OAES_API OAES_CTX * oaes_alloc(void);
|
||||
|
||||
OAES_API OAES_RET oaes_free( OAES_CTX ** ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_set_option( OAES_CTX * ctx,
|
||||
OAES_OPTION option, const void * value );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_128( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_192( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_256( OAES_CTX * ctx );
|
||||
|
||||
// export key with header information
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// directly export the data from key
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export_data( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// import key with header information
|
||||
OAES_API OAES_RET oaes_key_import( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// directly import data into key
|
||||
OAES_API OAES_RET oaes_key_import_data( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// set c == NULL to get the required c_len
|
||||
OAES_API OAES_RET oaes_encrypt( OAES_CTX * ctx,
|
||||
const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len );
|
||||
|
||||
// set m == NULL to get the required m_len
|
||||
OAES_API OAES_RET oaes_decrypt( OAES_CTX * ctx,
|
||||
const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len );
|
||||
|
||||
// set buf == NULL to get the required buf_len
|
||||
OAES_API OAES_RET oaes_sprintf(
|
||||
char * buf, size_t * buf_len, const uint8_t * data, size_t data_len );
|
||||
|
||||
OAES_API OAES_RET oaes_encryption_round( const uint8_t * key, uint8_t * c );
|
||||
|
||||
OAES_API OAES_RET oaes_pseudo_encrypt_ecb( OAES_CTX * ctx, uint8_t * c );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_LIB_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
#ifndef SKEIN_H
|
||||
#define SKEIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int skein(int hashbitlen, const unsigned char *input,
|
||||
size_t input_len, unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,179 @@
|
|||
#ifndef _SKEIN_PORT_H_
|
||||
#define _SKEIN_PORT_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef RETURN_VALUES
|
||||
# define RETURN_VALUES
|
||||
# if defined( DLL_EXPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllexport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllexport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllexport__ ) void
|
||||
# define INT_RETURN __declspec( __dllexport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( DLL_IMPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllimport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllimport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllimport__ ) void
|
||||
# define INT_RETURN __declspec( __dllimport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( __WATCOMC__ )
|
||||
# define VOID_RETURN void __cdecl
|
||||
# define INT_RETURN int __cdecl
|
||||
# else
|
||||
# define VOID_RETURN void
|
||||
# define INT_RETURN int
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These defines are used to declare buffers in a way that allows
|
||||
faster operations on longer variables to be used. In all these
|
||||
defines 'size' must be a power of 2 and >= 8
|
||||
|
||||
dec_unit_type(size,x) declares a variable 'x' of length
|
||||
'size' bits
|
||||
|
||||
dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'
|
||||
bytes defined as an array of variables
|
||||
each of 'size' bits (bsize must be a
|
||||
multiple of size / 8)
|
||||
|
||||
ptr_cast(x,size) casts a pointer to a pointer to a
|
||||
varaiable of length 'size' bits
|
||||
*/
|
||||
|
||||
#define ui_type(size) uint##size##_t
|
||||
#define dec_unit_type(size,x) typedef ui_type(size) x
|
||||
#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]
|
||||
#define ptr_cast(x,size) ((ui_type(size)*)(x))
|
||||
|
||||
typedef unsigned int uint_t; /* native unsigned integer */
|
||||
typedef uint8_t u08b_t; /* 8-bit unsigned integer */
|
||||
typedef uint64_t u64b_t; /* 64-bit unsigned integer */
|
||||
|
||||
#ifndef RotL_64
|
||||
#define RotL_64(x,N) (((x) << (N)) | ((x) >> (64-(N))))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Skein is "natively" little-endian (unlike SHA-xxx), for optimal
|
||||
* performance on x86 CPUs. The Skein code requires the following
|
||||
* definitions for dealing with endianness:
|
||||
*
|
||||
* SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian
|
||||
* Skein_Put64_LSB_First
|
||||
* Skein_Get64_LSB_First
|
||||
* Skein_Swap64
|
||||
*
|
||||
* If SKEIN_NEED_SWAP is defined at compile time, it is used here
|
||||
* along with the portable versions of Put64/Get64/Swap64, which
|
||||
* are slow in general.
|
||||
*
|
||||
* Otherwise, an "auto-detect" of endianness is attempted below.
|
||||
* If the default handling doesn't work well, the user may insert
|
||||
* platform-specific code instead (e.g., for big-endian CPUs).
|
||||
*
|
||||
*/
|
||||
#ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
|
||||
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
/* special handler for IA64, which may be either endianness (?) */
|
||||
/* here we assume little-endian, but this may need to be changed */
|
||||
#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
# define PLATFORM_MUST_ALIGN (1)
|
||||
#ifndef PLATFORM_BYTE_ORDER
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_MUST_ALIGN
|
||||
# define PLATFORM_MUST_ALIGN (0)
|
||||
#endif
|
||||
|
||||
|
||||
#if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN
|
||||
/* here for big-endian CPUs */
|
||||
#define SKEIN_NEED_SWAP (1)
|
||||
#elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
|
||||
/* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */
|
||||
#define SKEIN_NEED_SWAP (0)
|
||||
#if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */
|
||||
#define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt)
|
||||
#define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt))
|
||||
#endif
|
||||
#else
|
||||
#error "Skein needs endianness setting!"
|
||||
#endif
|
||||
|
||||
#endif /* ifndef SKEIN_NEED_SWAP */
|
||||
|
||||
/*
|
||||
******************************************************************
|
||||
* Provide any definitions still needed.
|
||||
******************************************************************
|
||||
*/
|
||||
#ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */
|
||||
#if SKEIN_NEED_SWAP
|
||||
#define Skein_Swap64(w64) \
|
||||
( (( ((u64b_t)(w64)) & 0xFF) << 56) | \
|
||||
(((((u64b_t)(w64)) >> 8) & 0xFF) << 48) | \
|
||||
(((((u64b_t)(w64)) >>16) & 0xFF) << 40) | \
|
||||
(((((u64b_t)(w64)) >>24) & 0xFF) << 32) | \
|
||||
(((((u64b_t)(w64)) >>32) & 0xFF) << 24) | \
|
||||
(((((u64b_t)(w64)) >>40) & 0xFF) << 16) | \
|
||||
(((((u64b_t)(w64)) >>48) & 0xFF) << 8) | \
|
||||
(((((u64b_t)(w64)) >>56) & 0xFF) ) )
|
||||
#else
|
||||
#define Skein_Swap64(w64) (w64)
|
||||
#endif
|
||||
#endif /* ifndef Skein_Swap64 */
|
||||
|
||||
|
||||
#ifndef Skein_Put64_LSB_First
|
||||
void Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)
|
||||
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
|
||||
{ /* this version is fully portable (big-endian or little-endian), but slow */
|
||||
size_t n;
|
||||
|
||||
for (n=0;n<bCnt;n++)
|
||||
dst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));
|
||||
}
|
||||
#else
|
||||
; /* output only the function prototype */
|
||||
#endif
|
||||
#endif /* ifndef Skein_Put64_LSB_First */
|
||||
|
||||
|
||||
#ifndef Skein_Get64_LSB_First
|
||||
void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)
|
||||
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
|
||||
{ /* this version is fully portable (big-endian or little-endian), but slow */
|
||||
size_t n;
|
||||
|
||||
for (n=0;n<8*wCnt;n+=8)
|
||||
dst[n/8] = (((u64b_t) src[n ]) ) +
|
||||
(((u64b_t) src[n+1]) << 8) +
|
||||
(((u64b_t) src[n+2]) << 16) +
|
||||
(((u64b_t) src[n+3]) << 24) +
|
||||
(((u64b_t) src[n+4]) << 32) +
|
||||
(((u64b_t) src[n+5]) << 40) +
|
||||
(((u64b_t) src[n+6]) << 48) +
|
||||
(((u64b_t) src[n+7]) << 56) ;
|
||||
}
|
||||
#else
|
||||
; /* output only the function prototype */
|
||||
#endif
|
||||
#endif /* ifndef Skein_Get64_LSB_First */
|
||||
|
||||
#endif /* ifndef _SKEIN_PORT_H_ */
|
|
@ -0,0 +1,28 @@
|
|||
TARGET = prog
|
||||
LIBS = -lm
|
||||
CC = emcc -O3 -s SINGLE_FILE=1 -s NO_FILESYSTEM=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' --llvm-lto 1 -s TOTAL_MEMORY=67108864 -s WASM=1 -s "BINARYEN_TRAP_MODE='allow'" -s EXPORTED_FUNCTIONS="['_hash_cn']" --shell-file html_template/shell_minimal.html
|
||||
CFLAGS = -Wall -msse2
|
||||
|
||||
|
||||
# SINGLE_FILE=1
|
||||
|
||||
# -s ASSERTIONS=1
|
||||
# -s SINGLE_FILE=1
|
||||
.PHONY: default all clean
|
||||
|
||||
default: $(TARGET)
|
||||
all: default
|
||||
|
||||
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
|
||||
HEADERS = $(wildcard *.h)
|
||||
|
||||
%.o: %.c $(HEADERS) $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
.PRECIOUS: $(TARGET) $(OBJECTS)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -Wall $(LIBS) -o cn.html
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
||||
-rm -f $(TARGET)
|
|
@ -0,0 +1,258 @@
|
|||
// https://github.com/tkislan/base64
|
||||
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
class Base64 {
|
||||
public:
|
||||
static bool Encode(const std::string &in, std::string *out) {
|
||||
int i = 0, j = 0;
|
||||
size_t enc_len = 0;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
out->resize(EncodedLength(in));
|
||||
|
||||
int input_len = in.size();
|
||||
std::string::const_iterator input = in.begin();
|
||||
|
||||
while (input_len--) {
|
||||
a3[i++] = *(input++);
|
||||
if (i == 3) {
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
(*out)[enc_len++] = kBase64Alphabet[a4[i]];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 3; j++) {
|
||||
a3[j] = '\0';
|
||||
}
|
||||
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (j = 0; j < i + 1; j++) {
|
||||
(*out)[enc_len++] = kBase64Alphabet[a4[j]];
|
||||
}
|
||||
|
||||
while ((i++ < 3)) {
|
||||
(*out)[enc_len++] = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return (enc_len == out->size());
|
||||
}
|
||||
|
||||
static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) {
|
||||
int i = 0, j = 0;
|
||||
char *out_begin = out;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
size_t encoded_length = EncodedLength(input_length);
|
||||
|
||||
if (out_length < encoded_length) return false;
|
||||
|
||||
while (input_length--) {
|
||||
a3[i++] = *input++;
|
||||
if (i == 3) {
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
*out++ = kBase64Alphabet[a4[i]];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 3; j++) {
|
||||
a3[j] = '\0';
|
||||
}
|
||||
|
||||
a3_to_a4(a4, a3);
|
||||
|
||||
for (j = 0; j < i + 1; j++) {
|
||||
*out++ = kBase64Alphabet[a4[j]];
|
||||
}
|
||||
|
||||
while ((i++ < 3)) {
|
||||
*out++ = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return (out == (out_begin + encoded_length));
|
||||
}
|
||||
|
||||
static bool Decode(const std::string &in, std::string *out) {
|
||||
int i = 0, j = 0;
|
||||
size_t dec_len = 0;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
int input_len = in.size();
|
||||
std::string::const_iterator input = in.begin();
|
||||
|
||||
out->resize(DecodedLength(in));
|
||||
|
||||
while (input_len--) {
|
||||
if (*input == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
a4[i++] = *(input++);
|
||||
if (i == 4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
a4[i] = b64_lookup(a4[i]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
(*out)[dec_len++] = a3[i];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 4; j++) {
|
||||
a4[j] = '\0';
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
a4[j] = b64_lookup(a4[j]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
(*out)[dec_len++] = a3[j];
|
||||
}
|
||||
}
|
||||
|
||||
return (dec_len == out->size());
|
||||
}
|
||||
|
||||
static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) {
|
||||
int i = 0, j = 0;
|
||||
char *out_begin = out;
|
||||
unsigned char a3[3];
|
||||
unsigned char a4[4];
|
||||
|
||||
size_t decoded_length = DecodedLength(input, input_length);
|
||||
|
||||
if (out_length < decoded_length) return false;
|
||||
|
||||
while (input_length--) {
|
||||
if (*input == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
a4[i++] = *(input++);
|
||||
if (i == 4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
a4[i] = b64_lookup(a4[i]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
*out++ = a3[i];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 4; j++) {
|
||||
a4[j] = '\0';
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
a4[j] = b64_lookup(a4[j]);
|
||||
}
|
||||
|
||||
a4_to_a3(a3,a4);
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
*out++ = a3[j];
|
||||
}
|
||||
}
|
||||
|
||||
return (out == (out_begin + decoded_length));
|
||||
}
|
||||
|
||||
static int DecodedLength(const char *in, size_t in_length) {
|
||||
int numEq = 0;
|
||||
|
||||
const char *in_end = in + in_length;
|
||||
while (*--in_end == '=') ++numEq;
|
||||
|
||||
return ((6 * in_length) / 8) - numEq;
|
||||
}
|
||||
|
||||
static int DecodedLength(const std::string &in) {
|
||||
int numEq = 0;
|
||||
int n = in.size();
|
||||
|
||||
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) {
|
||||
++numEq;
|
||||
}
|
||||
|
||||
return ((6 * n) / 8) - numEq;
|
||||
}
|
||||
|
||||
inline static int EncodedLength(size_t length) {
|
||||
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
|
||||
}
|
||||
|
||||
inline static int EncodedLength(const std::string &in) {
|
||||
return EncodedLength(in.length());
|
||||
}
|
||||
|
||||
inline static void StripPadding(std::string *in) {
|
||||
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
|
||||
a4[0] = (a3[0] & 0xfc) >> 2;
|
||||
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
|
||||
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
|
||||
a4[3] = (a3[2] & 0x3f);
|
||||
}
|
||||
|
||||
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
|
||||
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
|
||||
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
|
||||
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
|
||||
}
|
||||
|
||||
static inline unsigned char b64_lookup(unsigned char c) {
|
||||
if(c >='A' && c <='Z') return c - 'A';
|
||||
if(c >='a' && c <='z') return c - 71;
|
||||
if(c >='0' && c <='9') return c + 4;
|
||||
if(c == '+') return 62;
|
||||
if(c == '/') return 63;
|
||||
return 255;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BASE64_H
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* The blake256_* and blake224_* functions are largely copied from
|
||||
* blake256_light.c and blake224_light.c from the BLAKE website:
|
||||
*
|
||||
* http://131002.net/blake/
|
||||
*
|
||||
* The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224.
|
||||
* HMAC is specified by RFC 2104.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t h[8], s[4], t[2];
|
||||
int buflen, nullt;
|
||||
uint8_t buf[64];
|
||||
} state;
|
||||
|
||||
typedef struct {
|
||||
state inner;
|
||||
state outer;
|
||||
} hmac_state;
|
||||
|
||||
|
||||
#define U8TO32(p) \
|
||||
(((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \
|
||||
((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) ))
|
||||
#define U32TO8(p, v) \
|
||||
(p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \
|
||||
(p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) );
|
||||
|
||||
const uint8_t sigma[][16] = {
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
|
||||
{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},
|
||||
{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},
|
||||
{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8},
|
||||
{ 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13},
|
||||
{ 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9},
|
||||
{12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11},
|
||||
{13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10},
|
||||
{ 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0},
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
|
||||
{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},
|
||||
{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},
|
||||
{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8}
|
||||
};
|
||||
|
||||
const uint32_t cst[16] = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
|
||||
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
|
||||
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
|
||||
};
|
||||
|
||||
static const uint8_t padding[] = {
|
||||
0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
|
||||
void blake256_compress(state *S, const uint8_t *block) {
|
||||
uint32_t v[16], m[16], i;
|
||||
|
||||
#define ROT(x,n) (((x)<<(32-n))|((x)>>(n)))
|
||||
#define G(a,b,c,d,e) \
|
||||
v[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \
|
||||
v[d] = ROT(v[d] ^ v[a],16); \
|
||||
v[c] += v[d]; \
|
||||
v[b] = ROT(v[b] ^ v[c],12); \
|
||||
v[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b]; \
|
||||
v[d] = ROT(v[d] ^ v[a], 8); \
|
||||
v[c] += v[d]; \
|
||||
v[b] = ROT(v[b] ^ v[c], 7);
|
||||
|
||||
for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4);
|
||||
for (i = 0; i < 8; ++i) v[i] = S->h[i];
|
||||
v[ 8] = S->s[0] ^ 0x243F6A88;
|
||||
v[ 9] = S->s[1] ^ 0x85A308D3;
|
||||
v[10] = S->s[2] ^ 0x13198A2E;
|
||||
v[11] = S->s[3] ^ 0x03707344;
|
||||
v[12] = 0xA4093822;
|
||||
v[13] = 0x299F31D0;
|
||||
v[14] = 0x082EFA98;
|
||||
v[15] = 0xEC4E6C89;
|
||||
|
||||
if (S->nullt == 0) {
|
||||
v[12] ^= S->t[0];
|
||||
v[13] ^= S->t[0];
|
||||
v[14] ^= S->t[1];
|
||||
v[15] ^= S->t[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < 14; ++i) {
|
||||
G(0, 4, 8, 12, 0);
|
||||
G(1, 5, 9, 13, 2);
|
||||
G(2, 6, 10, 14, 4);
|
||||
G(3, 7, 11, 15, 6);
|
||||
G(3, 4, 9, 14, 14);
|
||||
G(2, 7, 8, 13, 12);
|
||||
G(0, 5, 10, 15, 8);
|
||||
G(1, 6, 11, 12, 10);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i];
|
||||
for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4];
|
||||
}
|
||||
|
||||
void blake256_init(state *S) {
|
||||
S->h[0] = 0x6A09E667;
|
||||
S->h[1] = 0xBB67AE85;
|
||||
S->h[2] = 0x3C6EF372;
|
||||
S->h[3] = 0xA54FF53A;
|
||||
S->h[4] = 0x510E527F;
|
||||
S->h[5] = 0x9B05688C;
|
||||
S->h[6] = 0x1F83D9AB;
|
||||
S->h[7] = 0x5BE0CD19;
|
||||
S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
|
||||
S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
|
||||
}
|
||||
|
||||
void blake224_init(state *S) {
|
||||
S->h[0] = 0xC1059ED8;
|
||||
S->h[1] = 0x367CD507;
|
||||
S->h[2] = 0x3070DD17;
|
||||
S->h[3] = 0xF70E5939;
|
||||
S->h[4] = 0xFFC00B31;
|
||||
S->h[5] = 0x68581511;
|
||||
S->h[6] = 0x64F98FA7;
|
||||
S->h[7] = 0xBEFA4FA4;
|
||||
S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
|
||||
S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void blake256_update(state *S, const uint8_t *data, uint64_t datalen) {
|
||||
int left = S->buflen >> 3;
|
||||
int fill = 64 - left;
|
||||
|
||||
if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) {
|
||||
memcpy((void *) (S->buf + left), (void *) data, fill);
|
||||
S->t[0] += 512;
|
||||
if (S->t[0] == 0) S->t[1]++;
|
||||
blake256_compress(S, S->buf);
|
||||
data += fill;
|
||||
datalen -= (fill << 3);
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (datalen >= 512) {
|
||||
S->t[0] += 512;
|
||||
if (S->t[0] == 0) S->t[1]++;
|
||||
blake256_compress(S, data);
|
||||
data += 64;
|
||||
datalen -= 512;
|
||||
}
|
||||
|
||||
if (datalen > 0) {
|
||||
memcpy((void *) (S->buf + left), (void *) data, datalen >> 3);
|
||||
S->buflen = (left << 3) + datalen;
|
||||
} else {
|
||||
S->buflen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void blake224_update(state *S, const uint8_t *data, uint64_t datalen) {
|
||||
blake256_update(S, data, datalen);
|
||||
}
|
||||
|
||||
void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) {
|
||||
uint8_t msglen[8];
|
||||
uint32_t lo = S->t[0] + S->buflen, hi = S->t[1];
|
||||
if (lo < (unsigned) S->buflen) hi++;
|
||||
U32TO8(msglen + 0, hi);
|
||||
U32TO8(msglen + 4, lo);
|
||||
|
||||
if (S->buflen == 440) { /* one padding byte */
|
||||
S->t[0] -= 8;
|
||||
blake256_update(S, &pa, 8);
|
||||
} else {
|
||||
if (S->buflen < 440) { /* enough space to fill the block */
|
||||
if (S->buflen == 0) S->nullt = 1;
|
||||
S->t[0] -= 440 - S->buflen;
|
||||
blake256_update(S, padding, 440 - S->buflen);
|
||||
} else { /* need 2 compressions */
|
||||
S->t[0] -= 512 - S->buflen;
|
||||
blake256_update(S, padding, 512 - S->buflen);
|
||||
S->t[0] -= 440;
|
||||
blake256_update(S, padding + 1, 440);
|
||||
S->nullt = 1;
|
||||
}
|
||||
blake256_update(S, &pb, 8);
|
||||
S->t[0] -= 8;
|
||||
}
|
||||
S->t[0] -= 64;
|
||||
blake256_update(S, msglen, 64);
|
||||
|
||||
U32TO8(digest + 0, S->h[0]);
|
||||
U32TO8(digest + 4, S->h[1]);
|
||||
U32TO8(digest + 8, S->h[2]);
|
||||
U32TO8(digest + 12, S->h[3]);
|
||||
U32TO8(digest + 16, S->h[4]);
|
||||
U32TO8(digest + 20, S->h[5]);
|
||||
U32TO8(digest + 24, S->h[6]);
|
||||
U32TO8(digest + 28, S->h[7]);
|
||||
}
|
||||
|
||||
void blake256_final(state *S, uint8_t *digest) {
|
||||
blake256_final_h(S, digest, 0x81, 0x01);
|
||||
}
|
||||
|
||||
void blake224_final(state *S, uint8_t *digest) {
|
||||
blake256_final_h(S, digest, 0x80, 0x00);
|
||||
}
|
||||
|
||||
// inlen = number of bytes
|
||||
void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
|
||||
state S;
|
||||
blake256_init(&S);
|
||||
blake256_update(&S, in, inlen * 8);
|
||||
blake256_final(&S, out);
|
||||
}
|
||||
|
||||
void blake(const uint8_t *input, uint64_t len, uint8_t *output)
|
||||
{
|
||||
blake256_hash(output, input, len);
|
||||
}
|
||||
|
||||
// inlen = number of bytes
|
||||
void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
|
||||
state S;
|
||||
blake224_init(&S);
|
||||
blake224_update(&S, in, inlen * 8);
|
||||
blake224_final(&S, out);
|
||||
}
|
||||
|
||||
// keylen = number of bytes
|
||||
void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
const uint8_t *key = _key;
|
||||
uint8_t keyhash[32];
|
||||
uint8_t pad[64];
|
||||
uint64_t i;
|
||||
|
||||
if (keylen > 64) {
|
||||
blake256_hash(keyhash, key, keylen);
|
||||
key = keyhash;
|
||||
keylen = 32;
|
||||
}
|
||||
|
||||
blake256_init(&S->inner);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake256_update(&S->inner, pad, 512);
|
||||
|
||||
blake256_init(&S->outer);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake256_update(&S->outer, pad, 512);
|
||||
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes
|
||||
void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
const uint8_t *key = _key;
|
||||
uint8_t keyhash[32];
|
||||
uint8_t pad[64];
|
||||
uint64_t i;
|
||||
|
||||
if (keylen > 64) {
|
||||
blake256_hash(keyhash, key, keylen);
|
||||
key = keyhash;
|
||||
keylen = 28;
|
||||
}
|
||||
|
||||
blake224_init(&S->inner);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake224_update(&S->inner, pad, 512);
|
||||
|
||||
blake224_init(&S->outer);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < keylen; ++i) {
|
||||
pad[i] ^= key[i];
|
||||
}
|
||||
blake224_update(&S->outer, pad, 512);
|
||||
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
|
||||
// update the inner state
|
||||
blake256_update(&S->inner, data, datalen);
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
|
||||
// update the inner state
|
||||
blake224_update(&S->inner, data, datalen);
|
||||
}
|
||||
|
||||
void hmac_blake256_final(hmac_state *S, uint8_t *digest) {
|
||||
uint8_t ihash[32];
|
||||
blake256_final(&S->inner, ihash);
|
||||
blake256_update(&S->outer, ihash, 256);
|
||||
blake256_final(&S->outer, digest);
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
|
||||
uint8_t ihash[32];
|
||||
blake224_final(&S->inner, ihash);
|
||||
blake224_update(&S->outer, ihash, 224);
|
||||
blake224_final(&S->outer, digest);
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes; inlen = number of bytes
|
||||
void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
|
||||
hmac_state S;
|
||||
hmac_blake256_init(&S, key, keylen);
|
||||
hmac_blake256_update(&S, in, inlen * 8);
|
||||
hmac_blake256_final(&S, out);
|
||||
}
|
||||
|
||||
// keylen = number of bytes; inlen = number of bytes
|
||||
void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
|
||||
hmac_state S;
|
||||
hmac_blake224_init(&S, key, keylen);
|
||||
hmac_blake224_update(&S, in, inlen * 8);
|
||||
hmac_blake224_final(&S, out);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BLAKE_H
|
||||
#define BLAKE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void blake(const uint8_t *input, uint64_t len, uint8_t *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,505 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "keccak.h"
|
||||
#include "blake.h"
|
||||
#include "skein.h"
|
||||
#include "jh.h"
|
||||
#include "groestl.h"
|
||||
#include "oaes_lib.h"
|
||||
|
||||
#define MEMORY (1 << 21) /* 2 MiB */
|
||||
#define ITER (1 << 20)
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_KEY_SIZE 32 /*16*/
|
||||
#define INIT_SIZE_BLK 8
|
||||
#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) // 128
|
||||
|
||||
#define VARIANT1_1(p) \
|
||||
do if (variant > 0) \
|
||||
{ \
|
||||
const uint8_t tmp = ((const uint8_t*)(p))[11]; \
|
||||
static const uint32_t table = 0x75310; \
|
||||
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \
|
||||
((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \
|
||||
} while(0)
|
||||
|
||||
#define VARIANT1_2(p) \
|
||||
do if (variant > 0) \
|
||||
{ \
|
||||
((uint64_t*)p)[1] ^= tweak1_2; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define VARIANT1_INIT() \
|
||||
const uint64_t tweak1_2 = variant > 0 ? *(const uint64_t*)(((const uint8_t*)input)+35) ^ ctx->state.hs.w[24] : 0
|
||||
|
||||
// zeile hier drüber möglicherweise ein & vor das ctx
|
||||
|
||||
void do_blake_hash(const void* input, size_t len, char* output) {
|
||||
blake(input, len, (unsigned char *)output);
|
||||
}
|
||||
|
||||
void do_groestl_hash(const void* input, size_t len, char* output) {
|
||||
groestl(input, len * 8, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void do_jh_hash(const void* input, size_t len, char* output) {
|
||||
jh(32 * 8, input, 8 * len, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void do_skein_hash(const void* input, size_t len, char* output) {
|
||||
skein(8 * 32, input, 8 * len, (uint8_t*)output);
|
||||
}
|
||||
|
||||
void (* const extra_hashes[4])(const void *, size_t, char *) = {
|
||||
do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
|
||||
|
||||
void xor_blocks_dst(const uint8_t * a, const uint8_t * b, uint8_t * dst) {
|
||||
((uint64_t*) dst)[0] = ((uint64_t*) a)[0] ^ ((uint64_t*) b)[0];
|
||||
((uint64_t*) dst)[1] = ((uint64_t*) a)[1] ^ ((uint64_t*) b)[1];
|
||||
}
|
||||
|
||||
#define likely(x) (x)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union hash_state {
|
||||
uint8_t b[200];
|
||||
uint64_t w[25];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union cn_slow_hash_state {
|
||||
union hash_state hs;
|
||||
struct {
|
||||
uint8_t k[64];
|
||||
uint8_t init[INIT_SIZE_BYTE];
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct cryptonight_ctx {
|
||||
uint8_t long_state[MEMORY] __attribute((aligned(16)));
|
||||
union cn_slow_hash_state state;
|
||||
uint8_t text[INIT_SIZE_BYTE] __attribute((aligned(16)));
|
||||
uint8_t a[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
uint8_t b[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
uint8_t c[AES_BLOCK_SIZE] __attribute__((aligned(16)));
|
||||
oaes_ctx* aes_ctx;
|
||||
};
|
||||
|
||||
const uint32_t TestTable1[256] __attribute((aligned(16))) ={
|
||||
0xA56363C6,0x847C7CF8,0x997777EE,0x8D7B7BF6,0x0DF2F2FF,0xBD6B6BD6,0xB16F6FDE,0x54C5C591,
|
||||
0x50303060,0x03010102,0xA96767CE,0x7D2B2B56,0x19FEFEE7,0x62D7D7B5,0xE6ABAB4D,0x9A7676EC,
|
||||
0x45CACA8F,0x9D82821F,0x40C9C989,0x877D7DFA,0x15FAFAEF,0xEB5959B2,0xC947478E,0x0BF0F0FB,
|
||||
0xECADAD41,0x67D4D4B3,0xFDA2A25F,0xEAAFAF45,0xBF9C9C23,0xF7A4A453,0x967272E4,0x5BC0C09B,
|
||||
0xC2B7B775,0x1CFDFDE1,0xAE93933D,0x6A26264C,0x5A36366C,0x413F3F7E,0x02F7F7F5,0x4FCCCC83,
|
||||
0x5C343468,0xF4A5A551,0x34E5E5D1,0x08F1F1F9,0x937171E2,0x73D8D8AB,0x53313162,0x3F15152A,
|
||||
0x0C040408,0x52C7C795,0x65232346,0x5EC3C39D,0x28181830,0xA1969637,0x0F05050A,0xB59A9A2F,
|
||||
0x0907070E,0x36121224,0x9B80801B,0x3DE2E2DF,0x26EBEBCD,0x6927274E,0xCDB2B27F,0x9F7575EA,
|
||||
0x1B090912,0x9E83831D,0x742C2C58,0x2E1A1A34,0x2D1B1B36,0xB26E6EDC,0xEE5A5AB4,0xFBA0A05B,
|
||||
0xF65252A4,0x4D3B3B76,0x61D6D6B7,0xCEB3B37D,0x7B292952,0x3EE3E3DD,0x712F2F5E,0x97848413,
|
||||
0xF55353A6,0x68D1D1B9,0x00000000,0x2CEDEDC1,0x60202040,0x1FFCFCE3,0xC8B1B179,0xED5B5BB6,
|
||||
0xBE6A6AD4,0x46CBCB8D,0xD9BEBE67,0x4B393972,0xDE4A4A94,0xD44C4C98,0xE85858B0,0x4ACFCF85,
|
||||
0x6BD0D0BB,0x2AEFEFC5,0xE5AAAA4F,0x16FBFBED,0xC5434386,0xD74D4D9A,0x55333366,0x94858511,
|
||||
0xCF45458A,0x10F9F9E9,0x06020204,0x817F7FFE,0xF05050A0,0x443C3C78,0xBA9F9F25,0xE3A8A84B,
|
||||
0xF35151A2,0xFEA3A35D,0xC0404080,0x8A8F8F05,0xAD92923F,0xBC9D9D21,0x48383870,0x04F5F5F1,
|
||||
0xDFBCBC63,0xC1B6B677,0x75DADAAF,0x63212142,0x30101020,0x1AFFFFE5,0x0EF3F3FD,0x6DD2D2BF,
|
||||
0x4CCDCD81,0x140C0C18,0x35131326,0x2FECECC3,0xE15F5FBE,0xA2979735,0xCC444488,0x3917172E,
|
||||
0x57C4C493,0xF2A7A755,0x827E7EFC,0x473D3D7A,0xAC6464C8,0xE75D5DBA,0x2B191932,0x957373E6,
|
||||
0xA06060C0,0x98818119,0xD14F4F9E,0x7FDCDCA3,0x66222244,0x7E2A2A54,0xAB90903B,0x8388880B,
|
||||
0xCA46468C,0x29EEEEC7,0xD3B8B86B,0x3C141428,0x79DEDEA7,0xE25E5EBC,0x1D0B0B16,0x76DBDBAD,
|
||||
0x3BE0E0DB,0x56323264,0x4E3A3A74,0x1E0A0A14,0xDB494992,0x0A06060C,0x6C242448,0xE45C5CB8,
|
||||
0x5DC2C29F,0x6ED3D3BD,0xEFACAC43,0xA66262C4,0xA8919139,0xA4959531,0x37E4E4D3,0x8B7979F2,
|
||||
0x32E7E7D5,0x43C8C88B,0x5937376E,0xB76D6DDA,0x8C8D8D01,0x64D5D5B1,0xD24E4E9C,0xE0A9A949,
|
||||
0xB46C6CD8,0xFA5656AC,0x07F4F4F3,0x25EAEACF,0xAF6565CA,0x8E7A7AF4,0xE9AEAE47,0x18080810,
|
||||
0xD5BABA6F,0x887878F0,0x6F25254A,0x722E2E5C,0x241C1C38,0xF1A6A657,0xC7B4B473,0x51C6C697,
|
||||
0x23E8E8CB,0x7CDDDDA1,0x9C7474E8,0x211F1F3E,0xDD4B4B96,0xDCBDBD61,0x868B8B0D,0x858A8A0F,
|
||||
0x907070E0,0x423E3E7C,0xC4B5B571,0xAA6666CC,0xD8484890,0x05030306,0x01F6F6F7,0x120E0E1C,
|
||||
0xA36161C2,0x5F35356A,0xF95757AE,0xD0B9B969,0x91868617,0x58C1C199,0x271D1D3A,0xB99E9E27,
|
||||
0x38E1E1D9,0x13F8F8EB,0xB398982B,0x33111122,0xBB6969D2,0x70D9D9A9,0x898E8E07,0xA7949433,
|
||||
0xB69B9B2D,0x221E1E3C,0x92878715,0x20E9E9C9,0x49CECE87,0xFF5555AA,0x78282850,0x7ADFDFA5,
|
||||
0x8F8C8C03,0xF8A1A159,0x80898909,0x170D0D1A,0xDABFBF65,0x31E6E6D7,0xC6424284,0xB86868D0,
|
||||
0xC3414182,0xB0999929,0x772D2D5A,0x110F0F1E,0xCBB0B07B,0xFC5454A8,0xD6BBBB6D,0x3A16162C
|
||||
};
|
||||
|
||||
const uint32_t TestTable2[256] __attribute((aligned(16))) ={
|
||||
0x6363C6A5,0x7C7CF884,0x7777EE99,0x7B7BF68D,0xF2F2FF0D,0x6B6BD6BD,0x6F6FDEB1,0xC5C59154,
|
||||
0x30306050,0x01010203,0x6767CEA9,0x2B2B567D,0xFEFEE719,0xD7D7B562,0xABAB4DE6,0x7676EC9A,
|
||||
0xCACA8F45,0x82821F9D,0xC9C98940,0x7D7DFA87,0xFAFAEF15,0x5959B2EB,0x47478EC9,0xF0F0FB0B,
|
||||
0xADAD41EC,0xD4D4B367,0xA2A25FFD,0xAFAF45EA,0x9C9C23BF,0xA4A453F7,0x7272E496,0xC0C09B5B,
|
||||
0xB7B775C2,0xFDFDE11C,0x93933DAE,0x26264C6A,0x36366C5A,0x3F3F7E41,0xF7F7F502,0xCCCC834F,
|
||||
0x3434685C,0xA5A551F4,0xE5E5D134,0xF1F1F908,0x7171E293,0xD8D8AB73,0x31316253,0x15152A3F,
|
||||
0x0404080C,0xC7C79552,0x23234665,0xC3C39D5E,0x18183028,0x969637A1,0x05050A0F,0x9A9A2FB5,
|
||||
0x07070E09,0x12122436,0x80801B9B,0xE2E2DF3D,0xEBEBCD26,0x27274E69,0xB2B27FCD,0x7575EA9F,
|
||||
0x0909121B,0x83831D9E,0x2C2C5874,0x1A1A342E,0x1B1B362D,0x6E6EDCB2,0x5A5AB4EE,0xA0A05BFB,
|
||||
0x5252A4F6,0x3B3B764D,0xD6D6B761,0xB3B37DCE,0x2929527B,0xE3E3DD3E,0x2F2F5E71,0x84841397,
|
||||
0x5353A6F5,0xD1D1B968,0x00000000,0xEDEDC12C,0x20204060,0xFCFCE31F,0xB1B179C8,0x5B5BB6ED,
|
||||
0x6A6AD4BE,0xCBCB8D46,0xBEBE67D9,0x3939724B,0x4A4A94DE,0x4C4C98D4,0x5858B0E8,0xCFCF854A,
|
||||
0xD0D0BB6B,0xEFEFC52A,0xAAAA4FE5,0xFBFBED16,0x434386C5,0x4D4D9AD7,0x33336655,0x85851194,
|
||||
0x45458ACF,0xF9F9E910,0x02020406,0x7F7FFE81,0x5050A0F0,0x3C3C7844,0x9F9F25BA,0xA8A84BE3,
|
||||
0x5151A2F3,0xA3A35DFE,0x404080C0,0x8F8F058A,0x92923FAD,0x9D9D21BC,0x38387048,0xF5F5F104,
|
||||
0xBCBC63DF,0xB6B677C1,0xDADAAF75,0x21214263,0x10102030,0xFFFFE51A,0xF3F3FD0E,0xD2D2BF6D,
|
||||
0xCDCD814C,0x0C0C1814,0x13132635,0xECECC32F,0x5F5FBEE1,0x979735A2,0x444488CC,0x17172E39,
|
||||
0xC4C49357,0xA7A755F2,0x7E7EFC82,0x3D3D7A47,0x6464C8AC,0x5D5DBAE7,0x1919322B,0x7373E695,
|
||||
0x6060C0A0,0x81811998,0x4F4F9ED1,0xDCDCA37F,0x22224466,0x2A2A547E,0x90903BAB,0x88880B83,
|
||||
0x46468CCA,0xEEEEC729,0xB8B86BD3,0x1414283C,0xDEDEA779,0x5E5EBCE2,0x0B0B161D,0xDBDBAD76,
|
||||
0xE0E0DB3B,0x32326456,0x3A3A744E,0x0A0A141E,0x494992DB,0x06060C0A,0x2424486C,0x5C5CB8E4,
|
||||
0xC2C29F5D,0xD3D3BD6E,0xACAC43EF,0x6262C4A6,0x919139A8,0x959531A4,0xE4E4D337,0x7979F28B,
|
||||
0xE7E7D532,0xC8C88B43,0x37376E59,0x6D6DDAB7,0x8D8D018C,0xD5D5B164,0x4E4E9CD2,0xA9A949E0,
|
||||
0x6C6CD8B4,0x5656ACFA,0xF4F4F307,0xEAEACF25,0x6565CAAF,0x7A7AF48E,0xAEAE47E9,0x08081018,
|
||||
0xBABA6FD5,0x7878F088,0x25254A6F,0x2E2E5C72,0x1C1C3824,0xA6A657F1,0xB4B473C7,0xC6C69751,
|
||||
0xE8E8CB23,0xDDDDA17C,0x7474E89C,0x1F1F3E21,0x4B4B96DD,0xBDBD61DC,0x8B8B0D86,0x8A8A0F85,
|
||||
0x7070E090,0x3E3E7C42,0xB5B571C4,0x6666CCAA,0x484890D8,0x03030605,0xF6F6F701,0x0E0E1C12,
|
||||
0x6161C2A3,0x35356A5F,0x5757AEF9,0xB9B969D0,0x86861791,0xC1C19958,0x1D1D3A27,0x9E9E27B9,
|
||||
0xE1E1D938,0xF8F8EB13,0x98982BB3,0x11112233,0x6969D2BB,0xD9D9A970,0x8E8E0789,0x949433A7,
|
||||
0x9B9B2DB6,0x1E1E3C22,0x87871592,0xE9E9C920,0xCECE8749,0x5555AAFF,0x28285078,0xDFDFA57A,
|
||||
0x8C8C038F,0xA1A159F8,0x89890980,0x0D0D1A17,0xBFBF65DA,0xE6E6D731,0x424284C6,0x6868D0B8,
|
||||
0x414182C3,0x999929B0,0x2D2D5A77,0x0F0F1E11,0xB0B07BCB,0x5454A8FC,0xBBBB6DD6,0x16162C3A
|
||||
};
|
||||
|
||||
const uint32_t TestTable3[256] __attribute((aligned(16))) ={
|
||||
0x63C6A563,0x7CF8847C,0x77EE9977,0x7BF68D7B,0xF2FF0DF2,0x6BD6BD6B,0x6FDEB16F,0xC59154C5,
|
||||
0x30605030,0x01020301,0x67CEA967,0x2B567D2B,0xFEE719FE,0xD7B562D7,0xAB4DE6AB,0x76EC9A76,
|
||||
0xCA8F45CA,0x821F9D82,0xC98940C9,0x7DFA877D,0xFAEF15FA,0x59B2EB59,0x478EC947,0xF0FB0BF0,
|
||||
0xAD41ECAD,0xD4B367D4,0xA25FFDA2,0xAF45EAAF,0x9C23BF9C,0xA453F7A4,0x72E49672,0xC09B5BC0,
|
||||
0xB775C2B7,0xFDE11CFD,0x933DAE93,0x264C6A26,0x366C5A36,0x3F7E413F,0xF7F502F7,0xCC834FCC,
|
||||
0x34685C34,0xA551F4A5,0xE5D134E5,0xF1F908F1,0x71E29371,0xD8AB73D8,0x31625331,0x152A3F15,
|
||||
0x04080C04,0xC79552C7,0x23466523,0xC39D5EC3,0x18302818,0x9637A196,0x050A0F05,0x9A2FB59A,
|
||||
0x070E0907,0x12243612,0x801B9B80,0xE2DF3DE2,0xEBCD26EB,0x274E6927,0xB27FCDB2,0x75EA9F75,
|
||||
0x09121B09,0x831D9E83,0x2C58742C,0x1A342E1A,0x1B362D1B,0x6EDCB26E,0x5AB4EE5A,0xA05BFBA0,
|
||||
0x52A4F652,0x3B764D3B,0xD6B761D6,0xB37DCEB3,0x29527B29,0xE3DD3EE3,0x2F5E712F,0x84139784,
|
||||
0x53A6F553,0xD1B968D1,0x00000000,0xEDC12CED,0x20406020,0xFCE31FFC,0xB179C8B1,0x5BB6ED5B,
|
||||
0x6AD4BE6A,0xCB8D46CB,0xBE67D9BE,0x39724B39,0x4A94DE4A,0x4C98D44C,0x58B0E858,0xCF854ACF,
|
||||
0xD0BB6BD0,0xEFC52AEF,0xAA4FE5AA,0xFBED16FB,0x4386C543,0x4D9AD74D,0x33665533,0x85119485,
|
||||
0x458ACF45,0xF9E910F9,0x02040602,0x7FFE817F,0x50A0F050,0x3C78443C,0x9F25BA9F,0xA84BE3A8,
|
||||
0x51A2F351,0xA35DFEA3,0x4080C040,0x8F058A8F,0x923FAD92,0x9D21BC9D,0x38704838,0xF5F104F5,
|
||||
0xBC63DFBC,0xB677C1B6,0xDAAF75DA,0x21426321,0x10203010,0xFFE51AFF,0xF3FD0EF3,0xD2BF6DD2,
|
||||
0xCD814CCD,0x0C18140C,0x13263513,0xECC32FEC,0x5FBEE15F,0x9735A297,0x4488CC44,0x172E3917,
|
||||
0xC49357C4,0xA755F2A7,0x7EFC827E,0x3D7A473D,0x64C8AC64,0x5DBAE75D,0x19322B19,0x73E69573,
|
||||
0x60C0A060,0x81199881,0x4F9ED14F,0xDCA37FDC,0x22446622,0x2A547E2A,0x903BAB90,0x880B8388,
|
||||
0x468CCA46,0xEEC729EE,0xB86BD3B8,0x14283C14,0xDEA779DE,0x5EBCE25E,0x0B161D0B,0xDBAD76DB,
|
||||
0xE0DB3BE0,0x32645632,0x3A744E3A,0x0A141E0A,0x4992DB49,0x060C0A06,0x24486C24,0x5CB8E45C,
|
||||
0xC29F5DC2,0xD3BD6ED3,0xAC43EFAC,0x62C4A662,0x9139A891,0x9531A495,0xE4D337E4,0x79F28B79,
|
||||
0xE7D532E7,0xC88B43C8,0x376E5937,0x6DDAB76D,0x8D018C8D,0xD5B164D5,0x4E9CD24E,0xA949E0A9,
|
||||
0x6CD8B46C,0x56ACFA56,0xF4F307F4,0xEACF25EA,0x65CAAF65,0x7AF48E7A,0xAE47E9AE,0x08101808,
|
||||
0xBA6FD5BA,0x78F08878,0x254A6F25,0x2E5C722E,0x1C38241C,0xA657F1A6,0xB473C7B4,0xC69751C6,
|
||||
0xE8CB23E8,0xDDA17CDD,0x74E89C74,0x1F3E211F,0x4B96DD4B,0xBD61DCBD,0x8B0D868B,0x8A0F858A,
|
||||
0x70E09070,0x3E7C423E,0xB571C4B5,0x66CCAA66,0x4890D848,0x03060503,0xF6F701F6,0x0E1C120E,
|
||||
0x61C2A361,0x356A5F35,0x57AEF957,0xB969D0B9,0x86179186,0xC19958C1,0x1D3A271D,0x9E27B99E,
|
||||
0xE1D938E1,0xF8EB13F8,0x982BB398,0x11223311,0x69D2BB69,0xD9A970D9,0x8E07898E,0x9433A794,
|
||||
0x9B2DB69B,0x1E3C221E,0x87159287,0xE9C920E9,0xCE8749CE,0x55AAFF55,0x28507828,0xDFA57ADF,
|
||||
0x8C038F8C,0xA159F8A1,0x89098089,0x0D1A170D,0xBF65DABF,0xE6D731E6,0x4284C642,0x68D0B868,
|
||||
0x4182C341,0x9929B099,0x2D5A772D,0x0F1E110F,0xB07BCBB0,0x54A8FC54,0xBB6DD6BB,0x162C3A16
|
||||
};
|
||||
|
||||
const uint32_t TestTable4[256] __attribute((aligned(16))) ={
|
||||
0xC6A56363,0xF8847C7C,0xEE997777,0xF68D7B7B,0xFF0DF2F2,0xD6BD6B6B,0xDEB16F6F,0x9154C5C5,
|
||||
0x60503030,0x02030101,0xCEA96767,0x567D2B2B,0xE719FEFE,0xB562D7D7,0x4DE6ABAB,0xEC9A7676,
|
||||
0x8F45CACA,0x1F9D8282,0x8940C9C9,0xFA877D7D,0xEF15FAFA,0xB2EB5959,0x8EC94747,0xFB0BF0F0,
|
||||
0x41ECADAD,0xB367D4D4,0x5FFDA2A2,0x45EAAFAF,0x23BF9C9C,0x53F7A4A4,0xE4967272,0x9B5BC0C0,
|
||||
0x75C2B7B7,0xE11CFDFD,0x3DAE9393,0x4C6A2626,0x6C5A3636,0x7E413F3F,0xF502F7F7,0x834FCCCC,
|
||||
0x685C3434,0x51F4A5A5,0xD134E5E5,0xF908F1F1,0xE2937171,0xAB73D8D8,0x62533131,0x2A3F1515,
|
||||
0x080C0404,0x9552C7C7,0x46652323,0x9D5EC3C3,0x30281818,0x37A19696,0x0A0F0505,0x2FB59A9A,
|
||||
0x0E090707,0x24361212,0x1B9B8080,0xDF3DE2E2,0xCD26EBEB,0x4E692727,0x7FCDB2B2,0xEA9F7575,
|
||||
0x121B0909,0x1D9E8383,0x58742C2C,0x342E1A1A,0x362D1B1B,0xDCB26E6E,0xB4EE5A5A,0x5BFBA0A0,
|
||||
0xA4F65252,0x764D3B3B,0xB761D6D6,0x7DCEB3B3,0x527B2929,0xDD3EE3E3,0x5E712F2F,0x13978484,
|
||||
0xA6F55353,0xB968D1D1,0x00000000,0xC12CEDED,0x40602020,0xE31FFCFC,0x79C8B1B1,0xB6ED5B5B,
|
||||
0xD4BE6A6A,0x8D46CBCB,0x67D9BEBE,0x724B3939,0x94DE4A4A,0x98D44C4C,0xB0E85858,0x854ACFCF,
|
||||
0xBB6BD0D0,0xC52AEFEF,0x4FE5AAAA,0xED16FBFB,0x86C54343,0x9AD74D4D,0x66553333,0x11948585,
|
||||
0x8ACF4545,0xE910F9F9,0x04060202,0xFE817F7F,0xA0F05050,0x78443C3C,0x25BA9F9F,0x4BE3A8A8,
|
||||
0xA2F35151,0x5DFEA3A3,0x80C04040,0x058A8F8F,0x3FAD9292,0x21BC9D9D,0x70483838,0xF104F5F5,
|
||||
0x63DFBCBC,0x77C1B6B6,0xAF75DADA,0x42632121,0x20301010,0xE51AFFFF,0xFD0EF3F3,0xBF6DD2D2,
|
||||
0x814CCDCD,0x18140C0C,0x26351313,0xC32FECEC,0xBEE15F5F,0x35A29797,0x88CC4444,0x2E391717,
|
||||
0x9357C4C4,0x55F2A7A7,0xFC827E7E,0x7A473D3D,0xC8AC6464,0xBAE75D5D,0x322B1919,0xE6957373,
|
||||
0xC0A06060,0x19988181,0x9ED14F4F,0xA37FDCDC,0x44662222,0x547E2A2A,0x3BAB9090,0x0B838888,
|
||||
0x8CCA4646,0xC729EEEE,0x6BD3B8B8,0x283C1414,0xA779DEDE,0xBCE25E5E,0x161D0B0B,0xAD76DBDB,
|
||||
0xDB3BE0E0,0x64563232,0x744E3A3A,0x141E0A0A,0x92DB4949,0x0C0A0606,0x486C2424,0xB8E45C5C,
|
||||
0x9F5DC2C2,0xBD6ED3D3,0x43EFACAC,0xC4A66262,0x39A89191,0x31A49595,0xD337E4E4,0xF28B7979,
|
||||
0xD532E7E7,0x8B43C8C8,0x6E593737,0xDAB76D6D,0x018C8D8D,0xB164D5D5,0x9CD24E4E,0x49E0A9A9,
|
||||
0xD8B46C6C,0xACFA5656,0xF307F4F4,0xCF25EAEA,0xCAAF6565,0xF48E7A7A,0x47E9AEAE,0x10180808,
|
||||
0x6FD5BABA,0xF0887878,0x4A6F2525,0x5C722E2E,0x38241C1C,0x57F1A6A6,0x73C7B4B4,0x9751C6C6,
|
||||
0xCB23E8E8,0xA17CDDDD,0xE89C7474,0x3E211F1F,0x96DD4B4B,0x61DCBDBD,0x0D868B8B,0x0F858A8A,
|
||||
0xE0907070,0x7C423E3E,0x71C4B5B5,0xCCAA6666,0x90D84848,0x06050303,0xF701F6F6,0x1C120E0E,
|
||||
0xC2A36161,0x6A5F3535,0xAEF95757,0x69D0B9B9,0x17918686,0x9958C1C1,0x3A271D1D,0x27B99E9E,
|
||||
0xD938E1E1,0xEB13F8F8,0x2BB39898,0x22331111,0xD2BB6969,0xA970D9D9,0x07898E8E,0x33A79494,
|
||||
0x2DB69B9B,0x3C221E1E,0x15928787,0xC920E9E9,0x8749CECE,0xAAFF5555,0x50782828,0xA57ADFDF,
|
||||
0x038F8C8C,0x59F8A1A1,0x09808989,0x1A170D0D,0x65DABFBF,0xD731E6E6,0x84C64242,0xD0B86868,
|
||||
0x82C34141,0x29B09999,0x5A772D2D,0x1E110F0F,0x7BCBB0B0,0xA8FC5454,0x6DD6BBBB,0x2C3A1616
|
||||
};
|
||||
/*
|
||||
inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi)
|
||||
{
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||
uint64_t a = multiplier >> 32;
|
||||
uint64_t b = multiplier & 0xFFFFFFFF;
|
||||
uint64_t c = multiplicand >> 32;
|
||||
uint64_t d = multiplicand & 0xFFFFFFFF;
|
||||
|
||||
//uint64_t ac = a * c;
|
||||
uint64_t ad = a * d;
|
||||
//uint64_t bc = b * c;
|
||||
uint64_t bd = b * d;
|
||||
|
||||
uint64_t adbc = ad + (b * c);
|
||||
uint64_t adbc_carry = adbc < ad ? 1 : 0;
|
||||
|
||||
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||
uint64_t product_lo = bd + (adbc << 32);
|
||||
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
|
||||
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||
//assert(ac <= *product_hi);
|
||||
|
||||
return product_lo;
|
||||
}*/
|
||||
|
||||
// void m64to128(uint64_t *a, uint64_t *b, uint64_t *r)
|
||||
// {
|
||||
// uint64_t lo, hi;
|
||||
// __asm__("mul %0, %1, %2\n\t" : "=r"(lo) : "r"(a[0]), "r"(b[0]) );
|
||||
// __asm__("umulh %0, %1, %2\n\t" : "=r"(hi) : "r"(a[0]), "r"(b[0]) );
|
||||
// r[0] = hi;
|
||||
// r[1] = lo;
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
|
||||
void mult64to128(uint64_t op1, uint64_t op2, uint64_t *hi, uint64_t *lo)
|
||||
{
|
||||
uint64_t u1 = (op1 & 0xffffffff);
|
||||
uint64_t v1 = (op2 & 0xffffffff);
|
||||
uint64_t t = (u1 * v1);
|
||||
uint64_t w3 = (t & 0xffffffff);
|
||||
uint64_t k = (t >> 32);
|
||||
|
||||
op1 >>= 32;
|
||||
t = (op1 * v1) + k;
|
||||
k = (t & 0xffffffff);
|
||||
v1 = (t >> 32);
|
||||
|
||||
op2 >>= 32;
|
||||
t = (u1 * op2) + k;
|
||||
k = (t >> 32);
|
||||
|
||||
*hi = (op1 * op2) + v1 + k;
|
||||
*lo = (t << 32) + w3;
|
||||
}
|
||||
|
||||
|
||||
void mul_sum_xor_dst(const uint8_t *a, uint8_t *c, uint8_t *dst)
|
||||
{
|
||||
|
||||
uint64_t hi = ((uint64_t *)a)[0];
|
||||
uint64_t lo = ((uint64_t *)dst)[0];
|
||||
|
||||
//mult64to128(((uint64_t *)a)[0], ((uint64_t *)dst)[0],&hi,&lo);
|
||||
|
||||
uint64_t u1 = (hi & 0xffffffff);
|
||||
uint64_t v1 = (lo & 0xffffffff);
|
||||
uint64_t t = (u1 * v1);
|
||||
uint64_t w3 = (t & 0xffffffff);
|
||||
uint64_t k = (t >> 32);
|
||||
|
||||
hi >>= 32;
|
||||
t = (hi * v1) + k;
|
||||
k = (t & 0xffffffff);
|
||||
v1 = (t >> 32);
|
||||
|
||||
lo >>= 32;
|
||||
t = (u1 * lo) + k;
|
||||
k = (t >> 32);
|
||||
|
||||
hi = (hi * lo) + v1 + k;
|
||||
lo = (t << 32) + w3;
|
||||
|
||||
lo += ((uint64_t *)c)[1];
|
||||
hi += ((uint64_t *)c)[0];
|
||||
|
||||
((uint64_t *)c)[0] = ((uint64_t*) dst)[0] ^ hi;
|
||||
((uint64_t *)c)[1] = ((uint64_t*) dst)[1] ^ lo;
|
||||
((uint64_t *)dst)[0] = hi;
|
||||
((uint64_t *)dst)[1] = lo;
|
||||
}
|
||||
|
||||
void xor_blocks(uint8_t * a, const uint8_t * b) {
|
||||
((uint64_t*) a)[0] ^= ((uint64_t*) b)[0];
|
||||
((uint64_t*) a)[1] ^= ((uint64_t*) b)[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SubAndShiftAndMixAddRound(uint32_t * out, uint8_t *temp, uint32_t * AesEncKey)
|
||||
{
|
||||
//uint8_t *state = (uint8_t *)&temp[0];
|
||||
|
||||
out[0] = TestTable1[temp[0]] ^ TestTable2[temp[5]] ^ TestTable3[temp[10]] ^ TestTable4[temp[15]] ^ AesEncKey[0];
|
||||
out[1] = TestTable4[temp[3]] ^ TestTable1[temp[4]] ^ TestTable2[temp[9]] ^ TestTable3[temp[14]] ^ AesEncKey[1];
|
||||
out[2] = TestTable3[temp[2]] ^ TestTable4[temp[7]] ^ TestTable1[temp[8]] ^ TestTable2[temp[13]] ^ AesEncKey[2];
|
||||
out[3] = TestTable2[temp[1]] ^ TestTable3[temp[6]] ^ TestTable4[temp[11]] ^ TestTable1[temp[12]] ^ AesEncKey[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SubAndShiftAndMixAddRoundInPlace(uint32_t * temp, uint32_t * AesEncKey)
|
||||
{
|
||||
uint8_t *state = (uint8_t *)&temp[0];
|
||||
|
||||
uint8_t saved[6];
|
||||
|
||||
saved[0] = state[3];
|
||||
saved[1] = state[2];
|
||||
saved[2] = state[7];
|
||||
saved[3] = state[1];
|
||||
saved[4] = state[6];
|
||||
saved[5] = state[11];
|
||||
|
||||
|
||||
temp[0]= TestTable1[state[0]] ^ TestTable2[state[5]] ^ TestTable3[state[10]] ^ TestTable4[state[15]] ^ AesEncKey[0];
|
||||
temp[1]= TestTable4[saved[0]] ^ TestTable1[state[4]] ^ TestTable2[state[9]] ^ TestTable3[state[14]] ^ AesEncKey[1];
|
||||
temp[2]= TestTable3[saved[1]] ^ TestTable4[saved[2]] ^ TestTable1[state[8]] ^ TestTable2[state[13]] ^ AesEncKey[2];
|
||||
temp[3]= TestTable2[saved[3]] ^ TestTable3[saved[4]] ^ TestTable4[saved[5]] ^ TestTable1[state[12]] ^ AesEncKey[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cryptonight_hash_ctx(void * output, const void * input, struct cryptonight_ctx * ctx) {
|
||||
ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
|
||||
size_t i, j;
|
||||
//hash_process(&ctx->state.hs, (const uint8_t*) input, 76);
|
||||
keccak((const uint8_t *)input, 76, ctx->state.hs.b, 200);
|
||||
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
|
||||
|
||||
|
||||
int variant = ((const uint8_t*)input)[0] >= 7 ? ((const uint8_t*)input)[0] - 6 : 0;
|
||||
//int variant = 1;
|
||||
|
||||
VARIANT1_INIT();
|
||||
|
||||
oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);
|
||||
|
||||
for(i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
|
||||
{
|
||||
for(j = 0; j < 10; j++)
|
||||
{
|
||||
|
||||
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
|
||||
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
|
||||
|
||||
}
|
||||
memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
((uint64_t *)(ctx->a))[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i+4];
|
||||
((uint64_t *)(ctx->b))[i] = ((uint64_t *)ctx->state.k)[i+2] ^ ((uint64_t *)ctx->state.k)[i+6];
|
||||
}
|
||||
|
||||
//xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a);
|
||||
//xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b);
|
||||
|
||||
for (i = 0; likely(i < ITER / 4); ++i) {
|
||||
|
||||
|
||||
// ueberall, woe uint64 & ... steht, sollte prinzipiell auch uint32 möglich sein.
|
||||
// auch aeon checken.
|
||||
|
||||
// Dependency chain: address -> read value ------+
|
||||
// written value <-+ hard function (AES or MUL) <+
|
||||
// next address <-+
|
||||
//
|
||||
// Iteration 1
|
||||
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
|
||||
|
||||
//SubAndShiftAndMixAddRound((uint32_t *)ctx->c, (uint32_t *)&ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
|
||||
VARIANT1_1(&ctx->long_state[j]);
|
||||
|
||||
// Iteration 2
|
||||
mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[((uint32_t *)(ctx->c))[0] & 0x1FFFF0]);
|
||||
|
||||
VARIANT1_2(&ctx->long_state[(((uint32_t *)(ctx->c))[0] & 0x1FFFF0)]);
|
||||
|
||||
// Iteration 3
|
||||
|
||||
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
|
||||
|
||||
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
//SubAndShiftAndMixAddRound((uint32_t *)ctx->b, (uint32_t *)&ctx->long_state[j], (uint32_t *)ctx->a);
|
||||
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
|
||||
|
||||
VARIANT1_1(&ctx->long_state[j]);
|
||||
|
||||
// Iteration 4
|
||||
mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[((uint32_t *)(ctx->b))[0] & 0x1FFFF0]);
|
||||
|
||||
VARIANT1_2(&ctx->long_state[(((uint32_t *)(ctx->b))[0] & 0x1FFFF0)]);
|
||||
}
|
||||
|
||||
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
|
||||
|
||||
oaes_free((OAES_CTX **) &ctx->aes_ctx);
|
||||
ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
|
||||
|
||||
oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
|
||||
|
||||
for(i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
|
||||
{
|
||||
|
||||
xor_blocks(&ctx->text[0x00], &ctx->long_state[i + 0x00]);
|
||||
xor_blocks(&ctx->text[0x10], &ctx->long_state[i + 0x10]);
|
||||
xor_blocks(&ctx->text[0x20], &ctx->long_state[i + 0x20]);
|
||||
xor_blocks(&ctx->text[0x30], &ctx->long_state[i + 0x30]);
|
||||
xor_blocks(&ctx->text[0x40], &ctx->long_state[i + 0x40]);
|
||||
xor_blocks(&ctx->text[0x50], &ctx->long_state[i + 0x50]);
|
||||
xor_blocks(&ctx->text[0x60], &ctx->long_state[i + 0x60]);
|
||||
xor_blocks(&ctx->text[0x70], &ctx->long_state[i + 0x70]);
|
||||
|
||||
|
||||
|
||||
for(j = 0; j < 10; j++)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
|
||||
|
||||
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
|
||||
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
|
||||
//hash_permutation(&ctx->state.hs);
|
||||
keccakf((uint64_t *)ctx->state.hs.b, 24);
|
||||
/*memcpy(hash, &state, 32);*/
|
||||
extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
|
||||
oaes_free((OAES_CTX **) &ctx->aes_ctx);
|
||||
}
|
||||
|
||||
void cryptonight(void* output, const void* input, size_t len) {
|
||||
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx));
|
||||
cryptonight_hash_ctx(output, input, ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef CRYPTONIGHT_H
|
||||
#define CRYPTONIGHT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cryptonight(void *output, const void *input, size_t len);
|
||||
struct cryptonight_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,393 @@
|
|||
/* hash.c April 2012
|
||||
* Groestl ANSI C code optimised for 32-bit machines
|
||||
* Author: Thomas Krinninger
|
||||
*
|
||||
* This work is based on the implementation of
|
||||
* Soeren S. Thomsen and Krystian Matusiewicz
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "groestl_tables.h"
|
||||
|
||||
typedef unsigned char BitSequence;
|
||||
typedef unsigned long long DataLength;
|
||||
typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;
|
||||
|
||||
/* some sizes (number of bytes) */
|
||||
#define ROWS 8
|
||||
#define LENGTHFIELDLEN ROWS
|
||||
#define COLS512 8
|
||||
|
||||
#define SIZE512 (ROWS*COLS512)
|
||||
|
||||
#define ROUNDS512 10
|
||||
#define HASH_BIT_LEN 256
|
||||
|
||||
#define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff))
|
||||
|
||||
#define li_32(h) 0x##h##u
|
||||
#define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n)))
|
||||
#define u32BIG(a) \
|
||||
((ROTL32(a,8) & li_32(00FF00FF)) | \
|
||||
(ROTL32(a,24) & li_32(FF00FF00)))
|
||||
|
||||
/* NIST API begin */
|
||||
typedef struct {
|
||||
uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */
|
||||
uint32_t block_counter1,
|
||||
block_counter2; /* message block counter(s) */
|
||||
BitSequence buffer[SIZE512]; /* data buffer */
|
||||
int buf_ptr; /* data buffer pointer */
|
||||
int bits_in_last_byte; /* no. of message bits in last byte of
|
||||
data buffer */
|
||||
} groestlHashState;
|
||||
|
||||
#define P_TYPE 0
|
||||
#define Q_TYPE 1
|
||||
|
||||
const uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}};
|
||||
|
||||
const uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6};
|
||||
|
||||
|
||||
#define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \
|
||||
v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \
|
||||
v1 = temp_var;}
|
||||
|
||||
|
||||
#define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t) \
|
||||
tu = T[2*(uint32_t)x[4*c0+0]]; \
|
||||
tl = T[2*(uint32_t)x[4*c0+0]+1]; \
|
||||
tv1 = T[2*(uint32_t)x[4*c1+1]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c1+1]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c2+2]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c2+2]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c3+3]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c3+3]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \
|
||||
tu ^= tv1; \
|
||||
tl ^= tv2; \
|
||||
tl ^= T[2*(uint32_t)x[4*c4+0]]; \
|
||||
tu ^= T[2*(uint32_t)x[4*c4+0]+1]; \
|
||||
tv1 = T[2*(uint32_t)x[4*c5+1]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c5+1]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c6+2]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c6+2]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
tv1 = T[2*(uint32_t)x[4*c7+3]]; \
|
||||
tv2 = T[2*(uint32_t)x[4*c7+3]+1]; \
|
||||
ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \
|
||||
tl ^= tv1; \
|
||||
tu ^= tv2; \
|
||||
y[i] = tu; \
|
||||
y[i+1] = tl;
|
||||
|
||||
|
||||
/* compute one round of P (short variants) */
|
||||
static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) {
|
||||
uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
|
||||
uint32_t* x32 = (uint32_t*)x;
|
||||
x32[ 0] ^= 0x00000000^r;
|
||||
x32[ 2] ^= 0x00000010^r;
|
||||
x32[ 4] ^= 0x00000020^r;
|
||||
x32[ 6] ^= 0x00000030^r;
|
||||
x32[ 8] ^= 0x00000040^r;
|
||||
x32[10] ^= 0x00000050^r;
|
||||
x32[12] ^= 0x00000060^r;
|
||||
x32[14] ^= 0x00000070^r;
|
||||
COLUMN(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
}
|
||||
|
||||
/* compute one round of Q (short variants) */
|
||||
static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {
|
||||
uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
|
||||
uint32_t* x32 = (uint32_t*)x;
|
||||
x32[ 0] = ~x32[ 0];
|
||||
x32[ 1] ^= 0xffffffff^r;
|
||||
x32[ 2] = ~x32[ 2];
|
||||
x32[ 3] ^= 0xefffffff^r;
|
||||
x32[ 4] = ~x32[ 4];
|
||||
x32[ 5] ^= 0xdfffffff^r;
|
||||
x32[ 6] = ~x32[ 6];
|
||||
x32[ 7] ^= 0xcfffffff^r;
|
||||
x32[ 8] = ~x32[ 8];
|
||||
x32[ 9] ^= 0xbfffffff^r;
|
||||
x32[10] = ~x32[10];
|
||||
x32[11] ^= 0xafffffff^r;
|
||||
x32[12] = ~x32[12];
|
||||
x32[13] ^= 0x9fffffff^r;
|
||||
x32[14] = ~x32[14];
|
||||
x32[15] ^= 0x8fffffff^r;
|
||||
COLUMN(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
COLUMN(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
|
||||
}
|
||||
|
||||
/* compute compression function (short variants) */
|
||||
static void F512(uint32_t *h, const uint32_t *m) {
|
||||
int i;
|
||||
uint32_t Ptmp[2*COLS512];
|
||||
uint32_t Qtmp[2*COLS512];
|
||||
uint32_t y[2*COLS512];
|
||||
uint32_t z[2*COLS512];
|
||||
|
||||
for (i = 0; i < 2*COLS512; i++) {
|
||||
z[i] = m[i];
|
||||
Ptmp[i] = h[i]^m[i];
|
||||
}
|
||||
|
||||
/* compute Q(m) */
|
||||
RND512Q((uint8_t*)z, y, 0x00000000);
|
||||
RND512Q((uint8_t*)y, z, 0x01000000);
|
||||
RND512Q((uint8_t*)z, y, 0x02000000);
|
||||
RND512Q((uint8_t*)y, z, 0x03000000);
|
||||
RND512Q((uint8_t*)z, y, 0x04000000);
|
||||
RND512Q((uint8_t*)y, z, 0x05000000);
|
||||
RND512Q((uint8_t*)z, y, 0x06000000);
|
||||
RND512Q((uint8_t*)y, z, 0x07000000);
|
||||
RND512Q((uint8_t*)z, y, 0x08000000);
|
||||
RND512Q((uint8_t*)y, Qtmp, 0x09000000);
|
||||
|
||||
/* compute P(h+m) */
|
||||
RND512P((uint8_t*)Ptmp, y, 0x00000000);
|
||||
RND512P((uint8_t*)y, z, 0x00000001);
|
||||
RND512P((uint8_t*)z, y, 0x00000002);
|
||||
RND512P((uint8_t*)y, z, 0x00000003);
|
||||
RND512P((uint8_t*)z, y, 0x00000004);
|
||||
RND512P((uint8_t*)y, z, 0x00000005);
|
||||
RND512P((uint8_t*)z, y, 0x00000006);
|
||||
RND512P((uint8_t*)y, z, 0x00000007);
|
||||
RND512P((uint8_t*)z, y, 0x00000008);
|
||||
RND512P((uint8_t*)y, Ptmp, 0x00000009);
|
||||
|
||||
/* compute P(h+m) + Q(m) + h */
|
||||
for (i = 0; i < 2*COLS512; i++) {
|
||||
h[i] ^= Ptmp[i]^Qtmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* digest up to msglen bytes of input (full blocks only) */
|
||||
static void Transform(groestlHashState *ctx,
|
||||
const uint8_t *input,
|
||||
int msglen) {
|
||||
|
||||
/* digest message, one block at a time */
|
||||
for (; msglen >= SIZE512;
|
||||
msglen -= SIZE512, input += SIZE512) {
|
||||
F512(ctx->chaining,(uint32_t*)input);
|
||||
|
||||
/* increment block counter */
|
||||
ctx->block_counter1++;
|
||||
if (ctx->block_counter1 == 0) ctx->block_counter2++;
|
||||
}
|
||||
}
|
||||
|
||||
/* given state h, do h <- P(h)+h */
|
||||
static void OutputTransformation(groestlHashState *ctx) {
|
||||
int j;
|
||||
uint32_t temp[2*COLS512];
|
||||
uint32_t y[2*COLS512];
|
||||
uint32_t z[2*COLS512];
|
||||
|
||||
|
||||
|
||||
for (j = 0; j < 2*COLS512; j++) {
|
||||
temp[j] = ctx->chaining[j];
|
||||
}
|
||||
RND512P((uint8_t*)temp, y, 0x00000000);
|
||||
RND512P((uint8_t*)y, z, 0x00000001);
|
||||
RND512P((uint8_t*)z, y, 0x00000002);
|
||||
RND512P((uint8_t*)y, z, 0x00000003);
|
||||
RND512P((uint8_t*)z, y, 0x00000004);
|
||||
RND512P((uint8_t*)y, z, 0x00000005);
|
||||
RND512P((uint8_t*)z, y, 0x00000006);
|
||||
RND512P((uint8_t*)y, z, 0x00000007);
|
||||
RND512P((uint8_t*)z, y, 0x00000008);
|
||||
RND512P((uint8_t*)y, temp, 0x00000009);
|
||||
for (j = 0; j < 2*COLS512; j++) {
|
||||
ctx->chaining[j] ^= temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* initialise context */
|
||||
static void Init(groestlHashState* ctx) {
|
||||
int i = 0;
|
||||
/* allocate memory for state and data buffer */
|
||||
|
||||
for(;i<(SIZE512/sizeof(uint32_t));i++)
|
||||
{
|
||||
ctx->chaining[i] = 0;
|
||||
}
|
||||
|
||||
/* set initial value */
|
||||
ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN);
|
||||
|
||||
/* set other variables */
|
||||
ctx->buf_ptr = 0;
|
||||
ctx->block_counter1 = 0;
|
||||
ctx->block_counter2 = 0;
|
||||
ctx->bits_in_last_byte = 0;
|
||||
}
|
||||
|
||||
/* update state with databitlen bits of input */
|
||||
static void Update(groestlHashState* ctx,
|
||||
const BitSequence* input,
|
||||
DataLength databitlen) {
|
||||
int index = 0;
|
||||
int msglen = (int)(databitlen/8);
|
||||
int rem = (int)(databitlen%8);
|
||||
|
||||
/* if the buffer contains data that has not yet been digested, first
|
||||
add data to buffer until full */
|
||||
if (ctx->buf_ptr) {
|
||||
while (ctx->buf_ptr < SIZE512 && index < msglen) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
|
||||
}
|
||||
if (ctx->buf_ptr < SIZE512) {
|
||||
/* buffer still not full, return */
|
||||
if (rem) {
|
||||
ctx->bits_in_last_byte = rem;
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* digest buffer */
|
||||
ctx->buf_ptr = 0;
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
}
|
||||
|
||||
/* digest bulk of message */
|
||||
Transform(ctx, input+index, msglen-index);
|
||||
index += ((msglen-index)/SIZE512)*SIZE512;
|
||||
|
||||
/* store remaining data in buffer */
|
||||
while (index < msglen) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
|
||||
}
|
||||
|
||||
/* if non-integral number of bytes have been supplied, store
|
||||
remaining bits in last byte, together with information about
|
||||
number of bits */
|
||||
if (rem) {
|
||||
ctx->bits_in_last_byte = rem;
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = input[index];
|
||||
}
|
||||
}
|
||||
|
||||
#define BILB ctx->bits_in_last_byte
|
||||
|
||||
/* finalise: process remaining data (including padding), perform
|
||||
output transformation, and write hash result to 'output' */
|
||||
static void Final(groestlHashState* ctx,
|
||||
BitSequence* output) {
|
||||
int i, j = 0, hashbytelen = HASH_BIT_LEN/8;
|
||||
uint8_t *s = (BitSequence*)ctx->chaining;
|
||||
|
||||
/* pad with '1'-bit and first few '0'-bits */
|
||||
if (BILB) {
|
||||
ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<<BILB)-1)<<(8-BILB);
|
||||
ctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB);
|
||||
BILB = 0;
|
||||
}
|
||||
else ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
|
||||
|
||||
/* pad with '0'-bits */
|
||||
if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
|
||||
/* padding requires two blocks */
|
||||
while (ctx->buf_ptr < SIZE512) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = 0;
|
||||
}
|
||||
/* digest first padding block */
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
ctx->buf_ptr = 0;
|
||||
}
|
||||
while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) {
|
||||
ctx->buffer[(int)ctx->buf_ptr++] = 0;
|
||||
}
|
||||
|
||||
/* length padding */
|
||||
ctx->block_counter1++;
|
||||
if (ctx->block_counter1 == 0) ctx->block_counter2++;
|
||||
ctx->buf_ptr = SIZE512;
|
||||
|
||||
while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) {
|
||||
ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1;
|
||||
ctx->block_counter1 >>= 8;
|
||||
}
|
||||
while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
|
||||
ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2;
|
||||
ctx->block_counter2 >>= 8;
|
||||
}
|
||||
/* digest final padding block */
|
||||
Transform(ctx, ctx->buffer, SIZE512);
|
||||
/* perform output transformation */
|
||||
OutputTransformation(ctx);
|
||||
|
||||
/* store hash result in output */
|
||||
for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) {
|
||||
output[j] = s[i];
|
||||
}
|
||||
|
||||
/* zeroise relevant variables and deallocate memory */
|
||||
for (i = 0; i < COLS512; i++) {
|
||||
ctx->chaining[i] = 0;
|
||||
}
|
||||
for (i = 0; i < SIZE512; i++) {
|
||||
ctx->buffer[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* hash bit sequence */
|
||||
void groestl(const BitSequence* data,
|
||||
DataLength databitlen,
|
||||
BitSequence* hashval) {
|
||||
|
||||
groestlHashState context;
|
||||
|
||||
/* initialise */
|
||||
Init(&context);
|
||||
|
||||
|
||||
/* process message */
|
||||
Update(&context, data, databitlen);
|
||||
|
||||
/* finalise */
|
||||
Final(&context, hashval);
|
||||
}
|
||||
/*
|
||||
static int crypto_hash(unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned long long len)
|
||||
{
|
||||
groestl(in, 8*len, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef GROESTL_H
|
||||
#define GROESTL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void groestl(const unsigned char *input,
|
||||
unsigned long long len,
|
||||
unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __tables_h
|
||||
#define __tables_h
|
||||
|
||||
|
||||
const uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc
|
||||
, 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5
|
||||
, 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d
|
||||
, 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded
|
||||
, 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1
|
||||
, 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441
|
||||
, 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4
|
||||
, 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba
|
||||
, 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616
|
||||
, 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2
|
||||
, 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c
|
||||
, 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de
|
||||
, 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7
|
||||
, 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e
|
||||
, 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c
|
||||
, 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7
|
||||
, 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b
|
||||
, 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4
|
||||
, 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e
|
||||
, 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a
|
||||
, 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37
|
||||
, 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86
|
||||
, 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b
|
||||
, 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028
|
||||
, 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3
|
||||
, 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94
|
||||
, 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836
|
||||
, 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0
|
||||
, 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2
|
||||
, 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e
|
||||
, 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3
|
||||
, 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e};
|
||||
|
||||
#endif /* __tables_h */
|
|
@ -0,0 +1,146 @@
|
|||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Emscripten-Generated Code</title>
|
||||
<style>
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
textarea.emscripten { font-family: monospace; width: 80%; }
|
||||
div.emscripten { text-align: center; }
|
||||
div.emscripten_border { border: 1px solid black; }
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten { border: 0px none; background-color: black; }
|
||||
.spinner {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin: 0px auto;
|
||||
-webkit-animation: rotation .8s linear infinite;
|
||||
-moz-animation: rotation .8s linear infinite;
|
||||
-o-animation: rotation .8s linear infinite;
|
||||
animation: rotation 0.8s linear infinite;
|
||||
border-left: 10px solid rgb(0,150,240);
|
||||
border-right: 10px solid rgb(0,150,240);
|
||||
border-bottom: 10px solid rgb(0,150,240);
|
||||
border-top: 10px solid rgb(100,0,200);
|
||||
border-radius: 100%;
|
||||
background-color: rgb(200,100,250);
|
||||
}
|
||||
@-webkit-keyframes rotation {
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
@-moz-keyframes rotation {
|
||||
from {-moz-transform: rotate(0deg);}
|
||||
to {-moz-transform: rotate(360deg);}
|
||||
}
|
||||
@-o-keyframes rotation {
|
||||
from {-o-transform: rotate(0deg);}
|
||||
to {-o-transform: rotate(360deg);}
|
||||
}
|
||||
@keyframes rotation {
|
||||
from {transform: rotate(0deg);}
|
||||
to {transform: rotate(360deg);}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<hr/>
|
||||
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
|
||||
<div class="emscripten" id="status">Downloading...</div>
|
||||
<div class="emscripten">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
</div>
|
||||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="emscripten">
|
||||
<input type="checkbox" id="resize">Resize canvas
|
||||
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||
|
||||
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
|
||||
document.getElementById('resize').checked)">
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<textarea class="emscripten" id="output" rows="8"></textarea>
|
||||
<hr>
|
||||
<script type='text/javascript'>
|
||||
var statusElement = document.getElementById('status');
|
||||
var progressElement = document.getElementById('progress');
|
||||
var spinnerElement = document.getElementById('spinner');
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
var element = document.getElementById('output');
|
||||
if (element) element.value = ''; // clear browser cache
|
||||
return function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
// These replacements are necessary if you render to raw HTML
|
||||
//text = text.replace(/&/g, "&");
|
||||
//text = text.replace(/</g, "<");
|
||||
//text = text.replace(/>/g, ">");
|
||||
//text = text.replace('\n', '<br>', 'g');
|
||||
console.log(text);
|
||||
if (element) {
|
||||
element.value += text + "\n";
|
||||
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||
}
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
if (0) { // XXX disabled for safety typeof dump == 'function') {
|
||||
dump(text + '\n'); // fast, straight to the real console
|
||||
} else {
|
||||
console.error(text);
|
||||
}
|
||||
},
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) {
|
||||
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
||||
if (text === Module.setStatus.text) return;
|
||||
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||
var now = Date.now();
|
||||
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
|
||||
if (m) {
|
||||
text = m[1];
|
||||
progressElement.value = parseInt(m[2])*100;
|
||||
progressElement.max = parseInt(m[4])*100;
|
||||
progressElement.hidden = false;
|
||||
spinnerElement.hidden = false;
|
||||
} else {
|
||||
progressElement.value = null;
|
||||
progressElement.max = null;
|
||||
progressElement.hidden = true;
|
||||
if (!text) spinnerElement.hidden = true;
|
||||
}
|
||||
statusElement.innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function() {
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
spinnerElement.style.display = 'none';
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,245 @@
|
|||
// Copyright (c) 2014-2017, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline uint32_t rol32(uint32_t x, int r) {
|
||||
static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers");
|
||||
return _rotl(x, r);
|
||||
}
|
||||
|
||||
static inline uint64_t rol64(uint64_t x, int r) {
|
||||
return _rotl64(x, r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline uint32_t rol32(uint32_t x, int r) {
|
||||
return (x << (r & 31)) | (x >> (-r & 31));
|
||||
}
|
||||
|
||||
static inline uint64_t rol64(uint64_t x, int r) {
|
||||
return (x << (r & 63)) | (x >> (-r & 63));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline uint64_t hi_dword(uint64_t val) {
|
||||
return val >> 32;
|
||||
}
|
||||
|
||||
static inline uint64_t lo_dword(uint64_t val) {
|
||||
return val & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||
uint64_t a = hi_dword(multiplier);
|
||||
uint64_t b = lo_dword(multiplier);
|
||||
uint64_t c = hi_dword(multiplicand);
|
||||
uint64_t d = lo_dword(multiplicand);
|
||||
|
||||
uint64_t ac = a * c;
|
||||
uint64_t ad = a * d;
|
||||
uint64_t bc = b * c;
|
||||
uint64_t bd = b * d;
|
||||
|
||||
uint64_t adbc = ad + bc;
|
||||
uint64_t adbc_carry = adbc < ad ? 1 : 0;
|
||||
|
||||
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||
uint64_t product_lo = bd + (adbc << 32);
|
||||
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
|
||||
*product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||
assert(ac <= *product_hi);
|
||||
|
||||
return product_lo;
|
||||
}
|
||||
|
||||
static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) {
|
||||
dividend |= ((uint64_t)*remainder) << 32;
|
||||
*remainder = dividend % divisor;
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
// Long division with 2^32 base
|
||||
static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) {
|
||||
uint64_t dividend_dwords[4];
|
||||
uint32_t remainder = 0;
|
||||
|
||||
dividend_dwords[3] = hi_dword(dividend_hi);
|
||||
dividend_dwords[2] = lo_dword(dividend_hi);
|
||||
dividend_dwords[1] = hi_dword(dividend_lo);
|
||||
dividend_dwords[0] = lo_dword(dividend_lo);
|
||||
|
||||
*quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32;
|
||||
*quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder);
|
||||
*quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32;
|
||||
*quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder);
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
#define IDENT32(x) ((uint32_t) (x))
|
||||
#define IDENT64(x) ((uint64_t) (x))
|
||||
|
||||
#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \
|
||||
(((uint32_t) (x) & 0x0000ff00) << 8) | \
|
||||
(((uint32_t) (x) & 0x00ff0000) >> 8) | \
|
||||
(((uint32_t) (x) & 0xff000000) >> 24))
|
||||
#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \
|
||||
(((uint64_t) (x) & 0x000000000000ff00) << 40) | \
|
||||
(((uint64_t) (x) & 0x0000000000ff0000) << 24) | \
|
||||
(((uint64_t) (x) & 0x00000000ff000000) << 8) | \
|
||||
(((uint64_t) (x) & 0x000000ff00000000) >> 8) | \
|
||||
(((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \
|
||||
(((uint64_t) (x) & 0x00ff000000000000) >> 40) | \
|
||||
(((uint64_t) (x) & 0xff00000000000000) >> 56))
|
||||
|
||||
static inline uint32_t ident32(uint32_t x) { return x; }
|
||||
static inline uint64_t ident64(uint64_t x) { return x; }
|
||||
|
||||
#ifndef __OpenBSD__
|
||||
# if defined(__ANDROID__) && defined(__swap32) && !defined(swap32)
|
||||
# define swap32 __swap32
|
||||
# elif !defined(swap32)
|
||||
static inline uint32_t swap32(uint32_t x) {
|
||||
x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
|
||||
return (x << 16) | (x >> 16);
|
||||
}
|
||||
# endif
|
||||
# if defined(__ANDROID__) && defined(__swap64) && !defined(swap64)
|
||||
# define swap64 __swap64
|
||||
# elif !defined(swap64)
|
||||
static inline uint64_t swap64(uint64_t x) {
|
||||
x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);
|
||||
x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
|
||||
return (x << 32) | (x >> 32);
|
||||
}
|
||||
# endif
|
||||
#endif /* __OpenBSD__ */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }
|
||||
#undef UNUSED
|
||||
|
||||
static inline void mem_inplace_swap32(void *mem, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]);
|
||||
}
|
||||
}
|
||||
static inline void mem_inplace_swap64(void *mem, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void memcpy_ident32(void *dst, const void *src, size_t n) {
|
||||
memcpy(dst, src, 4 * n);
|
||||
}
|
||||
static inline void memcpy_ident64(void *dst, const void *src, size_t n) {
|
||||
memcpy(dst, src, 8 * n);
|
||||
}
|
||||
|
||||
static inline void memcpy_swap32(void *dst, const void *src, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]);
|
||||
}
|
||||
}
|
||||
static inline void memcpy_swap64(void *dst, const void *src, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
|
||||
static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled");
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define SWAP32LE IDENT32
|
||||
#define SWAP32BE SWAP32
|
||||
#define swap32le ident32
|
||||
#define swap32be swap32
|
||||
#define mem_inplace_swap32le mem_inplace_ident
|
||||
#define mem_inplace_swap32be mem_inplace_swap32
|
||||
#define memcpy_swap32le memcpy_ident32
|
||||
#define memcpy_swap32be memcpy_swap32
|
||||
#define SWAP64LE IDENT64
|
||||
#define SWAP64BE SWAP64
|
||||
#define swap64le ident64
|
||||
#define swap64be swap64
|
||||
#define mem_inplace_swap64le mem_inplace_ident
|
||||
#define mem_inplace_swap64be mem_inplace_swap64
|
||||
#define memcpy_swap64le memcpy_ident64
|
||||
#define memcpy_swap64be memcpy_swap64
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define SWAP32BE IDENT32
|
||||
#define SWAP32LE SWAP32
|
||||
#define swap32be ident32
|
||||
#define swap32le swap32
|
||||
#define mem_inplace_swap32be mem_inplace_ident
|
||||
#define mem_inplace_swap32le mem_inplace_swap32
|
||||
#define memcpy_swap32be memcpy_ident32
|
||||
#define memcpy_swap32le memcpy_swap32
|
||||
#define SWAP64BE IDENT64
|
||||
#define SWAP64LE SWAP64
|
||||
#define swap64be ident64
|
||||
#define swap64le swap64
|
||||
#define mem_inplace_swap64be mem_inplace_ident
|
||||
#define mem_inplace_swap64le mem_inplace_swap64
|
||||
#define memcpy_swap64be memcpy_ident64
|
||||
#define memcpy_swap64le memcpy_swap64
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef JH_H
|
||||
#define JH_H
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void jh(unsigned bit_len, const uint8_t input[],
|
||||
size_t input_bit_length, uint8_t output[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,377 @@
|
|||
/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C
|
||||
|
||||
--------------------------------
|
||||
Performance
|
||||
|
||||
Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)
|
||||
Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)
|
||||
Speed for long message:
|
||||
1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2
|
||||
2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3
|
||||
|
||||
--------------------------------
|
||||
Last Modified: January 16, 2011
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
typedef unsigned char BitSequence;
|
||||
typedef unsigned long long DataLength;
|
||||
typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;
|
||||
|
||||
/*define data alignment for different C compilers*/
|
||||
#if defined(__GNUC__)
|
||||
#define DATA_ALIGN16(x) x __attribute__ ((aligned(16)))
|
||||
#else
|
||||
#define DATA_ALIGN16(x) __declspec(align(16)) x
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
int hashbitlen; /*the message digest size*/
|
||||
unsigned long long databitlen; /*the message size in bits*/
|
||||
unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
|
||||
DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
|
||||
unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/
|
||||
} hashState;
|
||||
|
||||
|
||||
/*The initial hash value H(0)*/
|
||||
static const unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e};
|
||||
static const unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69};
|
||||
static const unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f};
|
||||
static const unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b};
|
||||
|
||||
/*42 round constants, each round constant is 32-byte (256-bit)*/
|
||||
static const unsigned char E8_bitslice_roundconstant[42][32]={
|
||||
{0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40},
|
||||
{0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31},
|
||||
{0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc},
|
||||
{0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3},
|
||||
{0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23},
|
||||
{0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97},
|
||||
{0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14},
|
||||
{0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4},
|
||||
{0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36},
|
||||
{0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f},
|
||||
{0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b},
|
||||
{0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62},
|
||||
{0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5},
|
||||
{0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f},
|
||||
{0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a},
|
||||
{0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf},
|
||||
{0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0},
|
||||
{0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a},
|
||||
{0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6},
|
||||
{0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67},
|
||||
{0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18},
|
||||
{0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e},
|
||||
{0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1},
|
||||
{0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83},
|
||||
{0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef},
|
||||
{0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65},
|
||||
{0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c},
|
||||
{0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71},
|
||||
{0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0},
|
||||
{0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f},
|
||||
{0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad},
|
||||
{0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6},
|
||||
{0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63},
|
||||
{0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f},
|
||||
{0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a},
|
||||
{0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5},
|
||||
{0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48},
|
||||
{0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e},
|
||||
{0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7},
|
||||
{0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde},
|
||||
{0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a},
|
||||
{0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}};
|
||||
|
||||
|
||||
static void E8(hashState *state); /*The bijective function E8, in bitslice form*/
|
||||
static void F8(hashState *state); /*The compression function F8 */
|
||||
|
||||
/*The API functions*/
|
||||
static HashReturn Init(hashState *state, int hashbitlen);
|
||||
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
|
||||
static HashReturn Final(hashState *state, BitSequence *hashval);
|
||||
static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval);
|
||||
|
||||
/*swapping bit 2i with bit 2i+1 of 64-bit x*/
|
||||
#define SWAP1(x) (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1));
|
||||
/*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/
|
||||
#define SWAP2(x) (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2));
|
||||
/*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/
|
||||
#define SWAP4(x) (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4));
|
||||
/*swapping bits 16i||16i+1||......||16i+7 with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/
|
||||
#define SWAP8(x) (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8));
|
||||
/*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/
|
||||
#define SWAP16(x) (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16));
|
||||
/*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/
|
||||
#define SWAP32(x) (x) = (((x) << 32) | ((x) >> 32));
|
||||
|
||||
/*The MDS transform*/
|
||||
#define L(m0,m1,m2,m3,m4,m5,m6,m7) \
|
||||
(m4) ^= (m1); \
|
||||
(m5) ^= (m2); \
|
||||
(m6) ^= (m0) ^ (m3); \
|
||||
(m7) ^= (m0); \
|
||||
(m0) ^= (m5); \
|
||||
(m1) ^= (m6); \
|
||||
(m2) ^= (m4) ^ (m7); \
|
||||
(m3) ^= (m4);
|
||||
|
||||
/*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/
|
||||
/*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/
|
||||
#define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1) \
|
||||
m3 = ~(m3); \
|
||||
m7 = ~(m7); \
|
||||
m0 ^= ((~(m2)) & (cc0)); \
|
||||
m4 ^= ((~(m6)) & (cc1)); \
|
||||
temp0 = (cc0) ^ ((m0) & (m1));\
|
||||
temp1 = (cc1) ^ ((m4) & (m5));\
|
||||
m0 ^= ((m2) & (m3)); \
|
||||
m4 ^= ((m6) & (m7)); \
|
||||
m3 ^= ((~(m1)) & (m2)); \
|
||||
m7 ^= ((~(m5)) & (m6)); \
|
||||
m1 ^= ((m0) & (m2)); \
|
||||
m5 ^= ((m4) & (m6)); \
|
||||
m2 ^= ((m0) & (~(m3))); \
|
||||
m6 ^= ((m4) & (~(m7))); \
|
||||
m0 ^= ((m1) | (m3)); \
|
||||
m4 ^= ((m5) | (m7)); \
|
||||
m3 ^= ((m1) & (m2)); \
|
||||
m7 ^= ((m5) & (m6)); \
|
||||
m1 ^= (temp0 & (m0)); \
|
||||
m5 ^= (temp1 & (m4)); \
|
||||
m2 ^= temp0; \
|
||||
m6 ^= temp1;
|
||||
|
||||
/*The bijective function E8, in bitslice form*/
|
||||
static void E8(hashState *state)
|
||||
{
|
||||
uint64 i,roundnumber,temp0,temp1;
|
||||
|
||||
for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) {
|
||||
/*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]);
|
||||
}
|
||||
|
||||
/*round 7*roundnumber+6: Sbox and MDS layers*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] );
|
||||
L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
|
||||
}
|
||||
/*round 7*roundnumber+6: swapping layer*/
|
||||
for (i = 1; i < 8; i = i+2) {
|
||||
temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*The compression function F8 */
|
||||
static void F8(hashState *state)
|
||||
{
|
||||
uint64 i;
|
||||
|
||||
/*xor the 512-bit message with the fist half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];
|
||||
|
||||
/*the bijective function E8 */
|
||||
E8(state);
|
||||
|
||||
/*xor the 512-bit message with the second half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
|
||||
}
|
||||
|
||||
/*before hashing a message, initialize the hash state as H0 */
|
||||
static HashReturn Init(hashState *state, int hashbitlen)
|
||||
{
|
||||
state->databitlen = 0;
|
||||
state->datasize_in_buffer = 0;
|
||||
|
||||
/*initialize the initial hash value of JH*/
|
||||
state->hashbitlen = hashbitlen;
|
||||
|
||||
/*load the intital hash value into state*/
|
||||
switch (hashbitlen)
|
||||
{
|
||||
case 224: memcpy(state->x,JH224_H0,128); break;
|
||||
case 256: memcpy(state->x,JH256_H0,128); break;
|
||||
case 384: memcpy(state->x,JH384_H0,128); break;
|
||||
case 512: memcpy(state->x,JH512_H0,128); break;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*hash each 512-bit message block, except the last partial block*/
|
||||
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
|
||||
{
|
||||
DataLength index; /*the starting address of the data to be compressed*/
|
||||
|
||||
state->databitlen += databitlen;
|
||||
index = 0;
|
||||
|
||||
/*if there is remaining data in the buffer, fill it to a full message block first*/
|
||||
/*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/
|
||||
|
||||
/*There is data in the buffer, but the incoming data is insufficient for a full block*/
|
||||
if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512) ) {
|
||||
if ( (databitlen & 7) == 0 ) {
|
||||
memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ;
|
||||
}
|
||||
else memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ;
|
||||
state->datasize_in_buffer += databitlen;
|
||||
databitlen = 0;
|
||||
}
|
||||
|
||||
/*There is data in the buffer, and the incoming data is sufficient for a full block*/
|
||||
if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512) ) {
|
||||
memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ;
|
||||
index = 64-(state->datasize_in_buffer >> 3);
|
||||
databitlen = databitlen - (512 - state->datasize_in_buffer);
|
||||
F8(state);
|
||||
state->datasize_in_buffer = 0;
|
||||
}
|
||||
|
||||
/*hash the remaining full message blocks*/
|
||||
for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) {
|
||||
memcpy(state->buffer, data+index, 64);
|
||||
F8(state);
|
||||
}
|
||||
|
||||
/*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/
|
||||
if ( databitlen > 0) {
|
||||
if ((databitlen & 7) == 0)
|
||||
memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3);
|
||||
else
|
||||
memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1);
|
||||
state->datasize_in_buffer = databitlen;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/
|
||||
static HashReturn Final(hashState *state, BitSequence *hashval)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ( (state->databitlen & 0x1ff) == 0 ) {
|
||||
/*pad the message when databitlen is multiple of 512 bits, then process the padded block*/
|
||||
memset(state->buffer, 0, 64);
|
||||
state->buffer[0] = 0x80;
|
||||
state->buffer[63] = state->databitlen & 0xff;
|
||||
state->buffer[62] = (state->databitlen >> 8) & 0xff;
|
||||
state->buffer[61] = (state->databitlen >> 16) & 0xff;
|
||||
state->buffer[60] = (state->databitlen >> 24) & 0xff;
|
||||
state->buffer[59] = (state->databitlen >> 32) & 0xff;
|
||||
state->buffer[58] = (state->databitlen >> 40) & 0xff;
|
||||
state->buffer[57] = (state->databitlen >> 48) & 0xff;
|
||||
state->buffer[56] = (state->databitlen >> 56) & 0xff;
|
||||
F8(state);
|
||||
}
|
||||
else {
|
||||
/*set the rest of the bytes in the buffer to 0*/
|
||||
if ( (state->datasize_in_buffer & 7) == 0)
|
||||
for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++) state->buffer[i] = 0;
|
||||
else
|
||||
for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++) state->buffer[i] = 0;
|
||||
|
||||
/*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/
|
||||
state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7));
|
||||
|
||||
F8(state);
|
||||
memset(state->buffer, 0, 64);
|
||||
state->buffer[63] = state->databitlen & 0xff;
|
||||
state->buffer[62] = (state->databitlen >> 8) & 0xff;
|
||||
state->buffer[61] = (state->databitlen >> 16) & 0xff;
|
||||
state->buffer[60] = (state->databitlen >> 24) & 0xff;
|
||||
state->buffer[59] = (state->databitlen >> 32) & 0xff;
|
||||
state->buffer[58] = (state->databitlen >> 40) & 0xff;
|
||||
state->buffer[57] = (state->databitlen >> 48) & 0xff;
|
||||
state->buffer[56] = (state->databitlen >> 56) & 0xff;
|
||||
F8(state);
|
||||
}
|
||||
|
||||
/*truncating the final hash value to generate the message digest*/
|
||||
switch(state->hashbitlen) {
|
||||
case 224: memcpy(hashval,(unsigned char*)state->x+64+36,28); break;
|
||||
case 256: memcpy(hashval,(unsigned char*)state->x+64+32,32); break;
|
||||
case 384: memcpy(hashval,(unsigned char*)state->x+64+16,48); break;
|
||||
case 512: memcpy(hashval,(unsigned char*)state->x+64,64); break;
|
||||
}
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
/* hash a message,
|
||||
three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen)
|
||||
one output: message digest (hashval)
|
||||
*/
|
||||
static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval)
|
||||
{
|
||||
hashState state;
|
||||
|
||||
if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) {
|
||||
Init(&state, hashbitlen);
|
||||
Update(&state, data, databitlen);
|
||||
Final(&state, hashval);
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
return(BAD_HASHLEN);
|
||||
}
|
||||
|
||||
void jh(unsigned bit_len, const uint8_t input[], size_t input_bit_length, uint8_t output[])
|
||||
{
|
||||
HashReturn ret = Hash(bit_len, input, input_bit_length, output);
|
||||
assert(ret == SUCCESS);
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
// keccak.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
// A baseline Keccak (3rd round) implementation.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
#include "keccak.h"
|
||||
|
||||
#define HASH_DATA_AREA 136
|
||||
#define KECCAK_ROUNDS 24
|
||||
|
||||
#ifndef ROTL64
|
||||
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
|
||||
#endif
|
||||
|
||||
const uint64_t keccakf_rndc[24] =
|
||||
{
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
};
|
||||
|
||||
const int keccakf_rotc[24] =
|
||||
{
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
|
||||
};
|
||||
|
||||
const int keccakf_piln[24] =
|
||||
{
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
};
|
||||
|
||||
// update the state with given number of rounds
|
||||
|
||||
void keccakf(uint64_t st[25], int rounds)
|
||||
{
|
||||
int i, j, round;
|
||||
uint64_t t, bc[5];
|
||||
|
||||
for (round = 0; round < rounds; ++round) {
|
||||
|
||||
// Theta
|
||||
bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
|
||||
bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
|
||||
bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
|
||||
bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
|
||||
bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
|
||||
st[i ] ^= t;
|
||||
st[i + 5] ^= t;
|
||||
st[i + 10] ^= t;
|
||||
st[i + 15] ^= t;
|
||||
st[i + 20] ^= t;
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
for (i = 0; i < 24; ++i) {
|
||||
bc[0] = st[keccakf_piln[i]];
|
||||
st[keccakf_piln[i]] = ROTL64(t, keccakf_rotc[i]);
|
||||
t = bc[0];
|
||||
}
|
||||
|
||||
// Chi
|
||||
for (j = 0; j < 25; j += 5) {
|
||||
bc[0] = st[j ];
|
||||
bc[1] = st[j + 1];
|
||||
bc[2] = st[j + 2];
|
||||
bc[3] = st[j + 3];
|
||||
bc[4] = st[j + 4];
|
||||
st[j ] ^= (~bc[1]) & bc[2];
|
||||
st[j + 1] ^= (~bc[2]) & bc[3];
|
||||
st[j + 2] ^= (~bc[3]) & bc[4];
|
||||
st[j + 3] ^= (~bc[4]) & bc[0];
|
||||
st[j + 4] ^= (~bc[0]) & bc[1];
|
||||
}
|
||||
|
||||
// Iota
|
||||
st[0] ^= keccakf_rndc[round];
|
||||
}
|
||||
}
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
typedef uint64_t state_t[25];
|
||||
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
||||
{
|
||||
state_t st;
|
||||
uint8_t temp[144];
|
||||
int i, rsiz, rsizw;
|
||||
|
||||
rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen;
|
||||
rsizw = rsiz / 8;
|
||||
|
||||
memset(st, 0, sizeof(st));
|
||||
|
||||
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
|
||||
for (i = 0; i < rsizw; i++)
|
||||
st[i] ^= ((uint64_t *) in)[i];
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
// last block and padding
|
||||
memcpy(temp, in, inlen);
|
||||
temp[inlen++] = 1;
|
||||
memset(temp + inlen, 0, rsiz - inlen);
|
||||
temp[rsiz - 1] |= 0x80;
|
||||
|
||||
for (i = 0; i < rsizw; i++)
|
||||
st[i] ^= ((uint64_t *) temp)[i];
|
||||
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
|
||||
memcpy(md, st, mdlen);
|
||||
}
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md)
|
||||
{
|
||||
keccak(in, inlen, md, sizeof(state_t));
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// keccak.h
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#ifndef KECCAK_H
|
||||
#define KECCAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);
|
||||
|
||||
void keccakf(uint64_t st[25], int norounds);
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
code is based on
|
||||
|
||||
https://github.com/noahdesu/xmonarch
|
||||
|
||||
which is based on the monero code.
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2014-2018, The Monero Project
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Parts of the project are originally copyright (c) 2012-2013 The Cryptonote
|
||||
developers
|
|
@ -0,0 +1,53 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "cryptonight.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "jh.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
char* tohex(unsigned char * in)
|
||||
{
|
||||
size_t size = 32;
|
||||
|
||||
char output[(size * 2) + 1];
|
||||
|
||||
char *ptr = &output[0];
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
ptr += sprintf (ptr, "%02x",in[i]);
|
||||
}
|
||||
|
||||
return &output[0];
|
||||
}
|
||||
|
||||
|
||||
char* hash_cn(char* hex, char* nonce)
|
||||
{
|
||||
unsigned char inp[76];
|
||||
|
||||
char *pos = hex;
|
||||
for( size_t i = 0; i < 76; i++) { sscanf(pos, "%2hhx", &inp[i]); pos += 2; }
|
||||
|
||||
pos = nonce;
|
||||
|
||||
for(size_t i = 39; i < 43; i++) { sscanf(pos, "%2hhx", &inp[i]); pos += 2; }
|
||||
|
||||
unsigned char hash[76];
|
||||
cryptonight(hash, inp, 76);
|
||||
|
||||
|
||||
return tohex(hash);
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_CONFIG_H
|
||||
#define _OAES_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#ifndef OAES_HAVE_ISAAC
|
||||
//#define OAES_HAVE_ISAAC 1
|
||||
//#endif // OAES_HAVE_ISAAC
|
||||
|
||||
//#ifndef OAES_DEBUG
|
||||
//#define OAES_DEBUG 0
|
||||
//#endif // OAES_DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_CONFIG_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_LIB_H
|
||||
#define _OAES_LIB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef OAES_SHARED
|
||||
# ifdef oaes_lib_EXPORTS
|
||||
# define OAES_API __declspec(dllexport)
|
||||
# else
|
||||
# define OAES_API __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define OAES_API
|
||||
# endif
|
||||
#else
|
||||
# define OAES_API
|
||||
#endif // WIN32
|
||||
|
||||
#define OAES_VERSION "0.8.1"
|
||||
#define OAES_BLOCK_SIZE 16
|
||||
|
||||
typedef void OAES_CTX;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OAES_RET_FIRST = 0,
|
||||
OAES_RET_SUCCESS = 0,
|
||||
OAES_RET_UNKNOWN,
|
||||
OAES_RET_ARG1,
|
||||
OAES_RET_ARG2,
|
||||
OAES_RET_ARG3,
|
||||
OAES_RET_ARG4,
|
||||
OAES_RET_ARG5,
|
||||
OAES_RET_NOKEY,
|
||||
OAES_RET_MEM,
|
||||
OAES_RET_BUF,
|
||||
OAES_RET_HEADER,
|
||||
OAES_RET_COUNT
|
||||
} OAES_RET;
|
||||
|
||||
/*
|
||||
* oaes_set_option() takes one of these values for its [option] parameter
|
||||
* some options accept either an optional or a required [value] parameter
|
||||
*/
|
||||
// no option
|
||||
#define OAES_OPTION_NONE 0
|
||||
// enable ECB mode, disable CBC mode
|
||||
#define OAES_OPTION_ECB 1
|
||||
// enable CBC mode, disable ECB mode
|
||||
// value is optional, may pass uint8_t iv[OAES_BLOCK_SIZE] to specify
|
||||
// the value of the initialization vector, iv
|
||||
#define OAES_OPTION_CBC 2
|
||||
|
||||
#ifdef OAES_DEBUG
|
||||
typedef int ( * oaes_step_cb ) (
|
||||
const uint8_t state[OAES_BLOCK_SIZE],
|
||||
const char * step_name,
|
||||
int step_count,
|
||||
void * user_data );
|
||||
// enable state stepping mode
|
||||
// value is required, must pass oaes_step_cb to receive the state at each step
|
||||
#define OAES_OPTION_STEP_ON 4
|
||||
// disable state stepping mode
|
||||
#define OAES_OPTION_STEP_OFF 8
|
||||
#endif // OAES_DEBUG
|
||||
|
||||
typedef uint16_t OAES_OPTION;
|
||||
|
||||
typedef struct _oaes_key
|
||||
{
|
||||
size_t data_len;
|
||||
uint8_t *data;
|
||||
size_t exp_data_len;
|
||||
uint8_t *exp_data;
|
||||
size_t num_keys;
|
||||
size_t key_base;
|
||||
} oaes_key;
|
||||
|
||||
typedef struct _oaes_ctx
|
||||
{
|
||||
#ifdef OAES_HAVE_ISAAC
|
||||
randctx * rctx;
|
||||
#endif // OAES_HAVE_ISAAC
|
||||
|
||||
#ifdef OAES_DEBUG
|
||||
oaes_step_cb step_cb;
|
||||
#endif // OAES_DEBUG
|
||||
|
||||
oaes_key * key;
|
||||
OAES_OPTION options;
|
||||
uint8_t iv[OAES_BLOCK_SIZE];
|
||||
} oaes_ctx;
|
||||
/*
|
||||
* // usage:
|
||||
*
|
||||
* OAES_CTX * ctx = oaes_alloc();
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* {
|
||||
* oaes_gen_key_xxx( ctx );
|
||||
* {
|
||||
* oaes_key_export( ctx, _buf, &_buf_len );
|
||||
* // or
|
||||
* oaes_key_export_data( ctx, _buf, &_buf_len );\
|
||||
* }
|
||||
* }
|
||||
* // or
|
||||
* {
|
||||
* oaes_key_import( ctx, _buf, _buf_len );
|
||||
* // or
|
||||
* oaes_key_import_data( ctx, _buf, _buf_len );
|
||||
* }
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_encrypt( ctx, m, m_len, c, &c_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_decrypt( ctx, c, c_len, m, &m_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_free( &ctx );
|
||||
*/
|
||||
|
||||
OAES_API OAES_CTX * oaes_alloc(void);
|
||||
|
||||
OAES_API OAES_RET oaes_free( OAES_CTX ** ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_set_option( OAES_CTX * ctx,
|
||||
OAES_OPTION option, const void * value );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_128( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_192( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_256( OAES_CTX * ctx );
|
||||
|
||||
// export key with header information
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// directly export the data from key
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export_data( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// import key with header information
|
||||
OAES_API OAES_RET oaes_key_import( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// directly import data into key
|
||||
OAES_API OAES_RET oaes_key_import_data( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// set c == NULL to get the required c_len
|
||||
OAES_API OAES_RET oaes_encrypt( OAES_CTX * ctx,
|
||||
const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len );
|
||||
|
||||
// set m == NULL to get the required m_len
|
||||
OAES_API OAES_RET oaes_decrypt( OAES_CTX * ctx,
|
||||
const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len );
|
||||
|
||||
// set buf == NULL to get the required buf_len
|
||||
OAES_API OAES_RET oaes_sprintf(
|
||||
char * buf, size_t * buf_len, const uint8_t * data, size_t data_len );
|
||||
|
||||
OAES_API OAES_RET oaes_encryption_round( const uint8_t * key, uint8_t * c );
|
||||
|
||||
OAES_API OAES_RET oaes_pseudo_encrypt_ecb( OAES_CTX * ctx, uint8_t * c );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_LIB_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
#ifndef SKEIN_H
|
||||
#define SKEIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int skein(int hashbitlen, const unsigned char *input,
|
||||
size_t input_len, unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,179 @@
|
|||
#ifndef _SKEIN_PORT_H_
|
||||
#define _SKEIN_PORT_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef RETURN_VALUES
|
||||
# define RETURN_VALUES
|
||||
# if defined( DLL_EXPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllexport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllexport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllexport__ ) void
|
||||
# define INT_RETURN __declspec( __dllexport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( DLL_IMPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllimport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllimport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllimport__ ) void
|
||||
# define INT_RETURN __declspec( __dllimport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( __WATCOMC__ )
|
||||
# define VOID_RETURN void __cdecl
|
||||
# define INT_RETURN int __cdecl
|
||||
# else
|
||||
# define VOID_RETURN void
|
||||
# define INT_RETURN int
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These defines are used to declare buffers in a way that allows
|
||||
faster operations on longer variables to be used. In all these
|
||||
defines 'size' must be a power of 2 and >= 8
|
||||
|
||||
dec_unit_type(size,x) declares a variable 'x' of length
|
||||
'size' bits
|
||||
|
||||
dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'
|
||||
bytes defined as an array of variables
|
||||
each of 'size' bits (bsize must be a
|
||||
multiple of size / 8)
|
||||
|
||||
ptr_cast(x,size) casts a pointer to a pointer to a
|
||||
varaiable of length 'size' bits
|
||||
*/
|
||||
|
||||
#define ui_type(size) uint##size##_t
|
||||
#define dec_unit_type(size,x) typedef ui_type(size) x
|
||||
#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]
|
||||
#define ptr_cast(x,size) ((ui_type(size)*)(x))
|
||||
|
||||
typedef unsigned int uint_t; /* native unsigned integer */
|
||||
typedef uint8_t u08b_t; /* 8-bit unsigned integer */
|
||||
typedef uint64_t u64b_t; /* 64-bit unsigned integer */
|
||||
|
||||
#ifndef RotL_64
|
||||
#define RotL_64(x,N) (((x) << (N)) | ((x) >> (64-(N))))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Skein is "natively" little-endian (unlike SHA-xxx), for optimal
|
||||
* performance on x86 CPUs. The Skein code requires the following
|
||||
* definitions for dealing with endianness:
|
||||
*
|
||||
* SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian
|
||||
* Skein_Put64_LSB_First
|
||||
* Skein_Get64_LSB_First
|
||||
* Skein_Swap64
|
||||
*
|
||||
* If SKEIN_NEED_SWAP is defined at compile time, it is used here
|
||||
* along with the portable versions of Put64/Get64/Swap64, which
|
||||
* are slow in general.
|
||||
*
|
||||
* Otherwise, an "auto-detect" of endianness is attempted below.
|
||||
* If the default handling doesn't work well, the user may insert
|
||||
* platform-specific code instead (e.g., for big-endian CPUs).
|
||||
*
|
||||
*/
|
||||
#ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
|
||||
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
/* special handler for IA64, which may be either endianness (?) */
|
||||
/* here we assume little-endian, but this may need to be changed */
|
||||
#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
# define PLATFORM_MUST_ALIGN (1)
|
||||
#ifndef PLATFORM_BYTE_ORDER
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_MUST_ALIGN
|
||||
# define PLATFORM_MUST_ALIGN (0)
|
||||
#endif
|
||||
|
||||
|
||||
#if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN
|
||||
/* here for big-endian CPUs */
|
||||
#define SKEIN_NEED_SWAP (1)
|
||||
#elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
|
||||
/* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */
|
||||
#define SKEIN_NEED_SWAP (0)
|
||||
#if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */
|
||||
#define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt)
|
||||
#define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt))
|
||||
#endif
|
||||
#else
|
||||
#error "Skein needs endianness setting!"
|
||||
#endif
|
||||
|
||||
#endif /* ifndef SKEIN_NEED_SWAP */
|
||||
|
||||
/*
|
||||
******************************************************************
|
||||
* Provide any definitions still needed.
|
||||
******************************************************************
|
||||
*/
|
||||
#ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */
|
||||
#if SKEIN_NEED_SWAP
|
||||
#define Skein_Swap64(w64) \
|
||||
( (( ((u64b_t)(w64)) & 0xFF) << 56) | \
|
||||
(((((u64b_t)(w64)) >> 8) & 0xFF) << 48) | \
|
||||
(((((u64b_t)(w64)) >>16) & 0xFF) << 40) | \
|
||||
(((((u64b_t)(w64)) >>24) & 0xFF) << 32) | \
|
||||
(((((u64b_t)(w64)) >>32) & 0xFF) << 24) | \
|
||||
(((((u64b_t)(w64)) >>40) & 0xFF) << 16) | \
|
||||
(((((u64b_t)(w64)) >>48) & 0xFF) << 8) | \
|
||||
(((((u64b_t)(w64)) >>56) & 0xFF) ) )
|
||||
#else
|
||||
#define Skein_Swap64(w64) (w64)
|
||||
#endif
|
||||
#endif /* ifndef Skein_Swap64 */
|
||||
|
||||
|
||||
#ifndef Skein_Put64_LSB_First
|
||||
void Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)
|
||||
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
|
||||
{ /* this version is fully portable (big-endian or little-endian), but slow */
|
||||
size_t n;
|
||||
|
||||
for (n=0;n<bCnt;n++)
|
||||
dst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));
|
||||
}
|
||||
#else
|
||||
; /* output only the function prototype */
|
||||
#endif
|
||||
#endif /* ifndef Skein_Put64_LSB_First */
|
||||
|
||||
|
||||
#ifndef Skein_Get64_LSB_First
|
||||
void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)
|
||||
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
|
||||
{ /* this version is fully portable (big-endian or little-endian), but slow */
|
||||
size_t n;
|
||||
|
||||
for (n=0;n<8*wCnt;n+=8)
|
||||
dst[n/8] = (((u64b_t) src[n ]) ) +
|
||||
(((u64b_t) src[n+1]) << 8) +
|
||||
(((u64b_t) src[n+2]) << 16) +
|
||||
(((u64b_t) src[n+3]) << 24) +
|
||||
(((u64b_t) src[n+4]) << 32) +
|
||||
(((u64b_t) src[n+5]) << 40) +
|
||||
(((u64b_t) src[n+6]) << 48) +
|
||||
(((u64b_t) src[n+7]) << 56) ;
|
||||
}
|
||||
#else
|
||||
; /* output only the function prototype */
|
||||
#endif
|
||||
#endif /* ifndef Skein_Get64_LSB_First */
|
||||
|
||||
#endif /* ifndef _SKEIN_PORT_H_ */
|
Loading…
Reference in New Issue