fb3421255ae9287539120e1bc66bf80a21c87647
[openssl.git] / crypto / ec / curve448 / arch_x86_64 / f_impl.h
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright 2014-2016 Cryptography Research, Inc.
4  *
5  * Licensed under the OpenSSL license (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  *
10  * Originally written by Mike Hamburg
11  */
12
13 #define GF_HEADROOM 60
14 #define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}}
15 #define LIMB_PLACE_VALUE(i) 56
16
17 void gf_add_RAW (gf out, const gf a, const gf b) {
18     for (unsigned int i=0; i<sizeof(*out)/sizeof(uint64xn_t); i++) {
19         ((uint64xn_t*)out)[i] = ((const uint64xn_t*)a)[i] + ((const uint64xn_t*)b)[i];
20     }
21     /*
22     unsigned int i;
23     for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
24         out->limb[i] = a->limb[i] + b->limb[i];
25     }
26     */
27 }
28
29 void gf_sub_RAW (gf out, const gf a, const gf b) {
30     for (unsigned int i=0; i<sizeof(*out)/sizeof(uint64xn_t); i++) {
31         ((uint64xn_t*)out)[i] = ((const uint64xn_t*)a)[i] - ((const uint64xn_t*)b)[i];
32     }
33     /*
34     unsigned int i;
35     for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
36         out->limb[i] = a->limb[i] - b->limb[i];
37     }
38     */
39 }
40
41 void gf_bias (gf a, int amt) {
42     uint64_t co1 = ((1ull<<56)-1)*amt, co2 = co1-amt;
43     
44 #if __AVX2__
45     uint64x4_t lo = {co1,co1,co1,co1}, hi = {co2,co1,co1,co1};
46     uint64x4_t *aa = (uint64x4_t*) a;
47     aa[0] += lo;
48     aa[1] += hi;
49 #elif __SSE2__
50     uint64x2_t lo = {co1,co1}, hi = {co2,co1};
51     uint64x2_t *aa = (uint64x2_t*) a;
52     aa[0] += lo;
53     aa[1] += lo;
54     aa[2] += hi;
55     aa[3] += lo;
56 #else
57     for (unsigned int i=0; i<sizeof(*a)/sizeof(uint64_t); i++) {
58         a->limb[i] += (i==4) ? co2 : co1;
59     }
60 #endif
61 }
62
63 void gf_weak_reduce (gf a) {
64     /* PERF: use pshufb/palignr if anyone cares about speed of this */
65     uint64_t mask = (1ull<<56) - 1;
66     uint64_t tmp = a->limb[7] >> 56;
67     a->limb[4] += tmp;
68     for (unsigned int i=7; i>0; i--) {
69         a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>56);
70     }
71     a->limb[0] = (a->limb[0] & mask) + tmp;
72 }
73