Branch data Line data Source code
1 : : /* Arithmetic in prime fields
2 : : * Daniel Beer <dlbeer@gmail.com>, 10 Jan 2014
3 : : *
4 : : * This file is in the public domain.
5 : : */
6 : :
7 : : #ifndef FPRIME_H_
8 : : #define FPRIME_H_
9 : :
10 : : #ifndef COMPACT_DISABLE_ED25519
11 : : #include <stdint.h>
12 : : #include <string.h>
13 : :
14 : : /* Maximum size of a field element (or a prime). Field elements are
15 : : * always manipulated and stored in normalized form, with 0 <= x < p.
16 : : * You can use normalize() to convert a denormalized bitstring to normal
17 : : * form.
18 : : *
19 : : * Operations are constant with respect to the value of field elements,
20 : : * but not with respect to the modulus.
21 : : *
22 : : * The modulus is a number p, such that 2p-1 fits in FPRIME_SIZE bytes.
23 : : */
24 : : #define FPRIME_SIZE 32
25 : :
26 : : #ifdef FULL_C25519_CODE
27 : : /* Useful constants */
28 : : extern const uint8_t fprime_zero[FPRIME_SIZE];
29 : : extern const uint8_t fprime_one[FPRIME_SIZE];
30 : : #endif
31 : :
32 : : #ifdef FULL_C25519_CODE
33 : : /* Load a small constant */
34 : : void fprime_load(uint8_t *x, uint32_t c);
35 : : #endif
36 : :
37 : : /* Load a large constant */
38 : : void fprime_from_bytes(uint8_t *n,
39 : : const uint8_t *x, size_t len,
40 : : const uint8_t *modulus);
41 : :
42 : : /* Copy an element */
43 : 506 : static inline void fprime_copy(uint8_t *x, const uint8_t *a)
44 : : {
45 : 506 : memcpy(x, a, FPRIME_SIZE);
46 : 506 : }
47 : :
48 : : #ifdef FULL_C25519_CODE
49 : : /* Normalize a field element */
50 : : void fprime_normalize(uint8_t *x, const uint8_t *modulus);
51 : :
52 : : /* Compare two field points in constant time. Return one if equal, zero
53 : : * otherwise. This should be performed only on normalized values.
54 : : */
55 : : uint8_t fprime_eq(const uint8_t *x, const uint8_t *y);
56 : :
57 : : #endif
58 : : /* Conditional copy. If condition == 0, then zero is copied to dst. If
59 : : * condition == 1, then one is copied to dst. Any other value results in
60 : : * undefined behaviour.
61 : : */
62 : : void fprime_select(uint8_t *dst,
63 : : const uint8_t *zero, const uint8_t *one,
64 : : uint8_t condition);
65 : :
66 : : /* Add one value to another. The two pointers must be distinct. */
67 : : void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
68 : : #ifdef FULL_C25519_CODE
69 : : void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
70 : : #endif
71 : :
72 : : /* Multiply two values to get a third. r must be distinct from a and b */
73 : : void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
74 : : const uint8_t *modulus);
75 : :
76 : : #ifdef FULL_C25519_CODE
77 : : /* Compute multiplicative inverse. r must be distinct from a */
78 : : void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
79 : : #endif
80 : : #endif
81 : : #endif
|