This repository has been archived by the owner on Jul 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathff.cpp
134 lines (112 loc) · 2.17 KB
/
ff.cpp
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "ff.hpp"
uint32_t
ff_add(const uint32_t a, const uint32_t b)
{
return a ^ b;
}
uint32_t
ff_sub(const uint32_t a, const uint32_t b)
{
return a ^ b;
}
uint32_t
ff_neg(const uint32_t a)
{
return a;
}
uint32_t
ff_mult(const uint32_t a, const uint32_t b)
{
uint64_t a_ = a;
uint32_t b_ = b;
uint32_t c = 0;
if (b > a) {
a_ = b;
b_ = a;
}
while (b_ > 0) {
if (b_ & 0b1) {
c = c ^ (uint32_t)a_;
}
b_ >>= 1;
a_ <<= 1;
if (a_ >= ORDER) {
a_ ^= IRREDUCIBLE_POLY;
}
}
return c;
}
uint32_t
ff_inv(const uint32_t a)
{
if (a == 0) {
// ** no multiplicative inverse of additive identity **
//
// may be I should have thrown an error, which I can not
// do inside a function which will be invoked from kernel
return 0;
}
uint32_t exp = ORDER - 0b10;
uint32_t res_s = a;
uint32_t res_m = 1;
while (exp > 1) {
if (exp % 2 == 0) {
res_s = ff_mult(res_s, res_s);
exp /= 2;
} else {
res_m = ff_mult(res_m, res_s);
exp -= 1;
}
}
uint32_t res = ff_mult(res_m, res_s);
return res;
}
uint32_t
ff_div(const uint32_t a, const uint32_t b)
{
if (b == 0) {
// ** no multiplicative inverse of additive identity **
//
// may be I should have thrown an error, which I can not
// do inside a function which will be invoked from kernel
return 0;
}
if (a == 0) {
return 0;
}
uint32_t b_inv = ff_inv(b);
uint32_t res = ff_mult(a, b_inv);
return res;
}
uint32_t
ff_pow(const uint32_t a, const int32_t b)
{
if (a == 0 && b < 0) {
// ** no multiplicative inverse of additive identity **
//
// may be I should have thrown an error, which I can not
// do inside a function which will be invoked from kernel
return 0;
}
if (b == 0) {
return 1;
}
uint32_t a_ = a;
uint32_t b_ = b < 0 ? sycl::abs(b) : (uint32_t)b;
if (b < 0) {
a_ = ff_inv(a);
}
uint32_t res_s = a_;
uint32_t res_m = 1;
while (b_ > 1) {
if (b_ % 2 == 0) {
res_s = ff_mult(res_s, res_s);
b_ /= 2;
} else {
res_m = ff_mult(res_m, res_s);
b_ -= 1;
}
}
uint32_t res = ff_mult(res_m, res_s);
return res;
}