1 /* Copyright (c) 2020, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H
16 #define OPENSSL_HEADER_CURVE25519_INTERNAL_H
17 
18 #include <ring-core/base.h>
19 
20 #include "../internal.h"
21 
22 
23 #if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE)
24 #define BORINGSSL_X25519_NEON
25 
26 // x25519_NEON is defined in asm/x25519-arm.S.
27 void x25519_NEON(uint8_t out[32], const uint8_t scalar[32],
28                      const uint8_t point[32]);
29 #endif
30 
31 #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && !defined(OPENSSL_WINDOWS) && \
32     defined(__GNUC__) && defined(__x86_64__)
33 #define BORINGSSL_FE25519_ADX
34 
35 // fiat_curve25519_adx_mul is defined in
36 // third_party/fiat/asm/fiat_curve25519_adx_mul.S
37 void __attribute__((sysv_abi))
38 fiat_curve25519_adx_mul(uint64_t out[4], const uint64_t in1[4],
39                         const uint64_t in2[4]);
40 
41 // fiat_curve25519_adx_square is defined in
42 // third_party/fiat/asm/fiat_curve25519_adx_square.S
43 void __attribute__((sysv_abi))
44 fiat_curve25519_adx_square(uint64_t out[4], const uint64_t in[4]);
45 
46 // x25519_scalar_mult_adx is defined in third_party/fiat/curve25519_64_adx.h
47 void x25519_scalar_mult_adx(uint8_t out[32], const uint8_t scalar[32],
48                             const uint8_t point[32]);
49 void x25519_ge_scalarmult_base_adx(uint8_t h[4][32], const uint8_t a[32]);
50 #endif
51 
52 #if defined(OPENSSL_64_BIT)
53 // An element t,
54 // entries t[0]...t[4], represents the integer t[0]+2^51 t[1]+2^102 t[2]+2^153
55 // t[3]+2^204 t[4].
56 // fe limbs are bounded by 1.125*2^51.
57 // fe_loose limbs are bounded by 3.375*2^51.
58 typedef uint64_t fe_limb_t;
59 #define FE_NUM_LIMBS 5
60 #else
61 // An element t,
62 // entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
63 // t[3]+2^102 t[4]+...+2^230 t[9].
64 // fe limbs are bounded by 1.125*2^26,1.125*2^25,1.125*2^26,1.125*2^25,etc.
65 // fe_loose limbs are bounded by 3.375*2^26,3.375*2^25,3.375*2^26,3.375*2^25,etc.
66 typedef uint32_t fe_limb_t;
67 #define FE_NUM_LIMBS 10
68 #endif
69 
70 // fe means field element. Here the field is \Z/(2^255-19).
71 // Multiplication and carrying produce fe from fe_loose.
72 // Keep in sync with `Elem` and `ELEM_LIMBS` in curve25519/ops.rs.
73 typedef struct fe { fe_limb_t v[FE_NUM_LIMBS]; } fe;
74 
75 // Addition and subtraction produce fe_loose from (fe, fe).
76 // Keep in sync with `Elem` and `ELEM_LIMBS` in curve25519/ops.rs.
77 typedef struct fe_loose { fe_limb_t v[FE_NUM_LIMBS]; } fe_loose;
78 
fe_limbs_copy(fe_limb_t r[],const fe_limb_t a[])79 static inline void fe_limbs_copy(fe_limb_t r[], const fe_limb_t a[]) {
80   for (size_t i = 0; i < FE_NUM_LIMBS; ++i) {
81     r[i] = a[i];
82   }
83 }
84 
85 // ge means group element.
86 //
87 // Here the group is the set of pairs (x,y) of field elements (see fe.h)
88 // satisfying -x^2 + y^2 = 1 + d x^2y^2
89 // where d = -121665/121666.
90 //
91 // Representations:
92 //   ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
93 //   ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
94 //   ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
95 //   ge_precomp (Duif): (y+x,y-x,2dxy)
96 
97 // Keep in sync with `Point` in curve25519/ops.rs.
98 typedef struct {
99   fe X;
100   fe Y;
101   fe Z;
102 } ge_p2;
103 
104 
105 // Keep in sync with `ExtPoint` in curve25519/ops.rs.
106 typedef struct {
107   fe X;
108   fe Y;
109   fe Z;
110   fe T;
111 } ge_p3;
112 
113 typedef struct {
114   fe_loose X;
115   fe_loose Y;
116   fe_loose Z;
117   fe_loose T;
118 } ge_p1p1;
119 
120 typedef struct {
121   fe_loose yplusx;
122   fe_loose yminusx;
123   fe_loose xy2d;
124 } ge_precomp;
125 
126 typedef struct {
127   fe_loose YplusX;
128   fe_loose YminusX;
129   fe_loose Z;
130   fe_loose T2d;
131 } ge_cached;
132 
133 extern const uint8_t k25519Precomp[32][8][3][32];
134 
135 #endif  // OPENSSL_HEADER_CURVE25519_INTERNAL_H
136