Skip to content

Commit c58bd24

Browse files
committed
implement poly functions
1 parent 30e3354 commit c58bd24

File tree

5 files changed

+179
-5
lines changed

5 files changed

+179
-5
lines changed

lib/Channel.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,41 @@ typename struct {
1919
size_t size[3];
2020
} Lambda;
2121

22-
int init_channel(Channel *channel, uint64_t p, uint64_t q, uint64_t w);
22+
int init_channel(Channel *channel, uint64_t p, uint64_t q, uint64_t w) {
23+
channel->w = w;
24+
channel->p = p;
25+
channel->q = q;
2326

24-
int generate_u(const Channel *channel, const Parameters *param, Polynomial *u);
27+
if (!(pow(p, 2) < q && are_coprime(p, q)))
28+
channel->q = pow(p + 1, 2);
29+
30+
return 0;
31+
}
32+
33+
int generate_u(const Channel *channel, const Parameters *param, Polynomial *u) {
34+
uint64_t nonzeros = clamp(param->dim / 2, param->dim - 1,
35+
normal_rand(param->dim / 2, param->dim / 2));
36+
uint64_t zeroes = param->dim - nonzeros;
37+
u->coeffs[0] = 1;
38+
39+
for (int i = 0; i < param->dim - 1; ++i) {
40+
if (nonzeros > 1) {
41+
u->coeffs[i] = randrange(0, param->q);
42+
nonzeros--;
43+
}
44+
45+
if (zeroes > 0) {
46+
uint64_t samp = clamp(0, zeroes, normal_rand(zeroes / 2, zeroes / 2));
47+
uint64_t zero = randrange(0, samp);
48+
for (int j = 0; j < zero; ++j)
49+
u->coeffs[i++] = 0;
50+
zeroes -= zero;
51+
}
52+
}
53+
54+
u->coeffs[param->dim - 1] = 0;
55+
u->coeffs[param->dim - 1] = param->q - sum(u);
56+
}
2557

2658
int generate_secret(const Channel *channel, const Parameters *param,
2759
const Polynomial *u, PolyArray *secret, Lambda *lambda);

lib/Common.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,26 @@
55
extern "C" {
66
#endif
77

8+
// gcd = ax + by
89
typename struct {
10+
uint64_t gcd;
11+
int64_t a;
12+
int64_t b;
913
} Xgcd;
1014

1115
Xgcd xgcd(uint64_t a, uint64_t b);
1216
randinverse(uint64_t value);
1317
factors(uint64_t value);
1418

15-
uint64_t coprime_rand(uint64_t value);
1619
uint64_t normal_rand(double mean, double stddev);
17-
uint64_t randint(min, max);
20+
21+
uint64_t max(uint64_t a, uint64_t b) { a > b ? a : b; }
22+
23+
uint64_t min(uint64_t a, uint64_t b) { a < b ? a : b; }
24+
25+
uint64_t clamp(uint64_t min_value, uint64_t max_value, uint64_t value) {
26+
return max(min_value, min(max_value, value));
27+
}
1828

1929
#ifdef __cplusplus
2030
}

lib/Polynomial.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ uint64_t coef_sum(const Polynomial *);
2121

2222
uint64_t poly_degree(const Polynomial *);
2323

24-
int poly_fit(uint64_t mod);
24+
int poly_fit(const Polynomial *poly, uint64_t mod);
2525

2626
int poly_mul(const Polynomial *poly1, const Polynomial *poly2,
2727
Polynomial *result);

