/
equix.c
96 lines (86 loc) · 2.54 KB
/
equix.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* Copyright (c) 2020 tevador <tevador@gmail.com> */
/* See LICENSE for licensing information */
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <equix.h>
#include <hashx.h>
#include "context.h"
#include "solver.h"
#include <hashx_endian.h>
static bool verify_order(const equix_solution* solution) {
return
tree_cmp4(&solution->idx[0], &solution->idx[4]) &
tree_cmp2(&solution->idx[0], &solution->idx[2]) &
tree_cmp2(&solution->idx[4], &solution->idx[6]) &
tree_cmp1(&solution->idx[0], &solution->idx[1]) &
tree_cmp1(&solution->idx[2], &solution->idx[3]) &
tree_cmp1(&solution->idx[4], &solution->idx[5]) &
tree_cmp1(&solution->idx[6], &solution->idx[7]);
}
static uint64_t sum_pair(hashx_ctx* hash_func, equix_idx left, equix_idx right) {
uint8_t hash_left[HASHX_SIZE];
uint8_t hash_right[HASHX_SIZE];
hashx_exec(hash_func, left, hash_left);
hashx_exec(hash_func, right, hash_right);
return load64(hash_left) + load64(hash_right);
}
static equix_result verify_internal(hashx_ctx* hash_func, const equix_solution* solution) {
uint64_t pair0 = sum_pair(hash_func, solution->idx[0], solution->idx[1]);
if (pair0 & EQUIX_STAGE1_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair1 = sum_pair(hash_func, solution->idx[2], solution->idx[3]);
if (pair1 & EQUIX_STAGE1_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair4 = pair0 + pair1;
if (pair4 & EQUIX_STAGE2_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair2 = sum_pair(hash_func, solution->idx[4], solution->idx[5]);
if (pair2 & EQUIX_STAGE1_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair3 = sum_pair(hash_func, solution->idx[6], solution->idx[7]);
if (pair3 & EQUIX_STAGE1_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair5 = pair2 + pair3;
if (pair5 & EQUIX_STAGE2_MASK) {
return EQUIX_PARTIAL_SUM;
}
uint64_t pair6 = pair4 + pair5;
if (pair6 & EQUIX_FULL_MASK) {
return EQUIX_FINAL_SUM;
}
return EQUIX_OK;
}
int equix_solve(
equix_ctx* ctx,
const void* challenge,
size_t challenge_size,
equix_solution output[EQUIX_MAX_SOLS])
{
if ((ctx->flags & EQUIX_CTX_SOLVE) == 0) {
return 0;
}
if (!hashx_make(ctx->hash_func, challenge, challenge_size)) {
return 0;
}
return equix_solver_solve(ctx->hash_func, ctx->heap, output);
}
equix_result equix_verify(
equix_ctx* ctx,
const void* challenge,
size_t challenge_size,
const equix_solution* solution)
{
if (!verify_order(solution)) {
return EQUIX_ORDER;
}
if (!hashx_make(ctx->hash_func, challenge, challenge_size)) {
return EQUIX_CHALLENGE;
}
return verify_internal(ctx->hash_func, solution);
}