-
Notifications
You must be signed in to change notification settings - Fork 8
/
key.h
64 lines (54 loc) · 2.73 KB
/
key.h
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
#pragma once
#include <string>
#define COMPARE_BLOCKS(block1, block2) if (block1 > block2) return 1; if (block1 < block2) return -1;
#define MULTIPLY_BLOCK_BY_BLOCK(i, j) result += (__uint128_t)blocks[i] * key.blocks[j]; table[i][j] = result; result >>= 64;
#define MULTIPLY_BLOCK_BY_BLOCK_LAST(i) result += (__uint128_t)blocks[i] * key.blocks[3]; table[i][3] = result; table[i][4] = result >> 64;
#define MULTIPLY_BLOCK_BY_BLOCK_REDUCED(i, j) table[i][j] = result + blocks[i] * key.blocks[j];
#define MULTIPLY_BLOCK_BY_R2(j) result += (__uint128_t)R2.blocks[0] * blocks[j]; table[j] = result; result >>= 64;
#define MULTIPLY_BLOCKS_BY_BLOCK(i) result = 0; MULTIPLY_BLOCK_BY_BLOCK(i, 0) MULTIPLY_BLOCK_BY_BLOCK(i, 1) MULTIPLY_BLOCK_BY_BLOCK(i, 2) MULTIPLY_BLOCK_BY_BLOCK_LAST(i)
#define ADD_MULTIPLIED_BLOCKS(i, sum) result >>= 64; result += (__uint128_t)sum; product.blocks[i] = result;
#define ADD_MULTIPLIED_BLOCKS_SELF(i, sum) result >>= 64; result += (__uint128_t)sum; blocks[i] = result;
#define ADD_MULTIPLIED_BLOCKS_REDUCED(i, sum) product.blocks[i] = (unsigned long long)(result >> 64) + sum;
#ifndef __aarch64__
#define ADD_BLOCKS(i) result += (__uint128_t)blocks[i] + key.blocks[i]; blocks[i] = result; result >>= 64;
#define SUBTRACT_BLOCKS(i) result = (__uint128_t)blocks[i] - key.blocks[i] - (bool)result; blocks[i] = result; result >>= 64;
#endif
#define GROUP_BITS 12
#define GROUP_SIZE (1 << GROUP_BITS)
struct Key
{
static const unsigned long long B = 0x0000000100000000;
static const Key ZERO;
static const Key ONE;
static const Key THREE;
static const Key R;
static const Key R2;
static const Key P_PRIME;
static const Key P;
static void gcd(Key a, Key b, Key& x, Key& y);
static void invertGroup(Key* keys);
unsigned long long blocks[8]{};
Key();
Key(unsigned long long block0, unsigned long long block1, unsigned long long block2, unsigned long long block3);
Key(unsigned long long block0, unsigned long long block1, unsigned long long block2, unsigned long long block3, unsigned long long block4, unsigned long long block5, unsigned long long block6, unsigned long long block7);
Key(const char* hex);
bool operator==(const Key& key) const;
void operator+=(const Key& key);
void operator-=(const Key& key);
void operator*=(const Key& key);
int compare(const Key& key);
int compareExtended(const Key& key);
bool isNotZero();
bool getBit(int index);
bool increment();
bool add(const Key& key);
bool addExtended(const Key& key);
bool subtract(const Key& key);
unsigned long long differenceParity(const Key& subtrahend);
void multiply(const Key& key, Key& product);
void multiplyLow(const Key& key, Key& product);
void multiplyByR2();
void reduce();
void divide(const Key& divisor, Key& quotient);
void invert();
};