-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpoly.h
185 lines (150 loc) · 4.01 KB
/
poly.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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
* Copyright 2016 naehrwert
* Licensed under the terms of the GNU GPL, version 2
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
#ifndef _POLY_H_
#define _POLY_H_
#include <stdio.h>
#include "bn.h"
#define POLY_CMP_E 1
#define POLY_CMP_NE 0
/*! Polynomial. */
/*
* Define a polynomial P of degree n as
* P(X) = a_0 + a_1*X + a_2*X^2 + ... + a_n*X^n
* with n + 1 coefficients a_0, a_1, ..., a_n.
*/
typedef struct _poly
{
/*! The polynomial's degree. */
int degree;
/*! Coefficients (mon). */
bn_t **coeffs;
/*! Modulus. */
bn_t *N;
} poly_t;
/*!
* \brief Read polynomial from file stream.
*/
poly_t *poly_read(FILE *fp, poly_t *dst);
/*!
* \brief Write polynomial to file stream.
*/
poly_t *poly_write(FILE *fp, poly_t *p);
/*!
* \brief Print polynomial to file stream.
*/
void poly_print(FILE *fp, const s8 *pre, poly_t *p, const s8 *post);
/*!
* \brief Allocate polynomial (with zero coefficients).
*/
poly_t *poly_alloc(int degree, bn_t *N, int alloc_coeffs);
/*!
* \brief Free polynomial.
*/
void poly_free(poly_t *p, int free_coeffs);
/*!
* \brief Adjust polynomial degree.
* This will alloc/free coefficients of alloc_free_coeffs is true.
*/
poly_t *poly_adjust(poly_t *p, int degree, int alloc_free_coeffs);
/*!
* \brief Copy polynomial.
* This will zero out coefficients if the source degree is smaller and adjust is false.
* This will truncate coefficients if the destination degree is smaller and adjust is false.
* If adjust is true, then it will set the destination degree to that of the source and copy every coefficient.
*/
poly_t *poly_copy(poly_t *d, poly_t *s, int adjust);
/*!
* \brief Concatenate two polynomials (as lists of coefficients).
*/
poly_t *poly_concat(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Compare two polynomials.
*/
int poly_cmp(poly_t *p, poly_t *q);
/*!
* \brief Zero out coefficients.
*/
poly_t *poly_zero(poly_t *p);
/*!
* \brief Checks whether the polynomial is zero.
*/
int poly_is_zero(poly_t *p);
/*!
* \brief Set linear coefficient to one.
*/
poly_t *poly_one(poly_t *p);
/*!
* \brief Checks whether the polynomial is linear one.
*/
int poly_is_one(poly_t *p);
/*!
* \brief Get mathematical degree of polynomial (highest non-zero power).
*/
int poly_deg(poly_t *p);
/*!
* \brief Set coefficient.
*/
int poly_set_coeff(poly_t *p, int i, bn_t *coeff);
/*!
* \brief Free coefficient.
*/
int poly_free_coeff(poly_t *p, int i);
/*!
* \brief Fill coefficients from format.
*/
poly_t *poly_from_fmt(poly_t *p, const char *fmt, ...);
/*!
* \brief Convert coefficients to montgomery form.
*/
poly_t *poly_to_mon(poly_t *p);
/*!
* \brief Convert coefficients from montgomery form.
*/
poly_t *poly_from_mon(poly_t *p);
/*!
* \brief Evaluate polynomial at given x.
*/
bn_t *poly_eval(poly_t *p, bn_t *dst, bn_t *x);
/*!
* \brief Add two polynomials.
* Note that d must not be the same as a or b.
*/
poly_t *poly_add_fast(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Add two polynomials.
*/
poly_t *poly_add(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Subtract two polynomials.
* Note that d must not be the same as a or b.
*/
poly_t *poly_sub_fast(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Subtract two polynomials.
*/
poly_t *poly_sub(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Multiply two polynomials.
* Note that d must not be the same as a or b.
*/
poly_t *poly_mul_fast(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Multiply two polynomials.
*/
poly_t *poly_mul(poly_t *d, poly_t *a, poly_t *b);
/*!
* \brief Multiply each polynomial coefficient with a constant.
*/
poly_t *poly_mulc(poly_t *d, poly_t *a, bn_t *b);
/*!
* \brief Divide two polynomials yielding quotient and remainder.
*/
poly_t *poly_div(poly_t *q, poly_t *r, poly_t *a, poly_t *b);
/*!
* \brief Compute remainder of two polynomials.
*/
poly_t *poly_rem(poly_t *r, poly_t *a, poly_t *b);
#endif