Skip to content

Commit

Permalink
[GRIN] support grin cuckarooz
Browse files Browse the repository at this point in the history
  • Loading branch information
BTC.com committed Jul 13, 2020
1 parent b1d7731 commit 609ec2b
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 0 deletions.
81 changes: 81 additions & 0 deletions 3rdparty/cuckoo/cuckarooz.cpp
@@ -0,0 +1,81 @@
#include "cuckarooz.h"
#include "siphash.h"
#include <iostream>
using namespace std;

static const uint64_t EDGE_BLOCK_BITS = 6;
static const uint64_t EDGE_BLOCK_SIZE = 1 << EDGE_BLOCK_BITS;
static const uint64_t EDGE_BLOCK_MASK = EDGE_BLOCK_SIZE - 1;

// fills buffer with EDGE_BLOCK_SIZE siphash outputs for block containing edge in cuckaroo graph
// return siphash output for given edge

static uint64_t SipHashBlock(siphash_keys &keys, uint64_t edge, bool xorAll) {
uint64_t nonce0 = ~EDGE_BLOCK_MASK & edge;
uint64_t nonceI = edge & EDGE_BLOCK_MASK;

siphash_state<> shs(keys);
std::vector<uint64_t> nonceHash(EDGE_BLOCK_SIZE, 0);

for (uint64_t i = 0; i < EDGE_BLOCK_SIZE; i++) {
shs.hash24(nonce0 + i);
nonceHash[i] = shs.xor_lanes();
}

uint64_t xOr = nonceHash[nonceI];
uint64_t xOrFrom = 0;

if(xorAll || nonceI == EDGE_BLOCK_MASK) {
xOrFrom = nonceI + 1;
} else {
xOrFrom = EDGE_BLOCK_MASK;
}

for(uint64_t i = xOrFrom; i < EDGE_BLOCK_SIZE; i ++) {
xOr ^= nonceHash[i];
}
return xOr;
}


// verify that edges are ascending and form a cycle in header-generated graph
bool verify_cuckarooz(const std::vector<uint64_t> &edges, siphash_keys &keys, uint32_t edge_bits) {
// uint64_t sips[EDGE_BLOCK_SIZE];
uint64_t proof_size = edges.size();
std::vector<uint64_t> uvs(2 * proof_size);
uint64_t edge_size = static_cast<uint64_t>(1) << edge_bits;
uint64_t edge_mask = edge_size - 1;
uint64_t xoruv = 0;

for (uint64_t n = 0; n < proof_size; n++) {
if (edges[n] > edge_mask)
return false;
if (n > 0&& edges[n] <= edges[n-1])
return false;

uint64_t edge = SipHashBlock(keys, edges[n], true);
uvs[2*n ] = edge & edge_mask;
uvs[2*n+1] = (edge >> 32) & edge_mask;
xoruv ^= uvs[2*n] ^ uvs[2*n+1];
}
if (xoruv != 0)
return false;
uint64_t n = 0, i = 0, j = 0;
do {
uint64_t k = j = i;
for (;;) {
k = (k + 1) % (2 * proof_size);
if(k == i) break;

if(uvs[k] == uvs[i]) {
if(j != i) return false;
j = k;
}
}

if (j == i) return false; // no matching endpoint
i = j^1;
n++;
} while (i != 0); // must cycle back to start or we would have found branch
return n == proof_size;
}
9 changes: 9 additions & 0 deletions 3rdparty/cuckoo/cuckarooz.h
@@ -0,0 +1,9 @@
#pragma once

#include <cstdint>
#include <cstddef>
#include <vector>

class siphash_keys;

bool verify_cuckarooz(const std::vector<uint64_t> &edges, siphash_keys &keys, uint32_t edge_bits);
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -476,6 +476,7 @@ add_library(cuckoo
3rdparty/cuckoo/cuckaroo.cpp
3rdparty/cuckoo/cuckarood.cpp
3rdparty/cuckoo/cuckaroom.cpp
3rdparty/cuckoo/cuckarooz.cpp
3rdparty/cuckoo/cuckatoo.cpp
3rdparty/cuckoo/siphash.cpp)