src/Common.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "Common.h"
2+
3+
uint64_t gcd(uint64_t x, uint64_t y) {
4+
while (x != y) {
5+
if (x > y)
6+
x -= y;
7+
else
8+
y -= x;
9+
}
10+
11+
return n1;
12+
}
13+
14+
Xgcd xgcd(uint64_t x, uint64_t y) {
15+
int64_t prev_a = 1;
16+
int64_t a = 0;
17+
int64_t prev_b = 0;
18+
int64_t b = 1;
19+
20+
while (y != 0) {
21+
int64_t q = (int64_t)(x / y);
22+
int64_t temp = (int64_t)(x % y);
23+
x = y;
24+
y = (uint64_t)temp;
25+
26+
temp = a;
27+
a = prev_a - (q * a);
28+
prev_a = temp;
29+
30+
temp = b;
31+
b = prev_b - (q * b);
32+
prev_b = temp;
33+
}
34+
35+
return Xgcd{x, prev_a, prev_b};
36+
}
37+
38+
int are_coprime(uint64_t x, uint64_t y) { return !(gcd(x, y) > 1); }
39+
40+
uint64_t randrange(uint64_t lower, uint64_t upper) {
41+
return (rand() % (upper - lower + 1)) + lower;
42+
}
43+
44+
randinverse(uint64_t value) {
45+
uint64_t a = randrange(2, value - 1);
46+
while (!are_coprime(a, value))
47+
a = randrange(2, value - 1);
48+
49+
Xgcd result = xgcd(a, value);
50+
51+
return a, result.a;
52+
}

src/Polynomial.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include "Polynomial.h"
2+
3+
uint64_t coef_sum(const Polynomial *poly) {
4+
if (!poly || poly->size == 0)
5+
return 0;
6+
7+
uint64_t sum = 0;
8+
for (int i = 0; i < poly->size; ++i)
9+
sum += poly->coeffs[i];
10+
11+
return sum;
12+
}
13+
14+
uint64_t poly_degree(const Polynomial *poly) {
15+
if (!poly || poly->size == 0)
16+
return 0;
17+
18+
const uint64_t *value = poly->coeffs;
19+
size_t count = poly->size;
20+
value += count - 1;
21+
22+
for (; count && !*value; count--)
23+
--value;
24+
25+
return count;
26+
}
27+
28+
int poly_fit(const Polynomial *poly, uint64_t mod) {
29+
if (!poly || poly->size == 0)
30+
return -1;
31+
32+
for (int i = 0; i < poly->size; ++i)
33+
poly->coeffs[i] = poly->coeffs[i] % mod;
34+
35+
return 0;
36+
}
37+
38+
int poly_mul(const Polynomial *poly1, const Polynomial *poly2,
39+
Polynomial *result) {
40+
// TODO: check
41+
42+
for (int i = 0; i < poly->size; ++i)
43+
result->coeffs[i] = poly1->coeffs[i] * poly2->coeffs[i];
44+
return 0;
45+
}
46+
47+
int poly_add(const Polynomial *poly1, const Polynomial *poly2,
48+
Polynomial *result) {
49+
for (int i = 0; i < poly->size; ++i)
50+
result->coeffs[i] = poly1->coeffs[i] + poly2->coeffs[i];
51+
return 0;
52+
}
53+
54+
int poly_lshift(const Polynomial *poly1, const Polynomial *poly2,
55+
Polynomial *result) {
56+
if (poly2->coeffs[0] != 1)
57+
return -1;
58+
59+
uint64_t degree1 = poly_degree(poly1);
60+
uint64_t degree2 = poly_degree(poly2);
61+
62+
if (degree1 < degree2)
63+
return -1;
64+
65+
uint64_t a_d = poly1->coeffs[0];
66+
67+
for (int i = 0; i < poly1->size; ++i) {
68+
if (i < poly2->size)
69+
result[i] = poly1->coeffs[i] - poly2->coeffs[i] * a_d;
70+
else
71+
result[i] = poly1->coeffs[i];
72+
}
73+
74+
return 0;
75+
}
76+
77+
int poly_mod(const Polynomial *poly1, const Polynomial *poly2) {
78+
while (poly_lshift(poly1, poly2, poly1) == 0) {
79+
}
80+
}

0 commit comments

Comments
 (0)