1 /**
2 * @file field.h
3 * @brief Generic gf header.
4 * @copyright
5 * Copyright (c) 2014 Cryptography Research, Inc. \n
6 * Released under the MIT License. See LICENSE.txt for license information.
7 * @author Mike Hamburg
8 */
9
10 #ifndef __GF_H__
11 #define __GF_H__
12
13 #include "constant_time.h"
14 #include "f_field.h"
15 #include <string.h>
16
17 /** Square x, n times. */
cryptonite_gf_sqrn(cryptonite_gf_s * __restrict__ y,const gf x,int n)18 static CRYPTONITE_DECAF_INLINE void cryptonite_gf_sqrn (
19 cryptonite_gf_s *__restrict__ y,
20 const gf x,
21 int n
22 ) {
23 gf tmp;
24 assert(n>0);
25 if (n&1) {
26 cryptonite_gf_sqr(y,x);
27 n--;
28 } else {
29 cryptonite_gf_sqr(tmp,x);
30 cryptonite_gf_sqr(y,tmp);
31 n-=2;
32 }
33 for (; n; n-=2) {
34 cryptonite_gf_sqr(tmp,y);
35 cryptonite_gf_sqr(y,tmp);
36 }
37 }
38
39 #define cryptonite_gf_add_nr cryptonite_gf_add_RAW
40
41 /** Subtract mod p. Bias by 2 and don't reduce */
cryptonite_gf_sub_nr(gf c,const gf a,const gf b)42 static inline void cryptonite_gf_sub_nr ( gf c, const gf a, const gf b ) {
43 cryptonite_gf_sub_RAW(c,a,b);
44 cryptonite_gf_bias(c, 2);
45 if (GF_HEADROOM < 3) cryptonite_gf_weak_reduce(c);
46 }
47
48 /** Subtract mod p. Bias by amt but don't reduce. */
cryptonite_gf_subx_nr(gf c,const gf a,const gf b,int amt)49 static inline void cryptonite_gf_subx_nr ( gf c, const gf a, const gf b, int amt ) {
50 cryptonite_gf_sub_RAW(c,a,b);
51 cryptonite_gf_bias(c, amt);
52 if (GF_HEADROOM < amt+1) cryptonite_gf_weak_reduce(c);
53 }
54
55 /** Mul by signed int. Not constant-time WRT the sign of that int. */
cryptonite_gf_mulw(gf c,const gf a,int32_t w)56 static inline void cryptonite_gf_mulw(gf c, const gf a, int32_t w) {
57 if (w>0) {
58 cryptonite_gf_mulw_unsigned(c, a, w);
59 } else {
60 cryptonite_gf_mulw_unsigned(c, a, -w);
61 cryptonite_gf_sub(c,ZERO,c);
62 }
63 }
64
65 /** Constant time, x = is_z ? z : y */
cryptonite_gf_cond_sel(gf x,const gf y,const gf z,mask_t is_z)66 static inline void cryptonite_gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z) {
67 constant_time_select(x,y,z,sizeof(gf),is_z,0);
68 }
69
70 /** Constant time, if (neg) x=-x; */
cryptonite_gf_cond_neg(gf x,mask_t neg)71 static inline void cryptonite_gf_cond_neg(gf x, mask_t neg) {
72 gf y;
73 cryptonite_gf_sub(y,ZERO,x);
74 cryptonite_gf_cond_sel(x,x,y,neg);
75 }
76
77 /** Constant time, if (swap) (x,y) = (y,x); */
78 static inline void
cryptonite_gf_cond_swap(gf x,cryptonite_gf_s * __restrict__ y,mask_t swap)79 cryptonite_gf_cond_swap(gf x, cryptonite_gf_s *__restrict__ y, mask_t swap) {
80 constant_time_cond_swap(x,y,sizeof(cryptonite_gf_s),swap);
81 }
82
cryptonite_gf_mul_qnr(cryptonite_gf_s * __restrict__ out,const gf x)83 static CRYPTONITE_DECAF_INLINE void cryptonite_gf_mul_qnr(cryptonite_gf_s *__restrict__ out, const gf x) {
84 #if P_MOD_8 == 5
85 /* r = QNR * r0^2 */
86 cryptonite_gf_mul(out,x,SQRT_MINUS_ONE);
87 #elif P_MOD_8 == 3 || P_MOD_8 == 7
88 cryptonite_gf_sub(out,ZERO,x);
89 #else
90 #error "Only supporting p=3,5,7 mod 8"
91 #endif
92 }
93
cryptonite_gf_div_qnr(cryptonite_gf_s * __restrict__ out,const gf x)94 static CRYPTONITE_DECAF_INLINE void cryptonite_gf_div_qnr(cryptonite_gf_s *__restrict__ out, const gf x) {
95 #if P_MOD_8 == 5
96 /* r = QNR * r0^2 */
97 cryptonite_gf_mul(out,x,SQRT_MINUS_ONE);
98 cryptonite_gf_sub(out,ZERO,out);
99 #elif P_MOD_8 == 3 || P_MOD_8 == 7
100 cryptonite_gf_sub(out,ZERO,x);
101 #else
102 #error "Only supporting p=3,5,7 mod 8"
103 #endif
104 }
105
106
107 #endif // __GF_H__
108