Expand Down
3 changes: 3 additions & 0 deletions src/grin/CommonGrin.cc
Expand Up @@ -27,6 +27,7 @@
#include "cuckoo/cuckaroo.h"
#include "cuckoo/cuckarood.h"
#include "cuckoo/cuckaroom.h"
#include "cuckoo/cuckarooz.h"
#include "cuckoo/cuckatoo.h"
#include "cuckoo/siphash.h"
#include "libblake2/blake2.h"
Expand Down Expand Up @@ -71,6 +72,8 @@ bool VerifyPowGrinSecondary(
uint32_t edgeBits,
uint16_t version) {
switch (version) {
case 4:
return verify_cuckarooz(edges, keys, edgeBits);
case 3:
return verify_cuckaroom(edges, keys, edgeBits);
case 2:
Expand Down
44 changes: 44 additions & 0 deletions test/grin/TestCommonGrin.cc
Expand Up @@ -139,6 +139,50 @@ TEST(CommonGrin, VerifyPowGrinSecondary_V3_19) {
ASSERT_TRUE(VerifyPowGrinSecondary(solution, hash, 19, 3));
}

// https://github.com/tromp/grin/blob/38244e504020924b1ef60ec2808f0571d98ef03a/core/src/pow/cuckarooz.rs#L154
TEST(CommonGrin, VerifyPowGrinSecondary_V4_29) {

siphash_keys hash{
0x34bb4c75c929a2f5,
0x21df13263aa81235,
0x37d00939eae4be06,
0x473251cbf6941553,
};

std::vector<uint64_t> solution{
0x49733a, 0x1d49107, 0x253d2ca, 0x5ad5e59, 0x5b671bd, 0x5dcae1c,
0x5f9a589, 0x65e9afc, 0x6a59a45, 0x7d9c6d3, 0x7df96e4, 0x8b26174,
0xa17b430, 0xa1c8c0d, 0xa8a0327, 0xabd7402, 0xacb7c77, 0xb67524f,
0xc1c15a6, 0xc7e2c26, 0xc7f5d8d, 0xcae478a, 0xdea9229, 0xe1ab49e,
0xf57c7db, 0xfb4e8c5, 0xff314aa, 0x110ccc12, 0x143e546f, 0x17007af8,
0x17140ea2, 0x173d7c5d, 0x175cd13f, 0x178b8880, 0x1801edc5, 0x18c8f56b,
0x18c8fe6d, 0x19f1a31a, 0x1bb028d1, 0x1caaa65a, 0x1cf29bc2, 0x1dbde27d,
};

ASSERT_TRUE(VerifyPowGrinSecondary(solution, hash, 29, 4));
}
// https://github.com/tromp/grin/blob/38244e504020924b1ef60ec2808f0571d98ef03a/core/src/pow/cuckarooz.rs#L139
TEST(CommonGrin, VerifyPowGrinSecondary_V4_19) {

siphash_keys hash{
0xd129f63fba4d9a85,
0x457dcb3666c5e09c,
0x045247a2e2ee75f7,
0x1a0f2e1bcb9d93ff,
};

std::vector<uint64_t> solution{
0x33b6, 0x487b, 0x88b7, 0x10bf6, 0x15144, 0x17cb7, 0x22621,
0x2358e, 0x23775, 0x24fb3, 0x26b8a, 0x2876c, 0x2973e, 0x2f4ba,
0x30a62, 0x3a36b, 0x3ba5d, 0x3be67, 0x3ec56, 0x43141, 0x4b9c5,
0x4fa06, 0x51a5c, 0x523e5, 0x53d08, 0x57d34, 0x5c2de, 0x60bba,
0x62509, 0x64d69, 0x6803f, 0x68af4, 0x6bd52, 0x6f041, 0x6f900,
0x70051, 0x7097d, 0x735e8, 0x742c2, 0x79ae5, 0x7f64d, 0x7fd49,
};

ASSERT_TRUE(VerifyPowGrinSecondary(solution, hash, 19, 4));
}

TEST(CommonGrin, VerifyPowHashGrin_29) {
std::vector<uint64_t> solution{
59138309, 59597355, 71107354, 77008533, 82816831, 101859133,
Expand Down

0 comments on commit 609ec2b

Please sign in to comment.