field.h 2.51 KB
Newer Older
1 2
/**
 * @file field.h
3
 * @brief Generic gf header.
4 5 6 7 8
 * @copyright
 *   Copyright (c) 2014 Cryptography Research, Inc.  \n
 *   Released under the MIT License.  See LICENSE.txt for license information.
 * @author Mike Hamburg
 */
9

10 11
#ifndef __GF_H__
#define __GF_H__
12

13
#include "constant_time.h"
14
#include "f_field.h"
15
#include <string.h>
16
    
17
/** Square x, n times. */
18
static DECAF_INLINE void gf_sqrn (
19 20
    gf_s *__restrict__ y,
    const gf x,
21 22
    int n
) {
23
    gf tmp;
24 25
    assert(n>0);
    if (n&1) {
26
        gf_sqr(y,x);
27 28
        n--;
    } else {
29 30
        gf_sqr(tmp,x);
        gf_sqr(y,tmp);
31 32 33
        n-=2;
    }
    for (; n; n-=2) {
34 35
        gf_sqr(tmp,y);
        gf_sqr(y,tmp);
36 37
    }
}
38

39 40 41 42 43 44
#define gf_add_nr gf_add_RAW

/** Subtract mod p.  Bias by 2 and don't reduce  */
static inline void gf_sub_nr ( gf c, const gf a, const gf b ) {
    gf_sub_RAW(c,a,b);
    gf_bias(c, 2);
45
    if (GF_HEADROOM < 3) gf_weak_reduce(c);
46 47 48 49 50 51
}

/** Subtract mod p. Bias by amt but don't reduce.  */
static inline void gf_subx_nr ( gf c, const gf a, const gf b, int amt ) {
    gf_sub_RAW(c,a,b);
    gf_bias(c, amt);
52
    if (GF_HEADROOM < amt+1) gf_weak_reduce(c);
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
/** Mul by signed int.  Not constant-time WRT the sign of that int. */
static inline void gf_mulw(gf c, const gf a, int32_t w) {
    if (w>0) {
        gf_mulw_unsigned(c, a, w);
    } else {
        gf_mulw_unsigned(c, a, -w);
        gf_sub(c,ZERO,c);
    }
}

/** Constant time, x = is_z ? z : y */
static inline void gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z) {
    constant_time_select(x,y,z,sizeof(gf),is_z,0);
}

/** Constant time, if (neg) x=-x; */
static inline void gf_cond_neg(gf x, mask_t neg) {
    gf y;
    gf_sub(y,ZERO,x);
    gf_cond_sel(x,x,y,neg);
}

/** Constant time, if (swap) (x,y) = (y,x); */
static inline void
gf_cond_swap(gf x, gf_s *__restrict__ y, mask_t swap) {
    constant_time_cond_swap(x,y,sizeof(gf_s),swap);
}

83
static DECAF_INLINE void gf_mul_qnr(gf_s *__restrict__ out, const gf x) {
84 85 86 87 88 89 90 91 92 93
#if P_MOD_8 == 5
    /* r = QNR * r0^2 */
    gf_mul(out,x,SQRT_MINUS_ONE);
#elif P_MOD_8 == 3 || P_MOD_8 == 7
    gf_sub(out,ZERO,x);
#else
    #error "Only supporting p=3,5,7 mod 8"
#endif
}

94
static DECAF_INLINE void gf_div_qnr(gf_s *__restrict__ out, const gf x) {
95 96 97 98 99 100 101 102 103 104 105
#if P_MOD_8 == 5
    /* r = QNR * r0^2 */
    gf_mul(out,x,SQRT_MINUS_ONE);
    gf_sub(out,ZERO,out);
#elif P_MOD_8 == 3 || P_MOD_8 == 7
    gf_sub(out,ZERO,x);
#else
    #error "Only supporting p=3,5,7 mod 8"
#endif
}

106 107 108 109 110
#if P_MOD_8 == 5
#define gf_mul_i gf_mul_qnr
#define gf_div_i gf_div_qnr
#endif

111

112
#endif // __GF_H__