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