1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (c) 2020, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker *
3*8fb009dcSAndroid Build Coastguard Worker * Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker * purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker * copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker *
7*8fb009dcSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14*8fb009dcSAndroid Build Coastguard Worker
15*8fb009dcSAndroid Build Coastguard Worker // Some of this code is taken from the ref10 version of Ed25519 in SUPERCOP
16*8fb009dcSAndroid Build Coastguard Worker // 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
17*8fb009dcSAndroid Build Coastguard Worker // public domain. Other parts have been replaced to call into code generated by
18*8fb009dcSAndroid Build Coastguard Worker // Fiat (https://github.com/mit-plv/fiat-crypto) in //third_party/fiat.
19*8fb009dcSAndroid Build Coastguard Worker //
20*8fb009dcSAndroid Build Coastguard Worker // The field functions are shared by Ed25519 and X25519 where possible.
21*8fb009dcSAndroid Build Coastguard Worker
22*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
23*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
24*8fb009dcSAndroid Build Coastguard Worker
25*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
26*8fb009dcSAndroid Build Coastguard Worker #include <openssl/rand.h>
27*8fb009dcSAndroid Build Coastguard Worker #include <openssl/sha.h>
28*8fb009dcSAndroid Build Coastguard Worker
29*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
30*8fb009dcSAndroid Build Coastguard Worker #include "../internal.h"
31*8fb009dcSAndroid Build Coastguard Worker
32*8fb009dcSAndroid Build Coastguard Worker // Various pre-computed constants.
33*8fb009dcSAndroid Build Coastguard Worker #include "./curve25519_tables.h"
34*8fb009dcSAndroid Build Coastguard Worker
35*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_HAS_UINT128)
36*8fb009dcSAndroid Build Coastguard Worker #include "../../third_party/fiat/curve25519_64.h"
37*8fb009dcSAndroid Build Coastguard Worker #elif defined(OPENSSL_64_BIT)
38*8fb009dcSAndroid Build Coastguard Worker #include "../../third_party/fiat/curve25519_64_msvc.h"
39*8fb009dcSAndroid Build Coastguard Worker #else
40*8fb009dcSAndroid Build Coastguard Worker #include "../../third_party/fiat/curve25519_32.h"
41*8fb009dcSAndroid Build Coastguard Worker #endif
42*8fb009dcSAndroid Build Coastguard Worker
43*8fb009dcSAndroid Build Coastguard Worker
44*8fb009dcSAndroid Build Coastguard Worker // Low-level intrinsic operations
45*8fb009dcSAndroid Build Coastguard Worker
load_3(const uint8_t * in)46*8fb009dcSAndroid Build Coastguard Worker static uint64_t load_3(const uint8_t *in) {
47*8fb009dcSAndroid Build Coastguard Worker uint64_t result;
48*8fb009dcSAndroid Build Coastguard Worker result = (uint64_t)in[0];
49*8fb009dcSAndroid Build Coastguard Worker result |= ((uint64_t)in[1]) << 8;
50*8fb009dcSAndroid Build Coastguard Worker result |= ((uint64_t)in[2]) << 16;
51*8fb009dcSAndroid Build Coastguard Worker return result;
52*8fb009dcSAndroid Build Coastguard Worker }
53*8fb009dcSAndroid Build Coastguard Worker
load_4(const uint8_t * in)54*8fb009dcSAndroid Build Coastguard Worker static uint64_t load_4(const uint8_t *in) {
55*8fb009dcSAndroid Build Coastguard Worker uint64_t result;
56*8fb009dcSAndroid Build Coastguard Worker result = (uint64_t)in[0];
57*8fb009dcSAndroid Build Coastguard Worker result |= ((uint64_t)in[1]) << 8;
58*8fb009dcSAndroid Build Coastguard Worker result |= ((uint64_t)in[2]) << 16;
59*8fb009dcSAndroid Build Coastguard Worker result |= ((uint64_t)in[3]) << 24;
60*8fb009dcSAndroid Build Coastguard Worker return result;
61*8fb009dcSAndroid Build Coastguard Worker }
62*8fb009dcSAndroid Build Coastguard Worker
63*8fb009dcSAndroid Build Coastguard Worker
64*8fb009dcSAndroid Build Coastguard Worker // Field operations.
65*8fb009dcSAndroid Build Coastguard Worker
66*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_64_BIT)
67*8fb009dcSAndroid Build Coastguard Worker
68*8fb009dcSAndroid Build Coastguard Worker typedef uint64_t fe_limb_t;
69*8fb009dcSAndroid Build Coastguard Worker #define FE_NUM_LIMBS 5
70*8fb009dcSAndroid Build Coastguard Worker
71*8fb009dcSAndroid Build Coastguard Worker // assert_fe asserts that |f| satisfies bounds:
72*8fb009dcSAndroid Build Coastguard Worker //
73*8fb009dcSAndroid Build Coastguard Worker // [[0x0 ~> 0x8cccccccccccc],
74*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x8cccccccccccc],
75*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x8cccccccccccc],
76*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x8cccccccccccc],
77*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x8cccccccccccc]]
78*8fb009dcSAndroid Build Coastguard Worker //
79*8fb009dcSAndroid Build Coastguard Worker // See comments in curve25519_64.h for which functions use these bounds for
80*8fb009dcSAndroid Build Coastguard Worker // inputs or outputs.
81*8fb009dcSAndroid Build Coastguard Worker #define assert_fe(f) \
82*8fb009dcSAndroid Build Coastguard Worker do { \
83*8fb009dcSAndroid Build Coastguard Worker for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \
84*8fb009dcSAndroid Build Coastguard Worker declassify_assert(f[_assert_fe_i] <= UINT64_C(0x8cccccccccccc)); \
85*8fb009dcSAndroid Build Coastguard Worker } \
86*8fb009dcSAndroid Build Coastguard Worker } while (0)
87*8fb009dcSAndroid Build Coastguard Worker
88*8fb009dcSAndroid Build Coastguard Worker // assert_fe_loose asserts that |f| satisfies bounds:
89*8fb009dcSAndroid Build Coastguard Worker //
90*8fb009dcSAndroid Build Coastguard Worker // [[0x0 ~> 0x1a666666666664],
91*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x1a666666666664],
92*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x1a666666666664],
93*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x1a666666666664],
94*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x1a666666666664]]
95*8fb009dcSAndroid Build Coastguard Worker //
96*8fb009dcSAndroid Build Coastguard Worker // See comments in curve25519_64.h for which functions use these bounds for
97*8fb009dcSAndroid Build Coastguard Worker // inputs or outputs.
98*8fb009dcSAndroid Build Coastguard Worker #define assert_fe_loose(f) \
99*8fb009dcSAndroid Build Coastguard Worker do { \
100*8fb009dcSAndroid Build Coastguard Worker for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \
101*8fb009dcSAndroid Build Coastguard Worker declassify_assert(f[_assert_fe_i] <= UINT64_C(0x1a666666666664)); \
102*8fb009dcSAndroid Build Coastguard Worker } \
103*8fb009dcSAndroid Build Coastguard Worker } while (0)
104*8fb009dcSAndroid Build Coastguard Worker
105*8fb009dcSAndroid Build Coastguard Worker #else
106*8fb009dcSAndroid Build Coastguard Worker
107*8fb009dcSAndroid Build Coastguard Worker typedef uint32_t fe_limb_t;
108*8fb009dcSAndroid Build Coastguard Worker #define FE_NUM_LIMBS 10
109*8fb009dcSAndroid Build Coastguard Worker
110*8fb009dcSAndroid Build Coastguard Worker // assert_fe asserts that |f| satisfies bounds:
111*8fb009dcSAndroid Build Coastguard Worker //
112*8fb009dcSAndroid Build Coastguard Worker // [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333],
113*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x4666666], [0x0 ~> 0x2333333],
114*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x4666666], [0x0 ~> 0x2333333],
115*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x4666666], [0x0 ~> 0x2333333],
116*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]]
117*8fb009dcSAndroid Build Coastguard Worker //
118*8fb009dcSAndroid Build Coastguard Worker // See comments in curve25519_32.h for which functions use these bounds for
119*8fb009dcSAndroid Build Coastguard Worker // inputs or outputs.
120*8fb009dcSAndroid Build Coastguard Worker #define assert_fe(f) \
121*8fb009dcSAndroid Build Coastguard Worker do { \
122*8fb009dcSAndroid Build Coastguard Worker for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \
123*8fb009dcSAndroid Build Coastguard Worker declassify_assert(f[_assert_fe_i] <= \
124*8fb009dcSAndroid Build Coastguard Worker ((_assert_fe_i & 1) ? 0x2333333u : 0x4666666u)); \
125*8fb009dcSAndroid Build Coastguard Worker } \
126*8fb009dcSAndroid Build Coastguard Worker } while (0)
127*8fb009dcSAndroid Build Coastguard Worker
128*8fb009dcSAndroid Build Coastguard Worker // assert_fe_loose asserts that |f| satisfies bounds:
129*8fb009dcSAndroid Build Coastguard Worker //
130*8fb009dcSAndroid Build Coastguard Worker // [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999],
131*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0xd333332], [0x0 ~> 0x6999999],
132*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0xd333332], [0x0 ~> 0x6999999],
133*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0xd333332], [0x0 ~> 0x6999999],
134*8fb009dcSAndroid Build Coastguard Worker // [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]]
135*8fb009dcSAndroid Build Coastguard Worker //
136*8fb009dcSAndroid Build Coastguard Worker // See comments in curve25519_32.h for which functions use these bounds for
137*8fb009dcSAndroid Build Coastguard Worker // inputs or outputs.
138*8fb009dcSAndroid Build Coastguard Worker #define assert_fe_loose(f) \
139*8fb009dcSAndroid Build Coastguard Worker do { \
140*8fb009dcSAndroid Build Coastguard Worker for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \
141*8fb009dcSAndroid Build Coastguard Worker declassify_assert(f[_assert_fe_i] <= \
142*8fb009dcSAndroid Build Coastguard Worker ((_assert_fe_i & 1) ? 0x6999999u : 0xd333332u)); \
143*8fb009dcSAndroid Build Coastguard Worker } \
144*8fb009dcSAndroid Build Coastguard Worker } while (0)
145*8fb009dcSAndroid Build Coastguard Worker
146*8fb009dcSAndroid Build Coastguard Worker #endif // OPENSSL_64_BIT
147*8fb009dcSAndroid Build Coastguard Worker
148*8fb009dcSAndroid Build Coastguard Worker static_assert(sizeof(fe) == sizeof(fe_limb_t) * FE_NUM_LIMBS,
149*8fb009dcSAndroid Build Coastguard Worker "fe_limb_t[FE_NUM_LIMBS] is inconsistent with fe");
150*8fb009dcSAndroid Build Coastguard Worker
fe_frombytes_strict(fe * h,const uint8_t s[32])151*8fb009dcSAndroid Build Coastguard Worker static void fe_frombytes_strict(fe *h, const uint8_t s[32]) {
152*8fb009dcSAndroid Build Coastguard Worker // |fiat_25519_from_bytes| requires the top-most bit be clear.
153*8fb009dcSAndroid Build Coastguard Worker declassify_assert((s[31] & 0x80) == 0);
154*8fb009dcSAndroid Build Coastguard Worker fiat_25519_from_bytes(h->v, s);
155*8fb009dcSAndroid Build Coastguard Worker assert_fe(h->v);
156*8fb009dcSAndroid Build Coastguard Worker }
157*8fb009dcSAndroid Build Coastguard Worker
fe_frombytes(fe * h,const uint8_t s[32])158*8fb009dcSAndroid Build Coastguard Worker static void fe_frombytes(fe *h, const uint8_t s[32]) {
159*8fb009dcSAndroid Build Coastguard Worker uint8_t s_copy[32];
160*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(s_copy, s, 32);
161*8fb009dcSAndroid Build Coastguard Worker s_copy[31] &= 0x7f;
162*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(h, s_copy);
163*8fb009dcSAndroid Build Coastguard Worker }
164*8fb009dcSAndroid Build Coastguard Worker
fe_tobytes(uint8_t s[32],const fe * f)165*8fb009dcSAndroid Build Coastguard Worker static void fe_tobytes(uint8_t s[32], const fe *f) {
166*8fb009dcSAndroid Build Coastguard Worker assert_fe(f->v);
167*8fb009dcSAndroid Build Coastguard Worker fiat_25519_to_bytes(s, f->v);
168*8fb009dcSAndroid Build Coastguard Worker }
169*8fb009dcSAndroid Build Coastguard Worker
170*8fb009dcSAndroid Build Coastguard Worker // h = 0
fe_0(fe * h)171*8fb009dcSAndroid Build Coastguard Worker static void fe_0(fe *h) {
172*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(h, 0, sizeof(fe));
173*8fb009dcSAndroid Build Coastguard Worker }
174*8fb009dcSAndroid Build Coastguard Worker
fe_loose_0(fe_loose * h)175*8fb009dcSAndroid Build Coastguard Worker static void fe_loose_0(fe_loose *h) {
176*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(h, 0, sizeof(fe_loose));
177*8fb009dcSAndroid Build Coastguard Worker }
178*8fb009dcSAndroid Build Coastguard Worker
179*8fb009dcSAndroid Build Coastguard Worker // h = 1
fe_1(fe * h)180*8fb009dcSAndroid Build Coastguard Worker static void fe_1(fe *h) {
181*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(h, 0, sizeof(fe));
182*8fb009dcSAndroid Build Coastguard Worker h->v[0] = 1;
183*8fb009dcSAndroid Build Coastguard Worker }
184*8fb009dcSAndroid Build Coastguard Worker
fe_loose_1(fe_loose * h)185*8fb009dcSAndroid Build Coastguard Worker static void fe_loose_1(fe_loose *h) {
186*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(h, 0, sizeof(fe_loose));
187*8fb009dcSAndroid Build Coastguard Worker h->v[0] = 1;
188*8fb009dcSAndroid Build Coastguard Worker }
189*8fb009dcSAndroid Build Coastguard Worker
190*8fb009dcSAndroid Build Coastguard Worker // h = f + g
191*8fb009dcSAndroid Build Coastguard Worker // Can overlap h with f or g.
fe_add(fe_loose * h,const fe * f,const fe * g)192*8fb009dcSAndroid Build Coastguard Worker static void fe_add(fe_loose *h, const fe *f, const fe *g) {
193*8fb009dcSAndroid Build Coastguard Worker assert_fe(f->v);
194*8fb009dcSAndroid Build Coastguard Worker assert_fe(g->v);
195*8fb009dcSAndroid Build Coastguard Worker fiat_25519_add(h->v, f->v, g->v);
196*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(h->v);
197*8fb009dcSAndroid Build Coastguard Worker }
198*8fb009dcSAndroid Build Coastguard Worker
199*8fb009dcSAndroid Build Coastguard Worker // h = f - g
200*8fb009dcSAndroid Build Coastguard Worker // Can overlap h with f or g.
fe_sub(fe_loose * h,const fe * f,const fe * g)201*8fb009dcSAndroid Build Coastguard Worker static void fe_sub(fe_loose *h, const fe *f, const fe *g) {
202*8fb009dcSAndroid Build Coastguard Worker assert_fe(f->v);
203*8fb009dcSAndroid Build Coastguard Worker assert_fe(g->v);
204*8fb009dcSAndroid Build Coastguard Worker fiat_25519_sub(h->v, f->v, g->v);
205*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(h->v);
206*8fb009dcSAndroid Build Coastguard Worker }
207*8fb009dcSAndroid Build Coastguard Worker
fe_carry(fe * h,const fe_loose * f)208*8fb009dcSAndroid Build Coastguard Worker static void fe_carry(fe *h, const fe_loose* f) {
209*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(f->v);
210*8fb009dcSAndroid Build Coastguard Worker fiat_25519_carry(h->v, f->v);
211*8fb009dcSAndroid Build Coastguard Worker assert_fe(h->v);
212*8fb009dcSAndroid Build Coastguard Worker }
213*8fb009dcSAndroid Build Coastguard Worker
fe_mul_impl(fe_limb_t out[FE_NUM_LIMBS],const fe_limb_t in1[FE_NUM_LIMBS],const fe_limb_t in2[FE_NUM_LIMBS])214*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_impl(fe_limb_t out[FE_NUM_LIMBS],
215*8fb009dcSAndroid Build Coastguard Worker const fe_limb_t in1[FE_NUM_LIMBS],
216*8fb009dcSAndroid Build Coastguard Worker const fe_limb_t in2[FE_NUM_LIMBS]) {
217*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(in1);
218*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(in2);
219*8fb009dcSAndroid Build Coastguard Worker fiat_25519_carry_mul(out, in1, in2);
220*8fb009dcSAndroid Build Coastguard Worker assert_fe(out);
221*8fb009dcSAndroid Build Coastguard Worker }
222*8fb009dcSAndroid Build Coastguard Worker
fe_mul_ltt(fe_loose * h,const fe * f,const fe * g)223*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) {
224*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
225*8fb009dcSAndroid Build Coastguard Worker }
226*8fb009dcSAndroid Build Coastguard Worker
fe_mul_llt(fe_loose * h,const fe_loose * f,const fe * g)227*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) {
228*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
229*8fb009dcSAndroid Build Coastguard Worker }
230*8fb009dcSAndroid Build Coastguard Worker
fe_mul_ttt(fe * h,const fe * f,const fe * g)231*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_ttt(fe *h, const fe *f, const fe *g) {
232*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
233*8fb009dcSAndroid Build Coastguard Worker }
234*8fb009dcSAndroid Build Coastguard Worker
fe_mul_tlt(fe * h,const fe_loose * f,const fe * g)235*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) {
236*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
237*8fb009dcSAndroid Build Coastguard Worker }
238*8fb009dcSAndroid Build Coastguard Worker
fe_mul_ttl(fe * h,const fe * f,const fe_loose * g)239*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) {
240*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
241*8fb009dcSAndroid Build Coastguard Worker }
242*8fb009dcSAndroid Build Coastguard Worker
fe_mul_tll(fe * h,const fe_loose * f,const fe_loose * g)243*8fb009dcSAndroid Build Coastguard Worker static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) {
244*8fb009dcSAndroid Build Coastguard Worker fe_mul_impl(h->v, f->v, g->v);
245*8fb009dcSAndroid Build Coastguard Worker }
246*8fb009dcSAndroid Build Coastguard Worker
fe_sq_tl(fe * h,const fe_loose * f)247*8fb009dcSAndroid Build Coastguard Worker static void fe_sq_tl(fe *h, const fe_loose *f) {
248*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(f->v);
249*8fb009dcSAndroid Build Coastguard Worker fiat_25519_carry_square(h->v, f->v);
250*8fb009dcSAndroid Build Coastguard Worker assert_fe(h->v);
251*8fb009dcSAndroid Build Coastguard Worker }
252*8fb009dcSAndroid Build Coastguard Worker
fe_sq_tt(fe * h,const fe * f)253*8fb009dcSAndroid Build Coastguard Worker static void fe_sq_tt(fe *h, const fe *f) {
254*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(f->v);
255*8fb009dcSAndroid Build Coastguard Worker fiat_25519_carry_square(h->v, f->v);
256*8fb009dcSAndroid Build Coastguard Worker assert_fe(h->v);
257*8fb009dcSAndroid Build Coastguard Worker }
258*8fb009dcSAndroid Build Coastguard Worker
259*8fb009dcSAndroid Build Coastguard Worker // Replace (f,g) with (g,f) if b == 1;
260*8fb009dcSAndroid Build Coastguard Worker // replace (f,g) with (f,g) if b == 0.
261*8fb009dcSAndroid Build Coastguard Worker //
262*8fb009dcSAndroid Build Coastguard Worker // Preconditions: b in {0,1}.
fe_cswap(fe * f,fe * g,fe_limb_t b)263*8fb009dcSAndroid Build Coastguard Worker static void fe_cswap(fe *f, fe *g, fe_limb_t b) {
264*8fb009dcSAndroid Build Coastguard Worker b = 0-b;
265*8fb009dcSAndroid Build Coastguard Worker for (unsigned i = 0; i < FE_NUM_LIMBS; i++) {
266*8fb009dcSAndroid Build Coastguard Worker fe_limb_t x = f->v[i] ^ g->v[i];
267*8fb009dcSAndroid Build Coastguard Worker x &= b;
268*8fb009dcSAndroid Build Coastguard Worker f->v[i] ^= x;
269*8fb009dcSAndroid Build Coastguard Worker g->v[i] ^= x;
270*8fb009dcSAndroid Build Coastguard Worker }
271*8fb009dcSAndroid Build Coastguard Worker }
272*8fb009dcSAndroid Build Coastguard Worker
fe_mul121666(fe * h,const fe_loose * f)273*8fb009dcSAndroid Build Coastguard Worker static void fe_mul121666(fe *h, const fe_loose *f) {
274*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(f->v);
275*8fb009dcSAndroid Build Coastguard Worker fiat_25519_carry_scmul_121666(h->v, f->v);
276*8fb009dcSAndroid Build Coastguard Worker assert_fe(h->v);
277*8fb009dcSAndroid Build Coastguard Worker }
278*8fb009dcSAndroid Build Coastguard Worker
279*8fb009dcSAndroid Build Coastguard Worker // h = -f
fe_neg(fe_loose * h,const fe * f)280*8fb009dcSAndroid Build Coastguard Worker static void fe_neg(fe_loose *h, const fe *f) {
281*8fb009dcSAndroid Build Coastguard Worker assert_fe(f->v);
282*8fb009dcSAndroid Build Coastguard Worker fiat_25519_opp(h->v, f->v);
283*8fb009dcSAndroid Build Coastguard Worker assert_fe_loose(h->v);
284*8fb009dcSAndroid Build Coastguard Worker }
285*8fb009dcSAndroid Build Coastguard Worker
286*8fb009dcSAndroid Build Coastguard Worker // Replace (f,g) with (g,g) if b == 1;
287*8fb009dcSAndroid Build Coastguard Worker // replace (f,g) with (f,g) if b == 0.
288*8fb009dcSAndroid Build Coastguard Worker //
289*8fb009dcSAndroid Build Coastguard Worker // Preconditions: b in {0,1}.
fe_cmov(fe_loose * f,const fe_loose * g,fe_limb_t b)290*8fb009dcSAndroid Build Coastguard Worker static void fe_cmov(fe_loose *f, const fe_loose *g, fe_limb_t b) {
291*8fb009dcSAndroid Build Coastguard Worker // Silence an unused function warning. |fiat_25519_selectznz| isn't quite the
292*8fb009dcSAndroid Build Coastguard Worker // calling convention the rest of this code wants, so implement it by hand.
293*8fb009dcSAndroid Build Coastguard Worker //
294*8fb009dcSAndroid Build Coastguard Worker // TODO(davidben): Switch to fiat's calling convention, or ask fiat to emit a
295*8fb009dcSAndroid Build Coastguard Worker // different one.
296*8fb009dcSAndroid Build Coastguard Worker (void)fiat_25519_selectznz;
297*8fb009dcSAndroid Build Coastguard Worker
298*8fb009dcSAndroid Build Coastguard Worker b = 0-b;
299*8fb009dcSAndroid Build Coastguard Worker for (unsigned i = 0; i < FE_NUM_LIMBS; i++) {
300*8fb009dcSAndroid Build Coastguard Worker fe_limb_t x = f->v[i] ^ g->v[i];
301*8fb009dcSAndroid Build Coastguard Worker x &= b;
302*8fb009dcSAndroid Build Coastguard Worker f->v[i] ^= x;
303*8fb009dcSAndroid Build Coastguard Worker }
304*8fb009dcSAndroid Build Coastguard Worker }
305*8fb009dcSAndroid Build Coastguard Worker
306*8fb009dcSAndroid Build Coastguard Worker // h = f
fe_copy(fe * h,const fe * f)307*8fb009dcSAndroid Build Coastguard Worker static void fe_copy(fe *h, const fe *f) {
308*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memmove(h, f, sizeof(fe));
309*8fb009dcSAndroid Build Coastguard Worker }
310*8fb009dcSAndroid Build Coastguard Worker
fe_copy_lt(fe_loose * h,const fe * f)311*8fb009dcSAndroid Build Coastguard Worker static void fe_copy_lt(fe_loose *h, const fe *f) {
312*8fb009dcSAndroid Build Coastguard Worker static_assert(sizeof(fe_loose) == sizeof(fe), "fe and fe_loose mismatch");
313*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memmove(h, f, sizeof(fe));
314*8fb009dcSAndroid Build Coastguard Worker }
315*8fb009dcSAndroid Build Coastguard Worker
fe_loose_invert(fe * out,const fe_loose * z)316*8fb009dcSAndroid Build Coastguard Worker static void fe_loose_invert(fe *out, const fe_loose *z) {
317*8fb009dcSAndroid Build Coastguard Worker fe t0;
318*8fb009dcSAndroid Build Coastguard Worker fe t1;
319*8fb009dcSAndroid Build Coastguard Worker fe t2;
320*8fb009dcSAndroid Build Coastguard Worker fe t3;
321*8fb009dcSAndroid Build Coastguard Worker int i;
322*8fb009dcSAndroid Build Coastguard Worker
323*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&t0, z);
324*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t0);
325*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 2; ++i) {
326*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
327*8fb009dcSAndroid Build Coastguard Worker }
328*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&t1, z, &t1);
329*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t0, &t1);
330*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t0);
331*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t1, &t2);
332*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t1);
333*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 5; ++i) {
334*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
335*8fb009dcSAndroid Build Coastguard Worker }
336*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t2, &t1);
337*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t1);
338*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 10; ++i) {
339*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
340*8fb009dcSAndroid Build Coastguard Worker }
341*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t2, &t2, &t1);
342*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t3, &t2);
343*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 20; ++i) {
344*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t3, &t3);
345*8fb009dcSAndroid Build Coastguard Worker }
346*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t2, &t3, &t2);
347*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
348*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 10; ++i) {
349*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
350*8fb009dcSAndroid Build Coastguard Worker }
351*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t2, &t1);
352*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t1);
353*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 50; ++i) {
354*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
355*8fb009dcSAndroid Build Coastguard Worker }
356*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t2, &t2, &t1);
357*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t3, &t2);
358*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 100; ++i) {
359*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t3, &t3);
360*8fb009dcSAndroid Build Coastguard Worker }
361*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t2, &t3, &t2);
362*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
363*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 50; ++i) {
364*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
365*8fb009dcSAndroid Build Coastguard Worker }
366*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t2, &t1);
367*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
368*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 5; ++i) {
369*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
370*8fb009dcSAndroid Build Coastguard Worker }
371*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(out, &t1, &t0);
372*8fb009dcSAndroid Build Coastguard Worker }
373*8fb009dcSAndroid Build Coastguard Worker
fe_invert(fe * out,const fe * z)374*8fb009dcSAndroid Build Coastguard Worker static void fe_invert(fe *out, const fe *z) {
375*8fb009dcSAndroid Build Coastguard Worker fe_loose l;
376*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&l, z);
377*8fb009dcSAndroid Build Coastguard Worker fe_loose_invert(out, &l);
378*8fb009dcSAndroid Build Coastguard Worker }
379*8fb009dcSAndroid Build Coastguard Worker
380*8fb009dcSAndroid Build Coastguard Worker // return 0 if f == 0
381*8fb009dcSAndroid Build Coastguard Worker // return 1 if f != 0
fe_isnonzero(const fe_loose * f)382*8fb009dcSAndroid Build Coastguard Worker static int fe_isnonzero(const fe_loose *f) {
383*8fb009dcSAndroid Build Coastguard Worker fe tight;
384*8fb009dcSAndroid Build Coastguard Worker fe_carry(&tight, f);
385*8fb009dcSAndroid Build Coastguard Worker uint8_t s[32];
386*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(s, &tight);
387*8fb009dcSAndroid Build Coastguard Worker
388*8fb009dcSAndroid Build Coastguard Worker static const uint8_t zero[32] = {0};
389*8fb009dcSAndroid Build Coastguard Worker return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0;
390*8fb009dcSAndroid Build Coastguard Worker }
391*8fb009dcSAndroid Build Coastguard Worker
392*8fb009dcSAndroid Build Coastguard Worker // return 1 if f is in {1,3,5,...,q-2}
393*8fb009dcSAndroid Build Coastguard Worker // return 0 if f is in {0,2,4,...,q-1}
fe_isnegative(const fe * f)394*8fb009dcSAndroid Build Coastguard Worker static int fe_isnegative(const fe *f) {
395*8fb009dcSAndroid Build Coastguard Worker uint8_t s[32];
396*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(s, f);
397*8fb009dcSAndroid Build Coastguard Worker return s[0] & 1;
398*8fb009dcSAndroid Build Coastguard Worker }
399*8fb009dcSAndroid Build Coastguard Worker
fe_sq2_tt(fe * h,const fe * f)400*8fb009dcSAndroid Build Coastguard Worker static void fe_sq2_tt(fe *h, const fe *f) {
401*8fb009dcSAndroid Build Coastguard Worker // h = f^2
402*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(h, f);
403*8fb009dcSAndroid Build Coastguard Worker
404*8fb009dcSAndroid Build Coastguard Worker // h = h + h
405*8fb009dcSAndroid Build Coastguard Worker fe_loose tmp;
406*8fb009dcSAndroid Build Coastguard Worker fe_add(&tmp, h, h);
407*8fb009dcSAndroid Build Coastguard Worker fe_carry(h, &tmp);
408*8fb009dcSAndroid Build Coastguard Worker }
409*8fb009dcSAndroid Build Coastguard Worker
fe_pow22523(fe * out,const fe * z)410*8fb009dcSAndroid Build Coastguard Worker static void fe_pow22523(fe *out, const fe *z) {
411*8fb009dcSAndroid Build Coastguard Worker fe t0;
412*8fb009dcSAndroid Build Coastguard Worker fe t1;
413*8fb009dcSAndroid Build Coastguard Worker fe t2;
414*8fb009dcSAndroid Build Coastguard Worker int i;
415*8fb009dcSAndroid Build Coastguard Worker
416*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t0, z);
417*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t0);
418*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 2; ++i) {
419*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
420*8fb009dcSAndroid Build Coastguard Worker }
421*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, z, &t1);
422*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t0, &t1);
423*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t0, &t0);
424*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t1, &t0);
425*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t0);
426*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 5; ++i) {
427*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
428*8fb009dcSAndroid Build Coastguard Worker }
429*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t1, &t0);
430*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t0);
431*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 10; ++i) {
432*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
433*8fb009dcSAndroid Build Coastguard Worker }
434*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t1, &t0);
435*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t1);
436*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 20; ++i) {
437*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
438*8fb009dcSAndroid Build Coastguard Worker }
439*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t2, &t1);
440*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
441*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 10; ++i) {
442*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
443*8fb009dcSAndroid Build Coastguard Worker }
444*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t1, &t0);
445*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t0);
446*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 50; ++i) {
447*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
448*8fb009dcSAndroid Build Coastguard Worker }
449*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t1, &t0);
450*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t1);
451*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 100; ++i) {
452*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t2, &t2);
453*8fb009dcSAndroid Build Coastguard Worker }
454*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t1, &t2, &t1);
455*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
456*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 50; ++i) {
457*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t1, &t1);
458*8fb009dcSAndroid Build Coastguard Worker }
459*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&t0, &t1, &t0);
460*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t0, &t0);
461*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 2; ++i) {
462*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&t0, &t0);
463*8fb009dcSAndroid Build Coastguard Worker }
464*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(out, &t0, z);
465*8fb009dcSAndroid Build Coastguard Worker }
466*8fb009dcSAndroid Build Coastguard Worker
467*8fb009dcSAndroid Build Coastguard Worker
468*8fb009dcSAndroid Build Coastguard Worker // Group operations.
469*8fb009dcSAndroid Build Coastguard Worker
x25519_ge_tobytes(uint8_t s[32],const ge_p2 * h)470*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h) {
471*8fb009dcSAndroid Build Coastguard Worker fe recip;
472*8fb009dcSAndroid Build Coastguard Worker fe x;
473*8fb009dcSAndroid Build Coastguard Worker fe y;
474*8fb009dcSAndroid Build Coastguard Worker
475*8fb009dcSAndroid Build Coastguard Worker fe_invert(&recip, &h->Z);
476*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&x, &h->X, &recip);
477*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&y, &h->Y, &recip);
478*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(s, &y);
479*8fb009dcSAndroid Build Coastguard Worker s[31] ^= fe_isnegative(&x) << 7;
480*8fb009dcSAndroid Build Coastguard Worker }
481*8fb009dcSAndroid Build Coastguard Worker
ge_p3_tobytes(uint8_t s[32],const ge_p3 * h)482*8fb009dcSAndroid Build Coastguard Worker static void ge_p3_tobytes(uint8_t s[32], const ge_p3 *h) {
483*8fb009dcSAndroid Build Coastguard Worker fe recip;
484*8fb009dcSAndroid Build Coastguard Worker fe x;
485*8fb009dcSAndroid Build Coastguard Worker fe y;
486*8fb009dcSAndroid Build Coastguard Worker
487*8fb009dcSAndroid Build Coastguard Worker fe_invert(&recip, &h->Z);
488*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&x, &h->X, &recip);
489*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&y, &h->Y, &recip);
490*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(s, &y);
491*8fb009dcSAndroid Build Coastguard Worker s[31] ^= fe_isnegative(&x) << 7;
492*8fb009dcSAndroid Build Coastguard Worker }
493*8fb009dcSAndroid Build Coastguard Worker
x25519_ge_frombytes_vartime(ge_p3 * h,const uint8_t s[32])494*8fb009dcSAndroid Build Coastguard Worker int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t s[32]) {
495*8fb009dcSAndroid Build Coastguard Worker fe u;
496*8fb009dcSAndroid Build Coastguard Worker fe_loose v;
497*8fb009dcSAndroid Build Coastguard Worker fe w;
498*8fb009dcSAndroid Build Coastguard Worker fe vxx;
499*8fb009dcSAndroid Build Coastguard Worker fe_loose check;
500*8fb009dcSAndroid Build Coastguard Worker
501*8fb009dcSAndroid Build Coastguard Worker fe_frombytes(&h->Y, s);
502*8fb009dcSAndroid Build Coastguard Worker fe_1(&h->Z);
503*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&w, &h->Y);
504*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&vxx, &w, &d);
505*8fb009dcSAndroid Build Coastguard Worker fe_sub(&v, &w, &h->Z); // u = y^2-1
506*8fb009dcSAndroid Build Coastguard Worker fe_carry(&u, &v);
507*8fb009dcSAndroid Build Coastguard Worker fe_add(&v, &vxx, &h->Z); // v = dy^2+1
508*8fb009dcSAndroid Build Coastguard Worker
509*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttl(&w, &u, &v); // w = u*v
510*8fb009dcSAndroid Build Coastguard Worker fe_pow22523(&h->X, &w); // x = w^((q-5)/8)
511*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&h->X, &h->X, &u); // x = u*w^((q-5)/8)
512*8fb009dcSAndroid Build Coastguard Worker
513*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&vxx, &h->X);
514*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttl(&vxx, &vxx, &v);
515*8fb009dcSAndroid Build Coastguard Worker fe_sub(&check, &vxx, &u);
516*8fb009dcSAndroid Build Coastguard Worker if (fe_isnonzero(&check)) {
517*8fb009dcSAndroid Build Coastguard Worker fe_add(&check, &vxx, &u);
518*8fb009dcSAndroid Build Coastguard Worker if (fe_isnonzero(&check)) {
519*8fb009dcSAndroid Build Coastguard Worker return 0;
520*8fb009dcSAndroid Build Coastguard Worker }
521*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&h->X, &h->X, &sqrtm1);
522*8fb009dcSAndroid Build Coastguard Worker }
523*8fb009dcSAndroid Build Coastguard Worker
524*8fb009dcSAndroid Build Coastguard Worker if (fe_isnegative(&h->X) != (s[31] >> 7)) {
525*8fb009dcSAndroid Build Coastguard Worker fe_loose t;
526*8fb009dcSAndroid Build Coastguard Worker fe_neg(&t, &h->X);
527*8fb009dcSAndroid Build Coastguard Worker fe_carry(&h->X, &t);
528*8fb009dcSAndroid Build Coastguard Worker }
529*8fb009dcSAndroid Build Coastguard Worker
530*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&h->T, &h->X, &h->Y);
531*8fb009dcSAndroid Build Coastguard Worker return 1;
532*8fb009dcSAndroid Build Coastguard Worker }
533*8fb009dcSAndroid Build Coastguard Worker
ge_p2_0(ge_p2 * h)534*8fb009dcSAndroid Build Coastguard Worker static void ge_p2_0(ge_p2 *h) {
535*8fb009dcSAndroid Build Coastguard Worker fe_0(&h->X);
536*8fb009dcSAndroid Build Coastguard Worker fe_1(&h->Y);
537*8fb009dcSAndroid Build Coastguard Worker fe_1(&h->Z);
538*8fb009dcSAndroid Build Coastguard Worker }
539*8fb009dcSAndroid Build Coastguard Worker
ge_p3_0(ge_p3 * h)540*8fb009dcSAndroid Build Coastguard Worker static void ge_p3_0(ge_p3 *h) {
541*8fb009dcSAndroid Build Coastguard Worker fe_0(&h->X);
542*8fb009dcSAndroid Build Coastguard Worker fe_1(&h->Y);
543*8fb009dcSAndroid Build Coastguard Worker fe_1(&h->Z);
544*8fb009dcSAndroid Build Coastguard Worker fe_0(&h->T);
545*8fb009dcSAndroid Build Coastguard Worker }
546*8fb009dcSAndroid Build Coastguard Worker
ge_cached_0(ge_cached * h)547*8fb009dcSAndroid Build Coastguard Worker static void ge_cached_0(ge_cached *h) {
548*8fb009dcSAndroid Build Coastguard Worker fe_loose_1(&h->YplusX);
549*8fb009dcSAndroid Build Coastguard Worker fe_loose_1(&h->YminusX);
550*8fb009dcSAndroid Build Coastguard Worker fe_loose_1(&h->Z);
551*8fb009dcSAndroid Build Coastguard Worker fe_loose_0(&h->T2d);
552*8fb009dcSAndroid Build Coastguard Worker }
553*8fb009dcSAndroid Build Coastguard Worker
ge_precomp_0(ge_precomp * h)554*8fb009dcSAndroid Build Coastguard Worker static void ge_precomp_0(ge_precomp *h) {
555*8fb009dcSAndroid Build Coastguard Worker fe_loose_1(&h->yplusx);
556*8fb009dcSAndroid Build Coastguard Worker fe_loose_1(&h->yminusx);
557*8fb009dcSAndroid Build Coastguard Worker fe_loose_0(&h->xy2d);
558*8fb009dcSAndroid Build Coastguard Worker }
559*8fb009dcSAndroid Build Coastguard Worker
560*8fb009dcSAndroid Build Coastguard Worker // r = p
ge_p3_to_p2(ge_p2 * r,const ge_p3 * p)561*8fb009dcSAndroid Build Coastguard Worker static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
562*8fb009dcSAndroid Build Coastguard Worker fe_copy(&r->X, &p->X);
563*8fb009dcSAndroid Build Coastguard Worker fe_copy(&r->Y, &p->Y);
564*8fb009dcSAndroid Build Coastguard Worker fe_copy(&r->Z, &p->Z);
565*8fb009dcSAndroid Build Coastguard Worker }
566*8fb009dcSAndroid Build Coastguard Worker
567*8fb009dcSAndroid Build Coastguard Worker // r = p
x25519_ge_p3_to_cached(ge_cached * r,const ge_p3 * p)568*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
569*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->YplusX, &p->Y, &p->X);
570*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->YminusX, &p->Y, &p->X);
571*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&r->Z, &p->Z);
572*8fb009dcSAndroid Build Coastguard Worker fe_mul_ltt(&r->T2d, &p->T, &d2);
573*8fb009dcSAndroid Build Coastguard Worker }
574*8fb009dcSAndroid Build Coastguard Worker
575*8fb009dcSAndroid Build Coastguard Worker // r = p
x25519_ge_p1p1_to_p2(ge_p2 * r,const ge_p1p1 * p)576*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
577*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->X, &p->X, &p->T);
578*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->Y, &p->Y, &p->Z);
579*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->Z, &p->Z, &p->T);
580*8fb009dcSAndroid Build Coastguard Worker }
581*8fb009dcSAndroid Build Coastguard Worker
582*8fb009dcSAndroid Build Coastguard Worker // r = p
x25519_ge_p1p1_to_p3(ge_p3 * r,const ge_p1p1 * p)583*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
584*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->X, &p->X, &p->T);
585*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->Y, &p->Y, &p->Z);
586*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->Z, &p->Z, &p->T);
587*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&r->T, &p->X, &p->Y);
588*8fb009dcSAndroid Build Coastguard Worker }
589*8fb009dcSAndroid Build Coastguard Worker
590*8fb009dcSAndroid Build Coastguard Worker // r = p
ge_p1p1_to_cached(ge_cached * r,const ge_p1p1 * p)591*8fb009dcSAndroid Build Coastguard Worker static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) {
592*8fb009dcSAndroid Build Coastguard Worker ge_p3 t;
593*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&t, p);
594*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(r, &t);
595*8fb009dcSAndroid Build Coastguard Worker }
596*8fb009dcSAndroid Build Coastguard Worker
597*8fb009dcSAndroid Build Coastguard Worker // r = 2 * p
ge_p2_dbl(ge_p1p1 * r,const ge_p2 * p)598*8fb009dcSAndroid Build Coastguard Worker static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
599*8fb009dcSAndroid Build Coastguard Worker fe trX, trZ, trT;
600*8fb009dcSAndroid Build Coastguard Worker fe t0;
601*8fb009dcSAndroid Build Coastguard Worker
602*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&trX, &p->X);
603*8fb009dcSAndroid Build Coastguard Worker fe_sq_tt(&trZ, &p->Y);
604*8fb009dcSAndroid Build Coastguard Worker fe_sq2_tt(&trT, &p->Z);
605*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &p->X, &p->Y);
606*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&t0, &r->Y);
607*8fb009dcSAndroid Build Coastguard Worker
608*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &trZ, &trX);
609*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Z, &trZ, &trX);
610*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->Y);
611*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->X, &t0, &trZ);
612*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->Z);
613*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->T, &trT, &trZ);
614*8fb009dcSAndroid Build Coastguard Worker }
615*8fb009dcSAndroid Build Coastguard Worker
616*8fb009dcSAndroid Build Coastguard Worker // r = 2 * p
ge_p3_dbl(ge_p1p1 * r,const ge_p3 * p)617*8fb009dcSAndroid Build Coastguard Worker static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
618*8fb009dcSAndroid Build Coastguard Worker ge_p2 q;
619*8fb009dcSAndroid Build Coastguard Worker ge_p3_to_p2(&q, p);
620*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(r, &q);
621*8fb009dcSAndroid Build Coastguard Worker }
622*8fb009dcSAndroid Build Coastguard Worker
623*8fb009dcSAndroid Build Coastguard Worker // r = p + q
ge_madd(ge_p1p1 * r,const ge_p3 * p,const ge_precomp * q)624*8fb009dcSAndroid Build Coastguard Worker static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
625*8fb009dcSAndroid Build Coastguard Worker fe trY, trZ, trT;
626*8fb009dcSAndroid Build Coastguard Worker
627*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->X, &p->Y, &p->X);
628*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Y, &p->Y, &p->X);
629*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trZ, &r->X, &q->yplusx);
630*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trY, &r->Y, &q->yminusx);
631*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&trT, &q->xy2d, &p->T);
632*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &p->Z, &p->Z);
633*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->X, &trZ, &trY);
634*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &trZ, &trY);
635*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->T);
636*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Z, &trZ, &trT);
637*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->T, &trZ, &trT);
638*8fb009dcSAndroid Build Coastguard Worker }
639*8fb009dcSAndroid Build Coastguard Worker
640*8fb009dcSAndroid Build Coastguard Worker // r = p - q
ge_msub(ge_p1p1 * r,const ge_p3 * p,const ge_precomp * q)641*8fb009dcSAndroid Build Coastguard Worker static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
642*8fb009dcSAndroid Build Coastguard Worker fe trY, trZ, trT;
643*8fb009dcSAndroid Build Coastguard Worker
644*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->X, &p->Y, &p->X);
645*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Y, &p->Y, &p->X);
646*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trZ, &r->X, &q->yminusx);
647*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trY, &r->Y, &q->yplusx);
648*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&trT, &q->xy2d, &p->T);
649*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &p->Z, &p->Z);
650*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->X, &trZ, &trY);
651*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &trZ, &trY);
652*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->T);
653*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Z, &trZ, &trT);
654*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &trZ, &trT);
655*8fb009dcSAndroid Build Coastguard Worker }
656*8fb009dcSAndroid Build Coastguard Worker
657*8fb009dcSAndroid Build Coastguard Worker // r = p + q
x25519_ge_add(ge_p1p1 * r,const ge_p3 * p,const ge_cached * q)658*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
659*8fb009dcSAndroid Build Coastguard Worker fe trX, trY, trZ, trT;
660*8fb009dcSAndroid Build Coastguard Worker
661*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->X, &p->Y, &p->X);
662*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Y, &p->Y, &p->X);
663*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trZ, &r->X, &q->YplusX);
664*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trY, &r->Y, &q->YminusX);
665*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&trT, &q->T2d, &p->T);
666*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttl(&trX, &p->Z, &q->Z);
667*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &trX, &trX);
668*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->X, &trZ, &trY);
669*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &trZ, &trY);
670*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->T);
671*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Z, &trZ, &trT);
672*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->T, &trZ, &trT);
673*8fb009dcSAndroid Build Coastguard Worker }
674*8fb009dcSAndroid Build Coastguard Worker
675*8fb009dcSAndroid Build Coastguard Worker // r = p - q
x25519_ge_sub(ge_p1p1 * r,const ge_p3 * p,const ge_cached * q)676*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
677*8fb009dcSAndroid Build Coastguard Worker fe trX, trY, trZ, trT;
678*8fb009dcSAndroid Build Coastguard Worker
679*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->X, &p->Y, &p->X);
680*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Y, &p->Y, &p->X);
681*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trZ, &r->X, &q->YminusX);
682*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&trY, &r->Y, &q->YplusX);
683*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&trT, &q->T2d, &p->T);
684*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttl(&trX, &p->Z, &q->Z);
685*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &trX, &trX);
686*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->X, &trZ, &trY);
687*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->Y, &trZ, &trY);
688*8fb009dcSAndroid Build Coastguard Worker fe_carry(&trZ, &r->T);
689*8fb009dcSAndroid Build Coastguard Worker fe_sub(&r->Z, &trZ, &trT);
690*8fb009dcSAndroid Build Coastguard Worker fe_add(&r->T, &trZ, &trT);
691*8fb009dcSAndroid Build Coastguard Worker }
692*8fb009dcSAndroid Build Coastguard Worker
cmov(ge_precomp * t,const ge_precomp * u,uint8_t b)693*8fb009dcSAndroid Build Coastguard Worker static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
694*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->yplusx, &u->yplusx, b);
695*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->yminusx, &u->yminusx, b);
696*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->xy2d, &u->xy2d, b);
697*8fb009dcSAndroid Build Coastguard Worker }
698*8fb009dcSAndroid Build Coastguard Worker
x25519_ge_scalarmult_small_precomp(ge_p3 * h,const uint8_t a[32],const uint8_t precomp_table[15* 2* 32])699*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_scalarmult_small_precomp(
700*8fb009dcSAndroid Build Coastguard Worker ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) {
701*8fb009dcSAndroid Build Coastguard Worker // precomp_table is first expanded into matching |ge_precomp|
702*8fb009dcSAndroid Build Coastguard Worker // elements.
703*8fb009dcSAndroid Build Coastguard Worker ge_precomp multiples[15];
704*8fb009dcSAndroid Build Coastguard Worker
705*8fb009dcSAndroid Build Coastguard Worker unsigned i;
706*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 15; i++) {
707*8fb009dcSAndroid Build Coastguard Worker // The precomputed table is assumed to already clear the top bit, so
708*8fb009dcSAndroid Build Coastguard Worker // |fe_frombytes_strict| may be used directly.
709*8fb009dcSAndroid Build Coastguard Worker const uint8_t *bytes = &precomp_table[i*(2 * 32)];
710*8fb009dcSAndroid Build Coastguard Worker fe x, y;
711*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(&x, bytes);
712*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(&y, bytes + 32);
713*8fb009dcSAndroid Build Coastguard Worker
714*8fb009dcSAndroid Build Coastguard Worker ge_precomp *out = &multiples[i];
715*8fb009dcSAndroid Build Coastguard Worker fe_add(&out->yplusx, &y, &x);
716*8fb009dcSAndroid Build Coastguard Worker fe_sub(&out->yminusx, &y, &x);
717*8fb009dcSAndroid Build Coastguard Worker fe_mul_ltt(&out->xy2d, &x, &y);
718*8fb009dcSAndroid Build Coastguard Worker fe_mul_llt(&out->xy2d, &out->xy2d, &d2);
719*8fb009dcSAndroid Build Coastguard Worker }
720*8fb009dcSAndroid Build Coastguard Worker
721*8fb009dcSAndroid Build Coastguard Worker // See the comment above |k25519SmallPrecomp| about the structure of the
722*8fb009dcSAndroid Build Coastguard Worker // precomputed elements. This loop does 64 additions and 64 doublings to
723*8fb009dcSAndroid Build Coastguard Worker // calculate the result.
724*8fb009dcSAndroid Build Coastguard Worker ge_p3_0(h);
725*8fb009dcSAndroid Build Coastguard Worker
726*8fb009dcSAndroid Build Coastguard Worker for (i = 63; i < 64; i--) {
727*8fb009dcSAndroid Build Coastguard Worker unsigned j;
728*8fb009dcSAndroid Build Coastguard Worker signed char index = 0;
729*8fb009dcSAndroid Build Coastguard Worker
730*8fb009dcSAndroid Build Coastguard Worker for (j = 0; j < 4; j++) {
731*8fb009dcSAndroid Build Coastguard Worker const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7));
732*8fb009dcSAndroid Build Coastguard Worker index |= (bit << j);
733*8fb009dcSAndroid Build Coastguard Worker }
734*8fb009dcSAndroid Build Coastguard Worker
735*8fb009dcSAndroid Build Coastguard Worker ge_precomp e;
736*8fb009dcSAndroid Build Coastguard Worker ge_precomp_0(&e);
737*8fb009dcSAndroid Build Coastguard Worker
738*8fb009dcSAndroid Build Coastguard Worker for (j = 1; j < 16; j++) {
739*8fb009dcSAndroid Build Coastguard Worker cmov(&e, &multiples[j-1], 1&constant_time_eq_w(index, j));
740*8fb009dcSAndroid Build Coastguard Worker }
741*8fb009dcSAndroid Build Coastguard Worker
742*8fb009dcSAndroid Build Coastguard Worker ge_cached cached;
743*8fb009dcSAndroid Build Coastguard Worker ge_p1p1 r;
744*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&cached, h);
745*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&r, h, &cached);
746*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(h, &r);
747*8fb009dcSAndroid Build Coastguard Worker
748*8fb009dcSAndroid Build Coastguard Worker ge_madd(&r, h, &e);
749*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(h, &r);
750*8fb009dcSAndroid Build Coastguard Worker }
751*8fb009dcSAndroid Build Coastguard Worker }
752*8fb009dcSAndroid Build Coastguard Worker
753*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_SMALL)
754*8fb009dcSAndroid Build Coastguard Worker
x25519_ge_scalarmult_base(ge_p3 * h,const uint8_t a[32])755*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
756*8fb009dcSAndroid Build Coastguard Worker x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp);
757*8fb009dcSAndroid Build Coastguard Worker }
758*8fb009dcSAndroid Build Coastguard Worker
759*8fb009dcSAndroid Build Coastguard Worker #else
760*8fb009dcSAndroid Build Coastguard Worker
table_select(ge_precomp * t,const int pos,const signed char b)761*8fb009dcSAndroid Build Coastguard Worker static void table_select(ge_precomp *t, const int pos, const signed char b) {
762*8fb009dcSAndroid Build Coastguard Worker uint8_t bnegative = constant_time_msb_w(b);
763*8fb009dcSAndroid Build Coastguard Worker uint8_t babs = b - ((bnegative & b) << 1);
764*8fb009dcSAndroid Build Coastguard Worker
765*8fb009dcSAndroid Build Coastguard Worker uint8_t t_bytes[3][32] = {
766*8fb009dcSAndroid Build Coastguard Worker {constant_time_is_zero_w(b) & 1}, {constant_time_is_zero_w(b) & 1}, {0}};
767*8fb009dcSAndroid Build Coastguard Worker #if defined(__clang__) // materialize for vectorization, 6% speedup
768*8fb009dcSAndroid Build Coastguard Worker __asm__("" : "+m" (t_bytes) : /*no inputs*/);
769*8fb009dcSAndroid Build Coastguard Worker #endif
770*8fb009dcSAndroid Build Coastguard Worker static_assert(sizeof(t_bytes) == sizeof(k25519Precomp[pos][0]), "");
771*8fb009dcSAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
772*8fb009dcSAndroid Build Coastguard Worker constant_time_conditional_memxor(t_bytes, k25519Precomp[pos][i],
773*8fb009dcSAndroid Build Coastguard Worker sizeof(t_bytes),
774*8fb009dcSAndroid Build Coastguard Worker constant_time_eq_w(babs, 1 + i));
775*8fb009dcSAndroid Build Coastguard Worker }
776*8fb009dcSAndroid Build Coastguard Worker
777*8fb009dcSAndroid Build Coastguard Worker fe yplusx, yminusx, xy2d;
778*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(&yplusx, t_bytes[0]);
779*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(&yminusx, t_bytes[1]);
780*8fb009dcSAndroid Build Coastguard Worker fe_frombytes_strict(&xy2d, t_bytes[2]);
781*8fb009dcSAndroid Build Coastguard Worker
782*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&t->yplusx, &yplusx);
783*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&t->yminusx, &yminusx);
784*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&t->xy2d, &xy2d);
785*8fb009dcSAndroid Build Coastguard Worker
786*8fb009dcSAndroid Build Coastguard Worker ge_precomp minust;
787*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&minust.yplusx, &yminusx);
788*8fb009dcSAndroid Build Coastguard Worker fe_copy_lt(&minust.yminusx, &yplusx);
789*8fb009dcSAndroid Build Coastguard Worker fe_neg(&minust.xy2d, &xy2d);
790*8fb009dcSAndroid Build Coastguard Worker cmov(t, &minust, bnegative>>7);
791*8fb009dcSAndroid Build Coastguard Worker }
792*8fb009dcSAndroid Build Coastguard Worker
793*8fb009dcSAndroid Build Coastguard Worker // h = a * B
794*8fb009dcSAndroid Build Coastguard Worker // where a = a[0]+256*a[1]+...+256^31 a[31]
795*8fb009dcSAndroid Build Coastguard Worker // B is the Ed25519 base point (x,4/5) with x positive.
796*8fb009dcSAndroid Build Coastguard Worker //
797*8fb009dcSAndroid Build Coastguard Worker // Preconditions:
798*8fb009dcSAndroid Build Coastguard Worker // a[31] <= 127
x25519_ge_scalarmult_base(ge_p3 * h,const uint8_t a[32])799*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
800*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_FE25519_ADX)
801*8fb009dcSAndroid Build Coastguard Worker if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() &&
802*8fb009dcSAndroid Build Coastguard Worker CRYPTO_is_ADX_capable()) {
803*8fb009dcSAndroid Build Coastguard Worker uint8_t t[4][32];
804*8fb009dcSAndroid Build Coastguard Worker x25519_ge_scalarmult_base_adx(t, a);
805*8fb009dcSAndroid Build Coastguard Worker fiat_25519_from_bytes(h->X.v, t[0]);
806*8fb009dcSAndroid Build Coastguard Worker fiat_25519_from_bytes(h->Y.v, t[1]);
807*8fb009dcSAndroid Build Coastguard Worker fiat_25519_from_bytes(h->Z.v, t[2]);
808*8fb009dcSAndroid Build Coastguard Worker fiat_25519_from_bytes(h->T.v, t[3]);
809*8fb009dcSAndroid Build Coastguard Worker return;
810*8fb009dcSAndroid Build Coastguard Worker }
811*8fb009dcSAndroid Build Coastguard Worker #endif
812*8fb009dcSAndroid Build Coastguard Worker signed char e[64];
813*8fb009dcSAndroid Build Coastguard Worker signed char carry;
814*8fb009dcSAndroid Build Coastguard Worker ge_p1p1 r;
815*8fb009dcSAndroid Build Coastguard Worker ge_p2 s;
816*8fb009dcSAndroid Build Coastguard Worker ge_precomp t;
817*8fb009dcSAndroid Build Coastguard Worker int i;
818*8fb009dcSAndroid Build Coastguard Worker
819*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 32; ++i) {
820*8fb009dcSAndroid Build Coastguard Worker e[2 * i + 0] = (a[i] >> 0) & 15;
821*8fb009dcSAndroid Build Coastguard Worker e[2 * i + 1] = (a[i] >> 4) & 15;
822*8fb009dcSAndroid Build Coastguard Worker }
823*8fb009dcSAndroid Build Coastguard Worker // each e[i] is between 0 and 15
824*8fb009dcSAndroid Build Coastguard Worker // e[63] is between 0 and 7
825*8fb009dcSAndroid Build Coastguard Worker
826*8fb009dcSAndroid Build Coastguard Worker carry = 0;
827*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 63; ++i) {
828*8fb009dcSAndroid Build Coastguard Worker e[i] += carry;
829*8fb009dcSAndroid Build Coastguard Worker carry = e[i] + 8;
830*8fb009dcSAndroid Build Coastguard Worker carry >>= 4;
831*8fb009dcSAndroid Build Coastguard Worker e[i] -= carry << 4;
832*8fb009dcSAndroid Build Coastguard Worker }
833*8fb009dcSAndroid Build Coastguard Worker e[63] += carry;
834*8fb009dcSAndroid Build Coastguard Worker // each e[i] is between -8 and 8
835*8fb009dcSAndroid Build Coastguard Worker
836*8fb009dcSAndroid Build Coastguard Worker ge_p3_0(h);
837*8fb009dcSAndroid Build Coastguard Worker for (i = 1; i < 64; i += 2) {
838*8fb009dcSAndroid Build Coastguard Worker table_select(&t, i / 2, e[i]);
839*8fb009dcSAndroid Build Coastguard Worker ge_madd(&r, h, &t);
840*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(h, &r);
841*8fb009dcSAndroid Build Coastguard Worker }
842*8fb009dcSAndroid Build Coastguard Worker
843*8fb009dcSAndroid Build Coastguard Worker ge_p3_dbl(&r, h);
844*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(&s, &r);
845*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&r, &s);
846*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(&s, &r);
847*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&r, &s);
848*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(&s, &r);
849*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&r, &s);
850*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(h, &r);
851*8fb009dcSAndroid Build Coastguard Worker
852*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 64; i += 2) {
853*8fb009dcSAndroid Build Coastguard Worker table_select(&t, i / 2, e[i]);
854*8fb009dcSAndroid Build Coastguard Worker ge_madd(&r, h, &t);
855*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(h, &r);
856*8fb009dcSAndroid Build Coastguard Worker }
857*8fb009dcSAndroid Build Coastguard Worker }
858*8fb009dcSAndroid Build Coastguard Worker
859*8fb009dcSAndroid Build Coastguard Worker #endif
860*8fb009dcSAndroid Build Coastguard Worker
cmov_cached(ge_cached * t,ge_cached * u,uint8_t b)861*8fb009dcSAndroid Build Coastguard Worker static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) {
862*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->YplusX, &u->YplusX, b);
863*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->YminusX, &u->YminusX, b);
864*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->Z, &u->Z, b);
865*8fb009dcSAndroid Build Coastguard Worker fe_cmov(&t->T2d, &u->T2d, b);
866*8fb009dcSAndroid Build Coastguard Worker }
867*8fb009dcSAndroid Build Coastguard Worker
868*8fb009dcSAndroid Build Coastguard Worker // r = scalar * A.
869*8fb009dcSAndroid Build Coastguard Worker // where a = a[0]+256*a[1]+...+256^31 a[31].
x25519_ge_scalarmult(ge_p2 * r,const uint8_t * scalar,const ge_p3 * A)870*8fb009dcSAndroid Build Coastguard Worker void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) {
871*8fb009dcSAndroid Build Coastguard Worker ge_p2 Ai_p2[8];
872*8fb009dcSAndroid Build Coastguard Worker ge_cached Ai[16];
873*8fb009dcSAndroid Build Coastguard Worker ge_p1p1 t;
874*8fb009dcSAndroid Build Coastguard Worker
875*8fb009dcSAndroid Build Coastguard Worker ge_cached_0(&Ai[0]);
876*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[1], A);
877*8fb009dcSAndroid Build Coastguard Worker ge_p3_to_p2(&Ai_p2[1], A);
878*8fb009dcSAndroid Build Coastguard Worker
879*8fb009dcSAndroid Build Coastguard Worker unsigned i;
880*8fb009dcSAndroid Build Coastguard Worker for (i = 2; i < 16; i += 2) {
881*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, &Ai_p2[i / 2]);
882*8fb009dcSAndroid Build Coastguard Worker ge_p1p1_to_cached(&Ai[i], &t);
883*8fb009dcSAndroid Build Coastguard Worker if (i < 8) {
884*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(&Ai_p2[i], &t);
885*8fb009dcSAndroid Build Coastguard Worker }
886*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, A, &Ai[i]);
887*8fb009dcSAndroid Build Coastguard Worker ge_p1p1_to_cached(&Ai[i + 1], &t);
888*8fb009dcSAndroid Build Coastguard Worker if (i < 7) {
889*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t);
890*8fb009dcSAndroid Build Coastguard Worker }
891*8fb009dcSAndroid Build Coastguard Worker }
892*8fb009dcSAndroid Build Coastguard Worker
893*8fb009dcSAndroid Build Coastguard Worker ge_p2_0(r);
894*8fb009dcSAndroid Build Coastguard Worker ge_p3 u;
895*8fb009dcSAndroid Build Coastguard Worker
896*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 256; i += 4) {
897*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, r);
898*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(r, &t);
899*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, r);
900*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(r, &t);
901*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, r);
902*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(r, &t);
903*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, r);
904*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
905*8fb009dcSAndroid Build Coastguard Worker
906*8fb009dcSAndroid Build Coastguard Worker uint8_t index = scalar[31 - i/8];
907*8fb009dcSAndroid Build Coastguard Worker index >>= 4 - (i & 4);
908*8fb009dcSAndroid Build Coastguard Worker index &= 0xf;
909*8fb009dcSAndroid Build Coastguard Worker
910*8fb009dcSAndroid Build Coastguard Worker unsigned j;
911*8fb009dcSAndroid Build Coastguard Worker ge_cached selected;
912*8fb009dcSAndroid Build Coastguard Worker ge_cached_0(&selected);
913*8fb009dcSAndroid Build Coastguard Worker for (j = 0; j < 16; j++) {
914*8fb009dcSAndroid Build Coastguard Worker cmov_cached(&selected, &Ai[j], 1&constant_time_eq_w(index, j));
915*8fb009dcSAndroid Build Coastguard Worker }
916*8fb009dcSAndroid Build Coastguard Worker
917*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &u, &selected);
918*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(r, &t);
919*8fb009dcSAndroid Build Coastguard Worker }
920*8fb009dcSAndroid Build Coastguard Worker }
921*8fb009dcSAndroid Build Coastguard Worker
slide(signed char * r,const uint8_t * a)922*8fb009dcSAndroid Build Coastguard Worker static void slide(signed char *r, const uint8_t *a) {
923*8fb009dcSAndroid Build Coastguard Worker int i;
924*8fb009dcSAndroid Build Coastguard Worker int b;
925*8fb009dcSAndroid Build Coastguard Worker int k;
926*8fb009dcSAndroid Build Coastguard Worker
927*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 256; ++i) {
928*8fb009dcSAndroid Build Coastguard Worker r[i] = 1 & (a[i >> 3] >> (i & 7));
929*8fb009dcSAndroid Build Coastguard Worker }
930*8fb009dcSAndroid Build Coastguard Worker
931*8fb009dcSAndroid Build Coastguard Worker for (i = 0; i < 256; ++i) {
932*8fb009dcSAndroid Build Coastguard Worker if (r[i]) {
933*8fb009dcSAndroid Build Coastguard Worker for (b = 1; b <= 6 && i + b < 256; ++b) {
934*8fb009dcSAndroid Build Coastguard Worker if (r[i + b]) {
935*8fb009dcSAndroid Build Coastguard Worker if (r[i] + (r[i + b] << b) <= 15) {
936*8fb009dcSAndroid Build Coastguard Worker r[i] += r[i + b] << b;
937*8fb009dcSAndroid Build Coastguard Worker r[i + b] = 0;
938*8fb009dcSAndroid Build Coastguard Worker } else if (r[i] - (r[i + b] << b) >= -15) {
939*8fb009dcSAndroid Build Coastguard Worker r[i] -= r[i + b] << b;
940*8fb009dcSAndroid Build Coastguard Worker for (k = i + b; k < 256; ++k) {
941*8fb009dcSAndroid Build Coastguard Worker if (!r[k]) {
942*8fb009dcSAndroid Build Coastguard Worker r[k] = 1;
943*8fb009dcSAndroid Build Coastguard Worker break;
944*8fb009dcSAndroid Build Coastguard Worker }
945*8fb009dcSAndroid Build Coastguard Worker r[k] = 0;
946*8fb009dcSAndroid Build Coastguard Worker }
947*8fb009dcSAndroid Build Coastguard Worker } else {
948*8fb009dcSAndroid Build Coastguard Worker break;
949*8fb009dcSAndroid Build Coastguard Worker }
950*8fb009dcSAndroid Build Coastguard Worker }
951*8fb009dcSAndroid Build Coastguard Worker }
952*8fb009dcSAndroid Build Coastguard Worker }
953*8fb009dcSAndroid Build Coastguard Worker }
954*8fb009dcSAndroid Build Coastguard Worker }
955*8fb009dcSAndroid Build Coastguard Worker
956*8fb009dcSAndroid Build Coastguard Worker // r = a * A + b * B
957*8fb009dcSAndroid Build Coastguard Worker // where a = a[0]+256*a[1]+...+256^31 a[31].
958*8fb009dcSAndroid Build Coastguard Worker // and b = b[0]+256*b[1]+...+256^31 b[31].
959*8fb009dcSAndroid Build Coastguard Worker // B is the Ed25519 base point (x,4/5) with x positive.
ge_double_scalarmult_vartime(ge_p2 * r,const uint8_t * a,const ge_p3 * A,const uint8_t * b)960*8fb009dcSAndroid Build Coastguard Worker static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
961*8fb009dcSAndroid Build Coastguard Worker const ge_p3 *A, const uint8_t *b) {
962*8fb009dcSAndroid Build Coastguard Worker signed char aslide[256];
963*8fb009dcSAndroid Build Coastguard Worker signed char bslide[256];
964*8fb009dcSAndroid Build Coastguard Worker ge_cached Ai[8]; // A,3A,5A,7A,9A,11A,13A,15A
965*8fb009dcSAndroid Build Coastguard Worker ge_p1p1 t;
966*8fb009dcSAndroid Build Coastguard Worker ge_p3 u;
967*8fb009dcSAndroid Build Coastguard Worker ge_p3 A2;
968*8fb009dcSAndroid Build Coastguard Worker int i;
969*8fb009dcSAndroid Build Coastguard Worker
970*8fb009dcSAndroid Build Coastguard Worker slide(aslide, a);
971*8fb009dcSAndroid Build Coastguard Worker slide(bslide, b);
972*8fb009dcSAndroid Build Coastguard Worker
973*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[0], A);
974*8fb009dcSAndroid Build Coastguard Worker ge_p3_dbl(&t, A);
975*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&A2, &t);
976*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[0]);
977*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
978*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[1], &u);
979*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[1]);
980*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
981*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[2], &u);
982*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[2]);
983*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
984*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[3], &u);
985*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[3]);
986*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
987*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[4], &u);
988*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[4]);
989*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
990*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[5], &u);
991*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[5]);
992*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
993*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[6], &u);
994*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &A2, &Ai[6]);
995*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
996*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p3_to_cached(&Ai[7], &u);
997*8fb009dcSAndroid Build Coastguard Worker
998*8fb009dcSAndroid Build Coastguard Worker ge_p2_0(r);
999*8fb009dcSAndroid Build Coastguard Worker
1000*8fb009dcSAndroid Build Coastguard Worker for (i = 255; i >= 0; --i) {
1001*8fb009dcSAndroid Build Coastguard Worker if (aslide[i] || bslide[i]) {
1002*8fb009dcSAndroid Build Coastguard Worker break;
1003*8fb009dcSAndroid Build Coastguard Worker }
1004*8fb009dcSAndroid Build Coastguard Worker }
1005*8fb009dcSAndroid Build Coastguard Worker
1006*8fb009dcSAndroid Build Coastguard Worker for (; i >= 0; --i) {
1007*8fb009dcSAndroid Build Coastguard Worker ge_p2_dbl(&t, r);
1008*8fb009dcSAndroid Build Coastguard Worker
1009*8fb009dcSAndroid Build Coastguard Worker if (aslide[i] > 0) {
1010*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
1011*8fb009dcSAndroid Build Coastguard Worker x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]);
1012*8fb009dcSAndroid Build Coastguard Worker } else if (aslide[i] < 0) {
1013*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
1014*8fb009dcSAndroid Build Coastguard Worker x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
1015*8fb009dcSAndroid Build Coastguard Worker }
1016*8fb009dcSAndroid Build Coastguard Worker
1017*8fb009dcSAndroid Build Coastguard Worker if (bslide[i] > 0) {
1018*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
1019*8fb009dcSAndroid Build Coastguard Worker ge_madd(&t, &u, &Bi[bslide[i] / 2]);
1020*8fb009dcSAndroid Build Coastguard Worker } else if (bslide[i] < 0) {
1021*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p3(&u, &t);
1022*8fb009dcSAndroid Build Coastguard Worker ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
1023*8fb009dcSAndroid Build Coastguard Worker }
1024*8fb009dcSAndroid Build Coastguard Worker
1025*8fb009dcSAndroid Build Coastguard Worker x25519_ge_p1p1_to_p2(r, &t);
1026*8fb009dcSAndroid Build Coastguard Worker }
1027*8fb009dcSAndroid Build Coastguard Worker }
1028*8fb009dcSAndroid Build Coastguard Worker
1029*8fb009dcSAndroid Build Coastguard Worker // int64_lshift21 returns |a << 21| but is defined when shifting bits into the
1030*8fb009dcSAndroid Build Coastguard Worker // sign bit. This works around a language flaw in C.
int64_lshift21(int64_t a)1031*8fb009dcSAndroid Build Coastguard Worker static inline int64_t int64_lshift21(int64_t a) {
1032*8fb009dcSAndroid Build Coastguard Worker return (int64_t)((uint64_t)a << 21);
1033*8fb009dcSAndroid Build Coastguard Worker }
1034*8fb009dcSAndroid Build Coastguard Worker
1035*8fb009dcSAndroid Build Coastguard Worker // The set of scalars is \Z/l
1036*8fb009dcSAndroid Build Coastguard Worker // where l = 2^252 + 27742317777372353535851937790883648493.
1037*8fb009dcSAndroid Build Coastguard Worker
1038*8fb009dcSAndroid Build Coastguard Worker // Input:
1039*8fb009dcSAndroid Build Coastguard Worker // s[0]+256*s[1]+...+256^63*s[63] = s
1040*8fb009dcSAndroid Build Coastguard Worker //
1041*8fb009dcSAndroid Build Coastguard Worker // Output:
1042*8fb009dcSAndroid Build Coastguard Worker // s[0]+256*s[1]+...+256^31*s[31] = s mod l
1043*8fb009dcSAndroid Build Coastguard Worker // where l = 2^252 + 27742317777372353535851937790883648493.
1044*8fb009dcSAndroid Build Coastguard Worker // Overwrites s in place.
x25519_sc_reduce(uint8_t s[64])1045*8fb009dcSAndroid Build Coastguard Worker void x25519_sc_reduce(uint8_t s[64]) {
1046*8fb009dcSAndroid Build Coastguard Worker int64_t s0 = 2097151 & load_3(s);
1047*8fb009dcSAndroid Build Coastguard Worker int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
1048*8fb009dcSAndroid Build Coastguard Worker int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
1049*8fb009dcSAndroid Build Coastguard Worker int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
1050*8fb009dcSAndroid Build Coastguard Worker int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
1051*8fb009dcSAndroid Build Coastguard Worker int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
1052*8fb009dcSAndroid Build Coastguard Worker int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
1053*8fb009dcSAndroid Build Coastguard Worker int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
1054*8fb009dcSAndroid Build Coastguard Worker int64_t s8 = 2097151 & load_3(s + 21);
1055*8fb009dcSAndroid Build Coastguard Worker int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
1056*8fb009dcSAndroid Build Coastguard Worker int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
1057*8fb009dcSAndroid Build Coastguard Worker int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
1058*8fb009dcSAndroid Build Coastguard Worker int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
1059*8fb009dcSAndroid Build Coastguard Worker int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
1060*8fb009dcSAndroid Build Coastguard Worker int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
1061*8fb009dcSAndroid Build Coastguard Worker int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
1062*8fb009dcSAndroid Build Coastguard Worker int64_t s16 = 2097151 & load_3(s + 42);
1063*8fb009dcSAndroid Build Coastguard Worker int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
1064*8fb009dcSAndroid Build Coastguard Worker int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
1065*8fb009dcSAndroid Build Coastguard Worker int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
1066*8fb009dcSAndroid Build Coastguard Worker int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
1067*8fb009dcSAndroid Build Coastguard Worker int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
1068*8fb009dcSAndroid Build Coastguard Worker int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
1069*8fb009dcSAndroid Build Coastguard Worker int64_t s23 = (load_4(s + 60) >> 3);
1070*8fb009dcSAndroid Build Coastguard Worker int64_t carry0;
1071*8fb009dcSAndroid Build Coastguard Worker int64_t carry1;
1072*8fb009dcSAndroid Build Coastguard Worker int64_t carry2;
1073*8fb009dcSAndroid Build Coastguard Worker int64_t carry3;
1074*8fb009dcSAndroid Build Coastguard Worker int64_t carry4;
1075*8fb009dcSAndroid Build Coastguard Worker int64_t carry5;
1076*8fb009dcSAndroid Build Coastguard Worker int64_t carry6;
1077*8fb009dcSAndroid Build Coastguard Worker int64_t carry7;
1078*8fb009dcSAndroid Build Coastguard Worker int64_t carry8;
1079*8fb009dcSAndroid Build Coastguard Worker int64_t carry9;
1080*8fb009dcSAndroid Build Coastguard Worker int64_t carry10;
1081*8fb009dcSAndroid Build Coastguard Worker int64_t carry11;
1082*8fb009dcSAndroid Build Coastguard Worker int64_t carry12;
1083*8fb009dcSAndroid Build Coastguard Worker int64_t carry13;
1084*8fb009dcSAndroid Build Coastguard Worker int64_t carry14;
1085*8fb009dcSAndroid Build Coastguard Worker int64_t carry15;
1086*8fb009dcSAndroid Build Coastguard Worker int64_t carry16;
1087*8fb009dcSAndroid Build Coastguard Worker
1088*8fb009dcSAndroid Build Coastguard Worker s11 += s23 * 666643;
1089*8fb009dcSAndroid Build Coastguard Worker s12 += s23 * 470296;
1090*8fb009dcSAndroid Build Coastguard Worker s13 += s23 * 654183;
1091*8fb009dcSAndroid Build Coastguard Worker s14 -= s23 * 997805;
1092*8fb009dcSAndroid Build Coastguard Worker s15 += s23 * 136657;
1093*8fb009dcSAndroid Build Coastguard Worker s16 -= s23 * 683901;
1094*8fb009dcSAndroid Build Coastguard Worker s23 = 0;
1095*8fb009dcSAndroid Build Coastguard Worker
1096*8fb009dcSAndroid Build Coastguard Worker s10 += s22 * 666643;
1097*8fb009dcSAndroid Build Coastguard Worker s11 += s22 * 470296;
1098*8fb009dcSAndroid Build Coastguard Worker s12 += s22 * 654183;
1099*8fb009dcSAndroid Build Coastguard Worker s13 -= s22 * 997805;
1100*8fb009dcSAndroid Build Coastguard Worker s14 += s22 * 136657;
1101*8fb009dcSAndroid Build Coastguard Worker s15 -= s22 * 683901;
1102*8fb009dcSAndroid Build Coastguard Worker s22 = 0;
1103*8fb009dcSAndroid Build Coastguard Worker
1104*8fb009dcSAndroid Build Coastguard Worker s9 += s21 * 666643;
1105*8fb009dcSAndroid Build Coastguard Worker s10 += s21 * 470296;
1106*8fb009dcSAndroid Build Coastguard Worker s11 += s21 * 654183;
1107*8fb009dcSAndroid Build Coastguard Worker s12 -= s21 * 997805;
1108*8fb009dcSAndroid Build Coastguard Worker s13 += s21 * 136657;
1109*8fb009dcSAndroid Build Coastguard Worker s14 -= s21 * 683901;
1110*8fb009dcSAndroid Build Coastguard Worker s21 = 0;
1111*8fb009dcSAndroid Build Coastguard Worker
1112*8fb009dcSAndroid Build Coastguard Worker s8 += s20 * 666643;
1113*8fb009dcSAndroid Build Coastguard Worker s9 += s20 * 470296;
1114*8fb009dcSAndroid Build Coastguard Worker s10 += s20 * 654183;
1115*8fb009dcSAndroid Build Coastguard Worker s11 -= s20 * 997805;
1116*8fb009dcSAndroid Build Coastguard Worker s12 += s20 * 136657;
1117*8fb009dcSAndroid Build Coastguard Worker s13 -= s20 * 683901;
1118*8fb009dcSAndroid Build Coastguard Worker s20 = 0;
1119*8fb009dcSAndroid Build Coastguard Worker
1120*8fb009dcSAndroid Build Coastguard Worker s7 += s19 * 666643;
1121*8fb009dcSAndroid Build Coastguard Worker s8 += s19 * 470296;
1122*8fb009dcSAndroid Build Coastguard Worker s9 += s19 * 654183;
1123*8fb009dcSAndroid Build Coastguard Worker s10 -= s19 * 997805;
1124*8fb009dcSAndroid Build Coastguard Worker s11 += s19 * 136657;
1125*8fb009dcSAndroid Build Coastguard Worker s12 -= s19 * 683901;
1126*8fb009dcSAndroid Build Coastguard Worker s19 = 0;
1127*8fb009dcSAndroid Build Coastguard Worker
1128*8fb009dcSAndroid Build Coastguard Worker s6 += s18 * 666643;
1129*8fb009dcSAndroid Build Coastguard Worker s7 += s18 * 470296;
1130*8fb009dcSAndroid Build Coastguard Worker s8 += s18 * 654183;
1131*8fb009dcSAndroid Build Coastguard Worker s9 -= s18 * 997805;
1132*8fb009dcSAndroid Build Coastguard Worker s10 += s18 * 136657;
1133*8fb009dcSAndroid Build Coastguard Worker s11 -= s18 * 683901;
1134*8fb009dcSAndroid Build Coastguard Worker s18 = 0;
1135*8fb009dcSAndroid Build Coastguard Worker
1136*8fb009dcSAndroid Build Coastguard Worker carry6 = (s6 + (1 << 20)) >> 21;
1137*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1138*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1139*8fb009dcSAndroid Build Coastguard Worker carry8 = (s8 + (1 << 20)) >> 21;
1140*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1141*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1142*8fb009dcSAndroid Build Coastguard Worker carry10 = (s10 + (1 << 20)) >> 21;
1143*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1144*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1145*8fb009dcSAndroid Build Coastguard Worker carry12 = (s12 + (1 << 20)) >> 21;
1146*8fb009dcSAndroid Build Coastguard Worker s13 += carry12;
1147*8fb009dcSAndroid Build Coastguard Worker s12 -= int64_lshift21(carry12);
1148*8fb009dcSAndroid Build Coastguard Worker carry14 = (s14 + (1 << 20)) >> 21;
1149*8fb009dcSAndroid Build Coastguard Worker s15 += carry14;
1150*8fb009dcSAndroid Build Coastguard Worker s14 -= int64_lshift21(carry14);
1151*8fb009dcSAndroid Build Coastguard Worker carry16 = (s16 + (1 << 20)) >> 21;
1152*8fb009dcSAndroid Build Coastguard Worker s17 += carry16;
1153*8fb009dcSAndroid Build Coastguard Worker s16 -= int64_lshift21(carry16);
1154*8fb009dcSAndroid Build Coastguard Worker
1155*8fb009dcSAndroid Build Coastguard Worker carry7 = (s7 + (1 << 20)) >> 21;
1156*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1157*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1158*8fb009dcSAndroid Build Coastguard Worker carry9 = (s9 + (1 << 20)) >> 21;
1159*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1160*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1161*8fb009dcSAndroid Build Coastguard Worker carry11 = (s11 + (1 << 20)) >> 21;
1162*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1163*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1164*8fb009dcSAndroid Build Coastguard Worker carry13 = (s13 + (1 << 20)) >> 21;
1165*8fb009dcSAndroid Build Coastguard Worker s14 += carry13;
1166*8fb009dcSAndroid Build Coastguard Worker s13 -= int64_lshift21(carry13);
1167*8fb009dcSAndroid Build Coastguard Worker carry15 = (s15 + (1 << 20)) >> 21;
1168*8fb009dcSAndroid Build Coastguard Worker s16 += carry15;
1169*8fb009dcSAndroid Build Coastguard Worker s15 -= int64_lshift21(carry15);
1170*8fb009dcSAndroid Build Coastguard Worker
1171*8fb009dcSAndroid Build Coastguard Worker s5 += s17 * 666643;
1172*8fb009dcSAndroid Build Coastguard Worker s6 += s17 * 470296;
1173*8fb009dcSAndroid Build Coastguard Worker s7 += s17 * 654183;
1174*8fb009dcSAndroid Build Coastguard Worker s8 -= s17 * 997805;
1175*8fb009dcSAndroid Build Coastguard Worker s9 += s17 * 136657;
1176*8fb009dcSAndroid Build Coastguard Worker s10 -= s17 * 683901;
1177*8fb009dcSAndroid Build Coastguard Worker s17 = 0;
1178*8fb009dcSAndroid Build Coastguard Worker
1179*8fb009dcSAndroid Build Coastguard Worker s4 += s16 * 666643;
1180*8fb009dcSAndroid Build Coastguard Worker s5 += s16 * 470296;
1181*8fb009dcSAndroid Build Coastguard Worker s6 += s16 * 654183;
1182*8fb009dcSAndroid Build Coastguard Worker s7 -= s16 * 997805;
1183*8fb009dcSAndroid Build Coastguard Worker s8 += s16 * 136657;
1184*8fb009dcSAndroid Build Coastguard Worker s9 -= s16 * 683901;
1185*8fb009dcSAndroid Build Coastguard Worker s16 = 0;
1186*8fb009dcSAndroid Build Coastguard Worker
1187*8fb009dcSAndroid Build Coastguard Worker s3 += s15 * 666643;
1188*8fb009dcSAndroid Build Coastguard Worker s4 += s15 * 470296;
1189*8fb009dcSAndroid Build Coastguard Worker s5 += s15 * 654183;
1190*8fb009dcSAndroid Build Coastguard Worker s6 -= s15 * 997805;
1191*8fb009dcSAndroid Build Coastguard Worker s7 += s15 * 136657;
1192*8fb009dcSAndroid Build Coastguard Worker s8 -= s15 * 683901;
1193*8fb009dcSAndroid Build Coastguard Worker s15 = 0;
1194*8fb009dcSAndroid Build Coastguard Worker
1195*8fb009dcSAndroid Build Coastguard Worker s2 += s14 * 666643;
1196*8fb009dcSAndroid Build Coastguard Worker s3 += s14 * 470296;
1197*8fb009dcSAndroid Build Coastguard Worker s4 += s14 * 654183;
1198*8fb009dcSAndroid Build Coastguard Worker s5 -= s14 * 997805;
1199*8fb009dcSAndroid Build Coastguard Worker s6 += s14 * 136657;
1200*8fb009dcSAndroid Build Coastguard Worker s7 -= s14 * 683901;
1201*8fb009dcSAndroid Build Coastguard Worker s14 = 0;
1202*8fb009dcSAndroid Build Coastguard Worker
1203*8fb009dcSAndroid Build Coastguard Worker s1 += s13 * 666643;
1204*8fb009dcSAndroid Build Coastguard Worker s2 += s13 * 470296;
1205*8fb009dcSAndroid Build Coastguard Worker s3 += s13 * 654183;
1206*8fb009dcSAndroid Build Coastguard Worker s4 -= s13 * 997805;
1207*8fb009dcSAndroid Build Coastguard Worker s5 += s13 * 136657;
1208*8fb009dcSAndroid Build Coastguard Worker s6 -= s13 * 683901;
1209*8fb009dcSAndroid Build Coastguard Worker s13 = 0;
1210*8fb009dcSAndroid Build Coastguard Worker
1211*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1212*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1213*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1214*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1215*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1216*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1217*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1218*8fb009dcSAndroid Build Coastguard Worker
1219*8fb009dcSAndroid Build Coastguard Worker carry0 = (s0 + (1 << 20)) >> 21;
1220*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1221*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1222*8fb009dcSAndroid Build Coastguard Worker carry2 = (s2 + (1 << 20)) >> 21;
1223*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1224*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1225*8fb009dcSAndroid Build Coastguard Worker carry4 = (s4 + (1 << 20)) >> 21;
1226*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1227*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1228*8fb009dcSAndroid Build Coastguard Worker carry6 = (s6 + (1 << 20)) >> 21;
1229*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1230*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1231*8fb009dcSAndroid Build Coastguard Worker carry8 = (s8 + (1 << 20)) >> 21;
1232*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1233*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1234*8fb009dcSAndroid Build Coastguard Worker carry10 = (s10 + (1 << 20)) >> 21;
1235*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1236*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1237*8fb009dcSAndroid Build Coastguard Worker
1238*8fb009dcSAndroid Build Coastguard Worker carry1 = (s1 + (1 << 20)) >> 21;
1239*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1240*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1241*8fb009dcSAndroid Build Coastguard Worker carry3 = (s3 + (1 << 20)) >> 21;
1242*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1243*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1244*8fb009dcSAndroid Build Coastguard Worker carry5 = (s5 + (1 << 20)) >> 21;
1245*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1246*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1247*8fb009dcSAndroid Build Coastguard Worker carry7 = (s7 + (1 << 20)) >> 21;
1248*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1249*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1250*8fb009dcSAndroid Build Coastguard Worker carry9 = (s9 + (1 << 20)) >> 21;
1251*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1252*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1253*8fb009dcSAndroid Build Coastguard Worker carry11 = (s11 + (1 << 20)) >> 21;
1254*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1255*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1256*8fb009dcSAndroid Build Coastguard Worker
1257*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1258*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1259*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1260*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1261*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1262*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1263*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1264*8fb009dcSAndroid Build Coastguard Worker
1265*8fb009dcSAndroid Build Coastguard Worker carry0 = s0 >> 21;
1266*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1267*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1268*8fb009dcSAndroid Build Coastguard Worker carry1 = s1 >> 21;
1269*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1270*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1271*8fb009dcSAndroid Build Coastguard Worker carry2 = s2 >> 21;
1272*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1273*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1274*8fb009dcSAndroid Build Coastguard Worker carry3 = s3 >> 21;
1275*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1276*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1277*8fb009dcSAndroid Build Coastguard Worker carry4 = s4 >> 21;
1278*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1279*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1280*8fb009dcSAndroid Build Coastguard Worker carry5 = s5 >> 21;
1281*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1282*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1283*8fb009dcSAndroid Build Coastguard Worker carry6 = s6 >> 21;
1284*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1285*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1286*8fb009dcSAndroid Build Coastguard Worker carry7 = s7 >> 21;
1287*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1288*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1289*8fb009dcSAndroid Build Coastguard Worker carry8 = s8 >> 21;
1290*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1291*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1292*8fb009dcSAndroid Build Coastguard Worker carry9 = s9 >> 21;
1293*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1294*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1295*8fb009dcSAndroid Build Coastguard Worker carry10 = s10 >> 21;
1296*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1297*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1298*8fb009dcSAndroid Build Coastguard Worker carry11 = s11 >> 21;
1299*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1300*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1301*8fb009dcSAndroid Build Coastguard Worker
1302*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1303*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1304*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1305*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1306*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1307*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1308*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1309*8fb009dcSAndroid Build Coastguard Worker
1310*8fb009dcSAndroid Build Coastguard Worker carry0 = s0 >> 21;
1311*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1312*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1313*8fb009dcSAndroid Build Coastguard Worker carry1 = s1 >> 21;
1314*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1315*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1316*8fb009dcSAndroid Build Coastguard Worker carry2 = s2 >> 21;
1317*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1318*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1319*8fb009dcSAndroid Build Coastguard Worker carry3 = s3 >> 21;
1320*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1321*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1322*8fb009dcSAndroid Build Coastguard Worker carry4 = s4 >> 21;
1323*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1324*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1325*8fb009dcSAndroid Build Coastguard Worker carry5 = s5 >> 21;
1326*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1327*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1328*8fb009dcSAndroid Build Coastguard Worker carry6 = s6 >> 21;
1329*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1330*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1331*8fb009dcSAndroid Build Coastguard Worker carry7 = s7 >> 21;
1332*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1333*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1334*8fb009dcSAndroid Build Coastguard Worker carry8 = s8 >> 21;
1335*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1336*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1337*8fb009dcSAndroid Build Coastguard Worker carry9 = s9 >> 21;
1338*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1339*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1340*8fb009dcSAndroid Build Coastguard Worker carry10 = s10 >> 21;
1341*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1342*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1343*8fb009dcSAndroid Build Coastguard Worker
1344*8fb009dcSAndroid Build Coastguard Worker s[0] = s0 >> 0;
1345*8fb009dcSAndroid Build Coastguard Worker s[1] = s0 >> 8;
1346*8fb009dcSAndroid Build Coastguard Worker s[2] = (s0 >> 16) | (s1 << 5);
1347*8fb009dcSAndroid Build Coastguard Worker s[3] = s1 >> 3;
1348*8fb009dcSAndroid Build Coastguard Worker s[4] = s1 >> 11;
1349*8fb009dcSAndroid Build Coastguard Worker s[5] = (s1 >> 19) | (s2 << 2);
1350*8fb009dcSAndroid Build Coastguard Worker s[6] = s2 >> 6;
1351*8fb009dcSAndroid Build Coastguard Worker s[7] = (s2 >> 14) | (s3 << 7);
1352*8fb009dcSAndroid Build Coastguard Worker s[8] = s3 >> 1;
1353*8fb009dcSAndroid Build Coastguard Worker s[9] = s3 >> 9;
1354*8fb009dcSAndroid Build Coastguard Worker s[10] = (s3 >> 17) | (s4 << 4);
1355*8fb009dcSAndroid Build Coastguard Worker s[11] = s4 >> 4;
1356*8fb009dcSAndroid Build Coastguard Worker s[12] = s4 >> 12;
1357*8fb009dcSAndroid Build Coastguard Worker s[13] = (s4 >> 20) | (s5 << 1);
1358*8fb009dcSAndroid Build Coastguard Worker s[14] = s5 >> 7;
1359*8fb009dcSAndroid Build Coastguard Worker s[15] = (s5 >> 15) | (s6 << 6);
1360*8fb009dcSAndroid Build Coastguard Worker s[16] = s6 >> 2;
1361*8fb009dcSAndroid Build Coastguard Worker s[17] = s6 >> 10;
1362*8fb009dcSAndroid Build Coastguard Worker s[18] = (s6 >> 18) | (s7 << 3);
1363*8fb009dcSAndroid Build Coastguard Worker s[19] = s7 >> 5;
1364*8fb009dcSAndroid Build Coastguard Worker s[20] = s7 >> 13;
1365*8fb009dcSAndroid Build Coastguard Worker s[21] = s8 >> 0;
1366*8fb009dcSAndroid Build Coastguard Worker s[22] = s8 >> 8;
1367*8fb009dcSAndroid Build Coastguard Worker s[23] = (s8 >> 16) | (s9 << 5);
1368*8fb009dcSAndroid Build Coastguard Worker s[24] = s9 >> 3;
1369*8fb009dcSAndroid Build Coastguard Worker s[25] = s9 >> 11;
1370*8fb009dcSAndroid Build Coastguard Worker s[26] = (s9 >> 19) | (s10 << 2);
1371*8fb009dcSAndroid Build Coastguard Worker s[27] = s10 >> 6;
1372*8fb009dcSAndroid Build Coastguard Worker s[28] = (s10 >> 14) | (s11 << 7);
1373*8fb009dcSAndroid Build Coastguard Worker s[29] = s11 >> 1;
1374*8fb009dcSAndroid Build Coastguard Worker s[30] = s11 >> 9;
1375*8fb009dcSAndroid Build Coastguard Worker s[31] = s11 >> 17;
1376*8fb009dcSAndroid Build Coastguard Worker }
1377*8fb009dcSAndroid Build Coastguard Worker
1378*8fb009dcSAndroid Build Coastguard Worker // Input:
1379*8fb009dcSAndroid Build Coastguard Worker // a[0]+256*a[1]+...+256^31*a[31] = a
1380*8fb009dcSAndroid Build Coastguard Worker // b[0]+256*b[1]+...+256^31*b[31] = b
1381*8fb009dcSAndroid Build Coastguard Worker // c[0]+256*c[1]+...+256^31*c[31] = c
1382*8fb009dcSAndroid Build Coastguard Worker //
1383*8fb009dcSAndroid Build Coastguard Worker // Output:
1384*8fb009dcSAndroid Build Coastguard Worker // s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
1385*8fb009dcSAndroid Build Coastguard Worker // where l = 2^252 + 27742317777372353535851937790883648493.
sc_muladd(uint8_t * s,const uint8_t * a,const uint8_t * b,const uint8_t * c)1386*8fb009dcSAndroid Build Coastguard Worker static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
1387*8fb009dcSAndroid Build Coastguard Worker const uint8_t *c) {
1388*8fb009dcSAndroid Build Coastguard Worker int64_t a0 = 2097151 & load_3(a);
1389*8fb009dcSAndroid Build Coastguard Worker int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
1390*8fb009dcSAndroid Build Coastguard Worker int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
1391*8fb009dcSAndroid Build Coastguard Worker int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
1392*8fb009dcSAndroid Build Coastguard Worker int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
1393*8fb009dcSAndroid Build Coastguard Worker int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
1394*8fb009dcSAndroid Build Coastguard Worker int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
1395*8fb009dcSAndroid Build Coastguard Worker int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
1396*8fb009dcSAndroid Build Coastguard Worker int64_t a8 = 2097151 & load_3(a + 21);
1397*8fb009dcSAndroid Build Coastguard Worker int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
1398*8fb009dcSAndroid Build Coastguard Worker int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
1399*8fb009dcSAndroid Build Coastguard Worker int64_t a11 = (load_4(a + 28) >> 7);
1400*8fb009dcSAndroid Build Coastguard Worker int64_t b0 = 2097151 & load_3(b);
1401*8fb009dcSAndroid Build Coastguard Worker int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
1402*8fb009dcSAndroid Build Coastguard Worker int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
1403*8fb009dcSAndroid Build Coastguard Worker int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
1404*8fb009dcSAndroid Build Coastguard Worker int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
1405*8fb009dcSAndroid Build Coastguard Worker int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
1406*8fb009dcSAndroid Build Coastguard Worker int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
1407*8fb009dcSAndroid Build Coastguard Worker int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
1408*8fb009dcSAndroid Build Coastguard Worker int64_t b8 = 2097151 & load_3(b + 21);
1409*8fb009dcSAndroid Build Coastguard Worker int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
1410*8fb009dcSAndroid Build Coastguard Worker int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
1411*8fb009dcSAndroid Build Coastguard Worker int64_t b11 = (load_4(b + 28) >> 7);
1412*8fb009dcSAndroid Build Coastguard Worker int64_t c0 = 2097151 & load_3(c);
1413*8fb009dcSAndroid Build Coastguard Worker int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
1414*8fb009dcSAndroid Build Coastguard Worker int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
1415*8fb009dcSAndroid Build Coastguard Worker int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
1416*8fb009dcSAndroid Build Coastguard Worker int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
1417*8fb009dcSAndroid Build Coastguard Worker int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
1418*8fb009dcSAndroid Build Coastguard Worker int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
1419*8fb009dcSAndroid Build Coastguard Worker int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
1420*8fb009dcSAndroid Build Coastguard Worker int64_t c8 = 2097151 & load_3(c + 21);
1421*8fb009dcSAndroid Build Coastguard Worker int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
1422*8fb009dcSAndroid Build Coastguard Worker int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
1423*8fb009dcSAndroid Build Coastguard Worker int64_t c11 = (load_4(c + 28) >> 7);
1424*8fb009dcSAndroid Build Coastguard Worker int64_t s0;
1425*8fb009dcSAndroid Build Coastguard Worker int64_t s1;
1426*8fb009dcSAndroid Build Coastguard Worker int64_t s2;
1427*8fb009dcSAndroid Build Coastguard Worker int64_t s3;
1428*8fb009dcSAndroid Build Coastguard Worker int64_t s4;
1429*8fb009dcSAndroid Build Coastguard Worker int64_t s5;
1430*8fb009dcSAndroid Build Coastguard Worker int64_t s6;
1431*8fb009dcSAndroid Build Coastguard Worker int64_t s7;
1432*8fb009dcSAndroid Build Coastguard Worker int64_t s8;
1433*8fb009dcSAndroid Build Coastguard Worker int64_t s9;
1434*8fb009dcSAndroid Build Coastguard Worker int64_t s10;
1435*8fb009dcSAndroid Build Coastguard Worker int64_t s11;
1436*8fb009dcSAndroid Build Coastguard Worker int64_t s12;
1437*8fb009dcSAndroid Build Coastguard Worker int64_t s13;
1438*8fb009dcSAndroid Build Coastguard Worker int64_t s14;
1439*8fb009dcSAndroid Build Coastguard Worker int64_t s15;
1440*8fb009dcSAndroid Build Coastguard Worker int64_t s16;
1441*8fb009dcSAndroid Build Coastguard Worker int64_t s17;
1442*8fb009dcSAndroid Build Coastguard Worker int64_t s18;
1443*8fb009dcSAndroid Build Coastguard Worker int64_t s19;
1444*8fb009dcSAndroid Build Coastguard Worker int64_t s20;
1445*8fb009dcSAndroid Build Coastguard Worker int64_t s21;
1446*8fb009dcSAndroid Build Coastguard Worker int64_t s22;
1447*8fb009dcSAndroid Build Coastguard Worker int64_t s23;
1448*8fb009dcSAndroid Build Coastguard Worker int64_t carry0;
1449*8fb009dcSAndroid Build Coastguard Worker int64_t carry1;
1450*8fb009dcSAndroid Build Coastguard Worker int64_t carry2;
1451*8fb009dcSAndroid Build Coastguard Worker int64_t carry3;
1452*8fb009dcSAndroid Build Coastguard Worker int64_t carry4;
1453*8fb009dcSAndroid Build Coastguard Worker int64_t carry5;
1454*8fb009dcSAndroid Build Coastguard Worker int64_t carry6;
1455*8fb009dcSAndroid Build Coastguard Worker int64_t carry7;
1456*8fb009dcSAndroid Build Coastguard Worker int64_t carry8;
1457*8fb009dcSAndroid Build Coastguard Worker int64_t carry9;
1458*8fb009dcSAndroid Build Coastguard Worker int64_t carry10;
1459*8fb009dcSAndroid Build Coastguard Worker int64_t carry11;
1460*8fb009dcSAndroid Build Coastguard Worker int64_t carry12;
1461*8fb009dcSAndroid Build Coastguard Worker int64_t carry13;
1462*8fb009dcSAndroid Build Coastguard Worker int64_t carry14;
1463*8fb009dcSAndroid Build Coastguard Worker int64_t carry15;
1464*8fb009dcSAndroid Build Coastguard Worker int64_t carry16;
1465*8fb009dcSAndroid Build Coastguard Worker int64_t carry17;
1466*8fb009dcSAndroid Build Coastguard Worker int64_t carry18;
1467*8fb009dcSAndroid Build Coastguard Worker int64_t carry19;
1468*8fb009dcSAndroid Build Coastguard Worker int64_t carry20;
1469*8fb009dcSAndroid Build Coastguard Worker int64_t carry21;
1470*8fb009dcSAndroid Build Coastguard Worker int64_t carry22;
1471*8fb009dcSAndroid Build Coastguard Worker
1472*8fb009dcSAndroid Build Coastguard Worker s0 = c0 + a0 * b0;
1473*8fb009dcSAndroid Build Coastguard Worker s1 = c1 + a0 * b1 + a1 * b0;
1474*8fb009dcSAndroid Build Coastguard Worker s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
1475*8fb009dcSAndroid Build Coastguard Worker s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
1476*8fb009dcSAndroid Build Coastguard Worker s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
1477*8fb009dcSAndroid Build Coastguard Worker s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
1478*8fb009dcSAndroid Build Coastguard Worker s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
1479*8fb009dcSAndroid Build Coastguard Worker s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
1480*8fb009dcSAndroid Build Coastguard Worker a6 * b1 + a7 * b0;
1481*8fb009dcSAndroid Build Coastguard Worker s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
1482*8fb009dcSAndroid Build Coastguard Worker a6 * b2 + a7 * b1 + a8 * b0;
1483*8fb009dcSAndroid Build Coastguard Worker s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
1484*8fb009dcSAndroid Build Coastguard Worker a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
1485*8fb009dcSAndroid Build Coastguard Worker s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
1486*8fb009dcSAndroid Build Coastguard Worker a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
1487*8fb009dcSAndroid Build Coastguard Worker s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
1488*8fb009dcSAndroid Build Coastguard Worker a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
1489*8fb009dcSAndroid Build Coastguard Worker s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
1490*8fb009dcSAndroid Build Coastguard Worker a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
1491*8fb009dcSAndroid Build Coastguard Worker s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
1492*8fb009dcSAndroid Build Coastguard Worker a9 * b4 + a10 * b3 + a11 * b2;
1493*8fb009dcSAndroid Build Coastguard Worker s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
1494*8fb009dcSAndroid Build Coastguard Worker a10 * b4 + a11 * b3;
1495*8fb009dcSAndroid Build Coastguard Worker s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
1496*8fb009dcSAndroid Build Coastguard Worker a11 * b4;
1497*8fb009dcSAndroid Build Coastguard Worker s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
1498*8fb009dcSAndroid Build Coastguard Worker s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
1499*8fb009dcSAndroid Build Coastguard Worker s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
1500*8fb009dcSAndroid Build Coastguard Worker s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
1501*8fb009dcSAndroid Build Coastguard Worker s20 = a9 * b11 + a10 * b10 + a11 * b9;
1502*8fb009dcSAndroid Build Coastguard Worker s21 = a10 * b11 + a11 * b10;
1503*8fb009dcSAndroid Build Coastguard Worker s22 = a11 * b11;
1504*8fb009dcSAndroid Build Coastguard Worker s23 = 0;
1505*8fb009dcSAndroid Build Coastguard Worker
1506*8fb009dcSAndroid Build Coastguard Worker carry0 = (s0 + (1 << 20)) >> 21;
1507*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1508*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1509*8fb009dcSAndroid Build Coastguard Worker carry2 = (s2 + (1 << 20)) >> 21;
1510*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1511*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1512*8fb009dcSAndroid Build Coastguard Worker carry4 = (s4 + (1 << 20)) >> 21;
1513*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1514*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1515*8fb009dcSAndroid Build Coastguard Worker carry6 = (s6 + (1 << 20)) >> 21;
1516*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1517*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1518*8fb009dcSAndroid Build Coastguard Worker carry8 = (s8 + (1 << 20)) >> 21;
1519*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1520*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1521*8fb009dcSAndroid Build Coastguard Worker carry10 = (s10 + (1 << 20)) >> 21;
1522*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1523*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1524*8fb009dcSAndroid Build Coastguard Worker carry12 = (s12 + (1 << 20)) >> 21;
1525*8fb009dcSAndroid Build Coastguard Worker s13 += carry12;
1526*8fb009dcSAndroid Build Coastguard Worker s12 -= int64_lshift21(carry12);
1527*8fb009dcSAndroid Build Coastguard Worker carry14 = (s14 + (1 << 20)) >> 21;
1528*8fb009dcSAndroid Build Coastguard Worker s15 += carry14;
1529*8fb009dcSAndroid Build Coastguard Worker s14 -= int64_lshift21(carry14);
1530*8fb009dcSAndroid Build Coastguard Worker carry16 = (s16 + (1 << 20)) >> 21;
1531*8fb009dcSAndroid Build Coastguard Worker s17 += carry16;
1532*8fb009dcSAndroid Build Coastguard Worker s16 -= int64_lshift21(carry16);
1533*8fb009dcSAndroid Build Coastguard Worker carry18 = (s18 + (1 << 20)) >> 21;
1534*8fb009dcSAndroid Build Coastguard Worker s19 += carry18;
1535*8fb009dcSAndroid Build Coastguard Worker s18 -= int64_lshift21(carry18);
1536*8fb009dcSAndroid Build Coastguard Worker carry20 = (s20 + (1 << 20)) >> 21;
1537*8fb009dcSAndroid Build Coastguard Worker s21 += carry20;
1538*8fb009dcSAndroid Build Coastguard Worker s20 -= int64_lshift21(carry20);
1539*8fb009dcSAndroid Build Coastguard Worker carry22 = (s22 + (1 << 20)) >> 21;
1540*8fb009dcSAndroid Build Coastguard Worker s23 += carry22;
1541*8fb009dcSAndroid Build Coastguard Worker s22 -= int64_lshift21(carry22);
1542*8fb009dcSAndroid Build Coastguard Worker
1543*8fb009dcSAndroid Build Coastguard Worker carry1 = (s1 + (1 << 20)) >> 21;
1544*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1545*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1546*8fb009dcSAndroid Build Coastguard Worker carry3 = (s3 + (1 << 20)) >> 21;
1547*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1548*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1549*8fb009dcSAndroid Build Coastguard Worker carry5 = (s5 + (1 << 20)) >> 21;
1550*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1551*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1552*8fb009dcSAndroid Build Coastguard Worker carry7 = (s7 + (1 << 20)) >> 21;
1553*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1554*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1555*8fb009dcSAndroid Build Coastguard Worker carry9 = (s9 + (1 << 20)) >> 21;
1556*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1557*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1558*8fb009dcSAndroid Build Coastguard Worker carry11 = (s11 + (1 << 20)) >> 21;
1559*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1560*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1561*8fb009dcSAndroid Build Coastguard Worker carry13 = (s13 + (1 << 20)) >> 21;
1562*8fb009dcSAndroid Build Coastguard Worker s14 += carry13;
1563*8fb009dcSAndroid Build Coastguard Worker s13 -= int64_lshift21(carry13);
1564*8fb009dcSAndroid Build Coastguard Worker carry15 = (s15 + (1 << 20)) >> 21;
1565*8fb009dcSAndroid Build Coastguard Worker s16 += carry15;
1566*8fb009dcSAndroid Build Coastguard Worker s15 -= int64_lshift21(carry15);
1567*8fb009dcSAndroid Build Coastguard Worker carry17 = (s17 + (1 << 20)) >> 21;
1568*8fb009dcSAndroid Build Coastguard Worker s18 += carry17;
1569*8fb009dcSAndroid Build Coastguard Worker s17 -= int64_lshift21(carry17);
1570*8fb009dcSAndroid Build Coastguard Worker carry19 = (s19 + (1 << 20)) >> 21;
1571*8fb009dcSAndroid Build Coastguard Worker s20 += carry19;
1572*8fb009dcSAndroid Build Coastguard Worker s19 -= int64_lshift21(carry19);
1573*8fb009dcSAndroid Build Coastguard Worker carry21 = (s21 + (1 << 20)) >> 21;
1574*8fb009dcSAndroid Build Coastguard Worker s22 += carry21;
1575*8fb009dcSAndroid Build Coastguard Worker s21 -= int64_lshift21(carry21);
1576*8fb009dcSAndroid Build Coastguard Worker
1577*8fb009dcSAndroid Build Coastguard Worker s11 += s23 * 666643;
1578*8fb009dcSAndroid Build Coastguard Worker s12 += s23 * 470296;
1579*8fb009dcSAndroid Build Coastguard Worker s13 += s23 * 654183;
1580*8fb009dcSAndroid Build Coastguard Worker s14 -= s23 * 997805;
1581*8fb009dcSAndroid Build Coastguard Worker s15 += s23 * 136657;
1582*8fb009dcSAndroid Build Coastguard Worker s16 -= s23 * 683901;
1583*8fb009dcSAndroid Build Coastguard Worker s23 = 0;
1584*8fb009dcSAndroid Build Coastguard Worker
1585*8fb009dcSAndroid Build Coastguard Worker s10 += s22 * 666643;
1586*8fb009dcSAndroid Build Coastguard Worker s11 += s22 * 470296;
1587*8fb009dcSAndroid Build Coastguard Worker s12 += s22 * 654183;
1588*8fb009dcSAndroid Build Coastguard Worker s13 -= s22 * 997805;
1589*8fb009dcSAndroid Build Coastguard Worker s14 += s22 * 136657;
1590*8fb009dcSAndroid Build Coastguard Worker s15 -= s22 * 683901;
1591*8fb009dcSAndroid Build Coastguard Worker s22 = 0;
1592*8fb009dcSAndroid Build Coastguard Worker
1593*8fb009dcSAndroid Build Coastguard Worker s9 += s21 * 666643;
1594*8fb009dcSAndroid Build Coastguard Worker s10 += s21 * 470296;
1595*8fb009dcSAndroid Build Coastguard Worker s11 += s21 * 654183;
1596*8fb009dcSAndroid Build Coastguard Worker s12 -= s21 * 997805;
1597*8fb009dcSAndroid Build Coastguard Worker s13 += s21 * 136657;
1598*8fb009dcSAndroid Build Coastguard Worker s14 -= s21 * 683901;
1599*8fb009dcSAndroid Build Coastguard Worker s21 = 0;
1600*8fb009dcSAndroid Build Coastguard Worker
1601*8fb009dcSAndroid Build Coastguard Worker s8 += s20 * 666643;
1602*8fb009dcSAndroid Build Coastguard Worker s9 += s20 * 470296;
1603*8fb009dcSAndroid Build Coastguard Worker s10 += s20 * 654183;
1604*8fb009dcSAndroid Build Coastguard Worker s11 -= s20 * 997805;
1605*8fb009dcSAndroid Build Coastguard Worker s12 += s20 * 136657;
1606*8fb009dcSAndroid Build Coastguard Worker s13 -= s20 * 683901;
1607*8fb009dcSAndroid Build Coastguard Worker s20 = 0;
1608*8fb009dcSAndroid Build Coastguard Worker
1609*8fb009dcSAndroid Build Coastguard Worker s7 += s19 * 666643;
1610*8fb009dcSAndroid Build Coastguard Worker s8 += s19 * 470296;
1611*8fb009dcSAndroid Build Coastguard Worker s9 += s19 * 654183;
1612*8fb009dcSAndroid Build Coastguard Worker s10 -= s19 * 997805;
1613*8fb009dcSAndroid Build Coastguard Worker s11 += s19 * 136657;
1614*8fb009dcSAndroid Build Coastguard Worker s12 -= s19 * 683901;
1615*8fb009dcSAndroid Build Coastguard Worker s19 = 0;
1616*8fb009dcSAndroid Build Coastguard Worker
1617*8fb009dcSAndroid Build Coastguard Worker s6 += s18 * 666643;
1618*8fb009dcSAndroid Build Coastguard Worker s7 += s18 * 470296;
1619*8fb009dcSAndroid Build Coastguard Worker s8 += s18 * 654183;
1620*8fb009dcSAndroid Build Coastguard Worker s9 -= s18 * 997805;
1621*8fb009dcSAndroid Build Coastguard Worker s10 += s18 * 136657;
1622*8fb009dcSAndroid Build Coastguard Worker s11 -= s18 * 683901;
1623*8fb009dcSAndroid Build Coastguard Worker s18 = 0;
1624*8fb009dcSAndroid Build Coastguard Worker
1625*8fb009dcSAndroid Build Coastguard Worker carry6 = (s6 + (1 << 20)) >> 21;
1626*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1627*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1628*8fb009dcSAndroid Build Coastguard Worker carry8 = (s8 + (1 << 20)) >> 21;
1629*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1630*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1631*8fb009dcSAndroid Build Coastguard Worker carry10 = (s10 + (1 << 20)) >> 21;
1632*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1633*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1634*8fb009dcSAndroid Build Coastguard Worker carry12 = (s12 + (1 << 20)) >> 21;
1635*8fb009dcSAndroid Build Coastguard Worker s13 += carry12;
1636*8fb009dcSAndroid Build Coastguard Worker s12 -= int64_lshift21(carry12);
1637*8fb009dcSAndroid Build Coastguard Worker carry14 = (s14 + (1 << 20)) >> 21;
1638*8fb009dcSAndroid Build Coastguard Worker s15 += carry14;
1639*8fb009dcSAndroid Build Coastguard Worker s14 -= int64_lshift21(carry14);
1640*8fb009dcSAndroid Build Coastguard Worker carry16 = (s16 + (1 << 20)) >> 21;
1641*8fb009dcSAndroid Build Coastguard Worker s17 += carry16;
1642*8fb009dcSAndroid Build Coastguard Worker s16 -= int64_lshift21(carry16);
1643*8fb009dcSAndroid Build Coastguard Worker
1644*8fb009dcSAndroid Build Coastguard Worker carry7 = (s7 + (1 << 20)) >> 21;
1645*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1646*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1647*8fb009dcSAndroid Build Coastguard Worker carry9 = (s9 + (1 << 20)) >> 21;
1648*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1649*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1650*8fb009dcSAndroid Build Coastguard Worker carry11 = (s11 + (1 << 20)) >> 21;
1651*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1652*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1653*8fb009dcSAndroid Build Coastguard Worker carry13 = (s13 + (1 << 20)) >> 21;
1654*8fb009dcSAndroid Build Coastguard Worker s14 += carry13;
1655*8fb009dcSAndroid Build Coastguard Worker s13 -= int64_lshift21(carry13);
1656*8fb009dcSAndroid Build Coastguard Worker carry15 = (s15 + (1 << 20)) >> 21;
1657*8fb009dcSAndroid Build Coastguard Worker s16 += carry15;
1658*8fb009dcSAndroid Build Coastguard Worker s15 -= int64_lshift21(carry15);
1659*8fb009dcSAndroid Build Coastguard Worker
1660*8fb009dcSAndroid Build Coastguard Worker s5 += s17 * 666643;
1661*8fb009dcSAndroid Build Coastguard Worker s6 += s17 * 470296;
1662*8fb009dcSAndroid Build Coastguard Worker s7 += s17 * 654183;
1663*8fb009dcSAndroid Build Coastguard Worker s8 -= s17 * 997805;
1664*8fb009dcSAndroid Build Coastguard Worker s9 += s17 * 136657;
1665*8fb009dcSAndroid Build Coastguard Worker s10 -= s17 * 683901;
1666*8fb009dcSAndroid Build Coastguard Worker s17 = 0;
1667*8fb009dcSAndroid Build Coastguard Worker
1668*8fb009dcSAndroid Build Coastguard Worker s4 += s16 * 666643;
1669*8fb009dcSAndroid Build Coastguard Worker s5 += s16 * 470296;
1670*8fb009dcSAndroid Build Coastguard Worker s6 += s16 * 654183;
1671*8fb009dcSAndroid Build Coastguard Worker s7 -= s16 * 997805;
1672*8fb009dcSAndroid Build Coastguard Worker s8 += s16 * 136657;
1673*8fb009dcSAndroid Build Coastguard Worker s9 -= s16 * 683901;
1674*8fb009dcSAndroid Build Coastguard Worker s16 = 0;
1675*8fb009dcSAndroid Build Coastguard Worker
1676*8fb009dcSAndroid Build Coastguard Worker s3 += s15 * 666643;
1677*8fb009dcSAndroid Build Coastguard Worker s4 += s15 * 470296;
1678*8fb009dcSAndroid Build Coastguard Worker s5 += s15 * 654183;
1679*8fb009dcSAndroid Build Coastguard Worker s6 -= s15 * 997805;
1680*8fb009dcSAndroid Build Coastguard Worker s7 += s15 * 136657;
1681*8fb009dcSAndroid Build Coastguard Worker s8 -= s15 * 683901;
1682*8fb009dcSAndroid Build Coastguard Worker s15 = 0;
1683*8fb009dcSAndroid Build Coastguard Worker
1684*8fb009dcSAndroid Build Coastguard Worker s2 += s14 * 666643;
1685*8fb009dcSAndroid Build Coastguard Worker s3 += s14 * 470296;
1686*8fb009dcSAndroid Build Coastguard Worker s4 += s14 * 654183;
1687*8fb009dcSAndroid Build Coastguard Worker s5 -= s14 * 997805;
1688*8fb009dcSAndroid Build Coastguard Worker s6 += s14 * 136657;
1689*8fb009dcSAndroid Build Coastguard Worker s7 -= s14 * 683901;
1690*8fb009dcSAndroid Build Coastguard Worker s14 = 0;
1691*8fb009dcSAndroid Build Coastguard Worker
1692*8fb009dcSAndroid Build Coastguard Worker s1 += s13 * 666643;
1693*8fb009dcSAndroid Build Coastguard Worker s2 += s13 * 470296;
1694*8fb009dcSAndroid Build Coastguard Worker s3 += s13 * 654183;
1695*8fb009dcSAndroid Build Coastguard Worker s4 -= s13 * 997805;
1696*8fb009dcSAndroid Build Coastguard Worker s5 += s13 * 136657;
1697*8fb009dcSAndroid Build Coastguard Worker s6 -= s13 * 683901;
1698*8fb009dcSAndroid Build Coastguard Worker s13 = 0;
1699*8fb009dcSAndroid Build Coastguard Worker
1700*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1701*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1702*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1703*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1704*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1705*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1706*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1707*8fb009dcSAndroid Build Coastguard Worker
1708*8fb009dcSAndroid Build Coastguard Worker carry0 = (s0 + (1 << 20)) >> 21;
1709*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1710*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1711*8fb009dcSAndroid Build Coastguard Worker carry2 = (s2 + (1 << 20)) >> 21;
1712*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1713*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1714*8fb009dcSAndroid Build Coastguard Worker carry4 = (s4 + (1 << 20)) >> 21;
1715*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1716*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1717*8fb009dcSAndroid Build Coastguard Worker carry6 = (s6 + (1 << 20)) >> 21;
1718*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1719*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1720*8fb009dcSAndroid Build Coastguard Worker carry8 = (s8 + (1 << 20)) >> 21;
1721*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1722*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1723*8fb009dcSAndroid Build Coastguard Worker carry10 = (s10 + (1 << 20)) >> 21;
1724*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1725*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1726*8fb009dcSAndroid Build Coastguard Worker
1727*8fb009dcSAndroid Build Coastguard Worker carry1 = (s1 + (1 << 20)) >> 21;
1728*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1729*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1730*8fb009dcSAndroid Build Coastguard Worker carry3 = (s3 + (1 << 20)) >> 21;
1731*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1732*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1733*8fb009dcSAndroid Build Coastguard Worker carry5 = (s5 + (1 << 20)) >> 21;
1734*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1735*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1736*8fb009dcSAndroid Build Coastguard Worker carry7 = (s7 + (1 << 20)) >> 21;
1737*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1738*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1739*8fb009dcSAndroid Build Coastguard Worker carry9 = (s9 + (1 << 20)) >> 21;
1740*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1741*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1742*8fb009dcSAndroid Build Coastguard Worker carry11 = (s11 + (1 << 20)) >> 21;
1743*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1744*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1745*8fb009dcSAndroid Build Coastguard Worker
1746*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1747*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1748*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1749*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1750*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1751*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1752*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1753*8fb009dcSAndroid Build Coastguard Worker
1754*8fb009dcSAndroid Build Coastguard Worker carry0 = s0 >> 21;
1755*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1756*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1757*8fb009dcSAndroid Build Coastguard Worker carry1 = s1 >> 21;
1758*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1759*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1760*8fb009dcSAndroid Build Coastguard Worker carry2 = s2 >> 21;
1761*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1762*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1763*8fb009dcSAndroid Build Coastguard Worker carry3 = s3 >> 21;
1764*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1765*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1766*8fb009dcSAndroid Build Coastguard Worker carry4 = s4 >> 21;
1767*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1768*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1769*8fb009dcSAndroid Build Coastguard Worker carry5 = s5 >> 21;
1770*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1771*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1772*8fb009dcSAndroid Build Coastguard Worker carry6 = s6 >> 21;
1773*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1774*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1775*8fb009dcSAndroid Build Coastguard Worker carry7 = s7 >> 21;
1776*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1777*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1778*8fb009dcSAndroid Build Coastguard Worker carry8 = s8 >> 21;
1779*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1780*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1781*8fb009dcSAndroid Build Coastguard Worker carry9 = s9 >> 21;
1782*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1783*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1784*8fb009dcSAndroid Build Coastguard Worker carry10 = s10 >> 21;
1785*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1786*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1787*8fb009dcSAndroid Build Coastguard Worker carry11 = s11 >> 21;
1788*8fb009dcSAndroid Build Coastguard Worker s12 += carry11;
1789*8fb009dcSAndroid Build Coastguard Worker s11 -= int64_lshift21(carry11);
1790*8fb009dcSAndroid Build Coastguard Worker
1791*8fb009dcSAndroid Build Coastguard Worker s0 += s12 * 666643;
1792*8fb009dcSAndroid Build Coastguard Worker s1 += s12 * 470296;
1793*8fb009dcSAndroid Build Coastguard Worker s2 += s12 * 654183;
1794*8fb009dcSAndroid Build Coastguard Worker s3 -= s12 * 997805;
1795*8fb009dcSAndroid Build Coastguard Worker s4 += s12 * 136657;
1796*8fb009dcSAndroid Build Coastguard Worker s5 -= s12 * 683901;
1797*8fb009dcSAndroid Build Coastguard Worker s12 = 0;
1798*8fb009dcSAndroid Build Coastguard Worker
1799*8fb009dcSAndroid Build Coastguard Worker carry0 = s0 >> 21;
1800*8fb009dcSAndroid Build Coastguard Worker s1 += carry0;
1801*8fb009dcSAndroid Build Coastguard Worker s0 -= int64_lshift21(carry0);
1802*8fb009dcSAndroid Build Coastguard Worker carry1 = s1 >> 21;
1803*8fb009dcSAndroid Build Coastguard Worker s2 += carry1;
1804*8fb009dcSAndroid Build Coastguard Worker s1 -= int64_lshift21(carry1);
1805*8fb009dcSAndroid Build Coastguard Worker carry2 = s2 >> 21;
1806*8fb009dcSAndroid Build Coastguard Worker s3 += carry2;
1807*8fb009dcSAndroid Build Coastguard Worker s2 -= int64_lshift21(carry2);
1808*8fb009dcSAndroid Build Coastguard Worker carry3 = s3 >> 21;
1809*8fb009dcSAndroid Build Coastguard Worker s4 += carry3;
1810*8fb009dcSAndroid Build Coastguard Worker s3 -= int64_lshift21(carry3);
1811*8fb009dcSAndroid Build Coastguard Worker carry4 = s4 >> 21;
1812*8fb009dcSAndroid Build Coastguard Worker s5 += carry4;
1813*8fb009dcSAndroid Build Coastguard Worker s4 -= int64_lshift21(carry4);
1814*8fb009dcSAndroid Build Coastguard Worker carry5 = s5 >> 21;
1815*8fb009dcSAndroid Build Coastguard Worker s6 += carry5;
1816*8fb009dcSAndroid Build Coastguard Worker s5 -= int64_lshift21(carry5);
1817*8fb009dcSAndroid Build Coastguard Worker carry6 = s6 >> 21;
1818*8fb009dcSAndroid Build Coastguard Worker s7 += carry6;
1819*8fb009dcSAndroid Build Coastguard Worker s6 -= int64_lshift21(carry6);
1820*8fb009dcSAndroid Build Coastguard Worker carry7 = s7 >> 21;
1821*8fb009dcSAndroid Build Coastguard Worker s8 += carry7;
1822*8fb009dcSAndroid Build Coastguard Worker s7 -= int64_lshift21(carry7);
1823*8fb009dcSAndroid Build Coastguard Worker carry8 = s8 >> 21;
1824*8fb009dcSAndroid Build Coastguard Worker s9 += carry8;
1825*8fb009dcSAndroid Build Coastguard Worker s8 -= int64_lshift21(carry8);
1826*8fb009dcSAndroid Build Coastguard Worker carry9 = s9 >> 21;
1827*8fb009dcSAndroid Build Coastguard Worker s10 += carry9;
1828*8fb009dcSAndroid Build Coastguard Worker s9 -= int64_lshift21(carry9);
1829*8fb009dcSAndroid Build Coastguard Worker carry10 = s10 >> 21;
1830*8fb009dcSAndroid Build Coastguard Worker s11 += carry10;
1831*8fb009dcSAndroid Build Coastguard Worker s10 -= int64_lshift21(carry10);
1832*8fb009dcSAndroid Build Coastguard Worker
1833*8fb009dcSAndroid Build Coastguard Worker s[0] = s0 >> 0;
1834*8fb009dcSAndroid Build Coastguard Worker s[1] = s0 >> 8;
1835*8fb009dcSAndroid Build Coastguard Worker s[2] = (s0 >> 16) | (s1 << 5);
1836*8fb009dcSAndroid Build Coastguard Worker s[3] = s1 >> 3;
1837*8fb009dcSAndroid Build Coastguard Worker s[4] = s1 >> 11;
1838*8fb009dcSAndroid Build Coastguard Worker s[5] = (s1 >> 19) | (s2 << 2);
1839*8fb009dcSAndroid Build Coastguard Worker s[6] = s2 >> 6;
1840*8fb009dcSAndroid Build Coastguard Worker s[7] = (s2 >> 14) | (s3 << 7);
1841*8fb009dcSAndroid Build Coastguard Worker s[8] = s3 >> 1;
1842*8fb009dcSAndroid Build Coastguard Worker s[9] = s3 >> 9;
1843*8fb009dcSAndroid Build Coastguard Worker s[10] = (s3 >> 17) | (s4 << 4);
1844*8fb009dcSAndroid Build Coastguard Worker s[11] = s4 >> 4;
1845*8fb009dcSAndroid Build Coastguard Worker s[12] = s4 >> 12;
1846*8fb009dcSAndroid Build Coastguard Worker s[13] = (s4 >> 20) | (s5 << 1);
1847*8fb009dcSAndroid Build Coastguard Worker s[14] = s5 >> 7;
1848*8fb009dcSAndroid Build Coastguard Worker s[15] = (s5 >> 15) | (s6 << 6);
1849*8fb009dcSAndroid Build Coastguard Worker s[16] = s6 >> 2;
1850*8fb009dcSAndroid Build Coastguard Worker s[17] = s6 >> 10;
1851*8fb009dcSAndroid Build Coastguard Worker s[18] = (s6 >> 18) | (s7 << 3);
1852*8fb009dcSAndroid Build Coastguard Worker s[19] = s7 >> 5;
1853*8fb009dcSAndroid Build Coastguard Worker s[20] = s7 >> 13;
1854*8fb009dcSAndroid Build Coastguard Worker s[21] = s8 >> 0;
1855*8fb009dcSAndroid Build Coastguard Worker s[22] = s8 >> 8;
1856*8fb009dcSAndroid Build Coastguard Worker s[23] = (s8 >> 16) | (s9 << 5);
1857*8fb009dcSAndroid Build Coastguard Worker s[24] = s9 >> 3;
1858*8fb009dcSAndroid Build Coastguard Worker s[25] = s9 >> 11;
1859*8fb009dcSAndroid Build Coastguard Worker s[26] = (s9 >> 19) | (s10 << 2);
1860*8fb009dcSAndroid Build Coastguard Worker s[27] = s10 >> 6;
1861*8fb009dcSAndroid Build Coastguard Worker s[28] = (s10 >> 14) | (s11 << 7);
1862*8fb009dcSAndroid Build Coastguard Worker s[29] = s11 >> 1;
1863*8fb009dcSAndroid Build Coastguard Worker s[30] = s11 >> 9;
1864*8fb009dcSAndroid Build Coastguard Worker s[31] = s11 >> 17;
1865*8fb009dcSAndroid Build Coastguard Worker }
1866*8fb009dcSAndroid Build Coastguard Worker
ED25519_keypair(uint8_t out_public_key[32],uint8_t out_private_key[64])1867*8fb009dcSAndroid Build Coastguard Worker void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
1868*8fb009dcSAndroid Build Coastguard Worker uint8_t seed[32];
1869*8fb009dcSAndroid Build Coastguard Worker RAND_bytes(seed, 32);
1870*8fb009dcSAndroid Build Coastguard Worker ED25519_keypair_from_seed(out_public_key, out_private_key, seed);
1871*8fb009dcSAndroid Build Coastguard Worker }
1872*8fb009dcSAndroid Build Coastguard Worker
ED25519_sign(uint8_t out_sig[64],const uint8_t * message,size_t message_len,const uint8_t private_key[64])1873*8fb009dcSAndroid Build Coastguard Worker int ED25519_sign(uint8_t out_sig[64], const uint8_t *message,
1874*8fb009dcSAndroid Build Coastguard Worker size_t message_len, const uint8_t private_key[64]) {
1875*8fb009dcSAndroid Build Coastguard Worker // NOTE: The documentation on this function says that it returns zero on
1876*8fb009dcSAndroid Build Coastguard Worker // allocation failure. While that can't happen with the current
1877*8fb009dcSAndroid Build Coastguard Worker // implementation, we want to reserve the ability to allocate in this
1878*8fb009dcSAndroid Build Coastguard Worker // implementation in the future.
1879*8fb009dcSAndroid Build Coastguard Worker
1880*8fb009dcSAndroid Build Coastguard Worker uint8_t az[SHA512_DIGEST_LENGTH];
1881*8fb009dcSAndroid Build Coastguard Worker SHA512(private_key, 32, az);
1882*8fb009dcSAndroid Build Coastguard Worker
1883*8fb009dcSAndroid Build Coastguard Worker az[0] &= 248;
1884*8fb009dcSAndroid Build Coastguard Worker az[31] &= 63;
1885*8fb009dcSAndroid Build Coastguard Worker az[31] |= 64;
1886*8fb009dcSAndroid Build Coastguard Worker
1887*8fb009dcSAndroid Build Coastguard Worker SHA512_CTX hash_ctx;
1888*8fb009dcSAndroid Build Coastguard Worker SHA512_Init(&hash_ctx);
1889*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, az + 32, 32);
1890*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, message, message_len);
1891*8fb009dcSAndroid Build Coastguard Worker uint8_t nonce[SHA512_DIGEST_LENGTH];
1892*8fb009dcSAndroid Build Coastguard Worker SHA512_Final(nonce, &hash_ctx);
1893*8fb009dcSAndroid Build Coastguard Worker
1894*8fb009dcSAndroid Build Coastguard Worker x25519_sc_reduce(nonce);
1895*8fb009dcSAndroid Build Coastguard Worker ge_p3 R;
1896*8fb009dcSAndroid Build Coastguard Worker x25519_ge_scalarmult_base(&R, nonce);
1897*8fb009dcSAndroid Build Coastguard Worker ge_p3_tobytes(out_sig, &R);
1898*8fb009dcSAndroid Build Coastguard Worker
1899*8fb009dcSAndroid Build Coastguard Worker SHA512_Init(&hash_ctx);
1900*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, out_sig, 32);
1901*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, private_key + 32, 32);
1902*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, message, message_len);
1903*8fb009dcSAndroid Build Coastguard Worker uint8_t hram[SHA512_DIGEST_LENGTH];
1904*8fb009dcSAndroid Build Coastguard Worker SHA512_Final(hram, &hash_ctx);
1905*8fb009dcSAndroid Build Coastguard Worker
1906*8fb009dcSAndroid Build Coastguard Worker x25519_sc_reduce(hram);
1907*8fb009dcSAndroid Build Coastguard Worker sc_muladd(out_sig + 32, hram, az, nonce);
1908*8fb009dcSAndroid Build Coastguard Worker
1909*8fb009dcSAndroid Build Coastguard Worker // The signature is computed from the private key, but is public.
1910*8fb009dcSAndroid Build Coastguard Worker CONSTTIME_DECLASSIFY(out_sig, 64);
1911*8fb009dcSAndroid Build Coastguard Worker return 1;
1912*8fb009dcSAndroid Build Coastguard Worker }
1913*8fb009dcSAndroid Build Coastguard Worker
ED25519_verify(const uint8_t * message,size_t message_len,const uint8_t signature[64],const uint8_t public_key[32])1914*8fb009dcSAndroid Build Coastguard Worker int ED25519_verify(const uint8_t *message, size_t message_len,
1915*8fb009dcSAndroid Build Coastguard Worker const uint8_t signature[64], const uint8_t public_key[32]) {
1916*8fb009dcSAndroid Build Coastguard Worker ge_p3 A;
1917*8fb009dcSAndroid Build Coastguard Worker if ((signature[63] & 224) != 0 ||
1918*8fb009dcSAndroid Build Coastguard Worker !x25519_ge_frombytes_vartime(&A, public_key)) {
1919*8fb009dcSAndroid Build Coastguard Worker return 0;
1920*8fb009dcSAndroid Build Coastguard Worker }
1921*8fb009dcSAndroid Build Coastguard Worker
1922*8fb009dcSAndroid Build Coastguard Worker fe_loose t;
1923*8fb009dcSAndroid Build Coastguard Worker fe_neg(&t, &A.X);
1924*8fb009dcSAndroid Build Coastguard Worker fe_carry(&A.X, &t);
1925*8fb009dcSAndroid Build Coastguard Worker fe_neg(&t, &A.T);
1926*8fb009dcSAndroid Build Coastguard Worker fe_carry(&A.T, &t);
1927*8fb009dcSAndroid Build Coastguard Worker
1928*8fb009dcSAndroid Build Coastguard Worker uint8_t pkcopy[32];
1929*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(pkcopy, public_key, 32);
1930*8fb009dcSAndroid Build Coastguard Worker uint8_t rcopy[32];
1931*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(rcopy, signature, 32);
1932*8fb009dcSAndroid Build Coastguard Worker uint8_t scopy[32];
1933*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(scopy, signature + 32, 32);
1934*8fb009dcSAndroid Build Coastguard Worker
1935*8fb009dcSAndroid Build Coastguard Worker // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
1936*8fb009dcSAndroid Build Coastguard Worker // the range [0, order) in order to prevent signature malleability.
1937*8fb009dcSAndroid Build Coastguard Worker
1938*8fb009dcSAndroid Build Coastguard Worker // kOrder is the order of Curve25519 in little-endian form.
1939*8fb009dcSAndroid Build Coastguard Worker static const uint64_t kOrder[4] = {
1940*8fb009dcSAndroid Build Coastguard Worker UINT64_C(0x5812631a5cf5d3ed),
1941*8fb009dcSAndroid Build Coastguard Worker UINT64_C(0x14def9dea2f79cd6),
1942*8fb009dcSAndroid Build Coastguard Worker 0,
1943*8fb009dcSAndroid Build Coastguard Worker UINT64_C(0x1000000000000000),
1944*8fb009dcSAndroid Build Coastguard Worker };
1945*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 3;; i--) {
1946*8fb009dcSAndroid Build Coastguard Worker uint64_t word = CRYPTO_load_u64_le(scopy + i * 8);
1947*8fb009dcSAndroid Build Coastguard Worker if (word > kOrder[i]) {
1948*8fb009dcSAndroid Build Coastguard Worker return 0;
1949*8fb009dcSAndroid Build Coastguard Worker } else if (word < kOrder[i]) {
1950*8fb009dcSAndroid Build Coastguard Worker break;
1951*8fb009dcSAndroid Build Coastguard Worker } else if (i == 0) {
1952*8fb009dcSAndroid Build Coastguard Worker return 0;
1953*8fb009dcSAndroid Build Coastguard Worker }
1954*8fb009dcSAndroid Build Coastguard Worker }
1955*8fb009dcSAndroid Build Coastguard Worker
1956*8fb009dcSAndroid Build Coastguard Worker SHA512_CTX hash_ctx;
1957*8fb009dcSAndroid Build Coastguard Worker SHA512_Init(&hash_ctx);
1958*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, signature, 32);
1959*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, public_key, 32);
1960*8fb009dcSAndroid Build Coastguard Worker SHA512_Update(&hash_ctx, message, message_len);
1961*8fb009dcSAndroid Build Coastguard Worker uint8_t h[SHA512_DIGEST_LENGTH];
1962*8fb009dcSAndroid Build Coastguard Worker SHA512_Final(h, &hash_ctx);
1963*8fb009dcSAndroid Build Coastguard Worker
1964*8fb009dcSAndroid Build Coastguard Worker x25519_sc_reduce(h);
1965*8fb009dcSAndroid Build Coastguard Worker
1966*8fb009dcSAndroid Build Coastguard Worker ge_p2 R;
1967*8fb009dcSAndroid Build Coastguard Worker ge_double_scalarmult_vartime(&R, h, &A, scopy);
1968*8fb009dcSAndroid Build Coastguard Worker
1969*8fb009dcSAndroid Build Coastguard Worker uint8_t rcheck[32];
1970*8fb009dcSAndroid Build Coastguard Worker x25519_ge_tobytes(rcheck, &R);
1971*8fb009dcSAndroid Build Coastguard Worker
1972*8fb009dcSAndroid Build Coastguard Worker return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
1973*8fb009dcSAndroid Build Coastguard Worker }
1974*8fb009dcSAndroid Build Coastguard Worker
ED25519_keypair_from_seed(uint8_t out_public_key[32],uint8_t out_private_key[64],const uint8_t seed[32])1975*8fb009dcSAndroid Build Coastguard Worker void ED25519_keypair_from_seed(uint8_t out_public_key[32],
1976*8fb009dcSAndroid Build Coastguard Worker uint8_t out_private_key[64],
1977*8fb009dcSAndroid Build Coastguard Worker const uint8_t seed[32]) {
1978*8fb009dcSAndroid Build Coastguard Worker uint8_t az[SHA512_DIGEST_LENGTH];
1979*8fb009dcSAndroid Build Coastguard Worker SHA512(seed, 32, az);
1980*8fb009dcSAndroid Build Coastguard Worker
1981*8fb009dcSAndroid Build Coastguard Worker az[0] &= 248;
1982*8fb009dcSAndroid Build Coastguard Worker az[31] &= 127;
1983*8fb009dcSAndroid Build Coastguard Worker az[31] |= 64;
1984*8fb009dcSAndroid Build Coastguard Worker
1985*8fb009dcSAndroid Build Coastguard Worker ge_p3 A;
1986*8fb009dcSAndroid Build Coastguard Worker x25519_ge_scalarmult_base(&A, az);
1987*8fb009dcSAndroid Build Coastguard Worker ge_p3_tobytes(out_public_key, &A);
1988*8fb009dcSAndroid Build Coastguard Worker // The public key is derived from the private key, but it is public.
1989*8fb009dcSAndroid Build Coastguard Worker CONSTTIME_DECLASSIFY(out_public_key, 32);
1990*8fb009dcSAndroid Build Coastguard Worker
1991*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(out_private_key, seed, 32);
1992*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(out_private_key + 32, out_public_key, 32);
1993*8fb009dcSAndroid Build Coastguard Worker }
1994*8fb009dcSAndroid Build Coastguard Worker
1995*8fb009dcSAndroid Build Coastguard Worker
x25519_scalar_mult_generic(uint8_t out[32],const uint8_t scalar[32],const uint8_t point[32])1996*8fb009dcSAndroid Build Coastguard Worker static void x25519_scalar_mult_generic(uint8_t out[32],
1997*8fb009dcSAndroid Build Coastguard Worker const uint8_t scalar[32],
1998*8fb009dcSAndroid Build Coastguard Worker const uint8_t point[32]) {
1999*8fb009dcSAndroid Build Coastguard Worker fe x1, x2, z2, x3, z3, tmp0, tmp1;
2000*8fb009dcSAndroid Build Coastguard Worker fe_loose x2l, z2l, x3l, tmp0l, tmp1l;
2001*8fb009dcSAndroid Build Coastguard Worker
2002*8fb009dcSAndroid Build Coastguard Worker uint8_t e[32];
2003*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(e, scalar, 32);
2004*8fb009dcSAndroid Build Coastguard Worker e[0] &= 248;
2005*8fb009dcSAndroid Build Coastguard Worker e[31] &= 127;
2006*8fb009dcSAndroid Build Coastguard Worker e[31] |= 64;
2007*8fb009dcSAndroid Build Coastguard Worker
2008*8fb009dcSAndroid Build Coastguard Worker // The following implementation was transcribed to Coq and proven to
2009*8fb009dcSAndroid Build Coastguard Worker // correspond to unary scalar multiplication in affine coordinates given that
2010*8fb009dcSAndroid Build Coastguard Worker // x1 != 0 is the x coordinate of some point on the curve. It was also checked
2011*8fb009dcSAndroid Build Coastguard Worker // in Coq that doing a ladderstep with x1 = x3 = 0 gives z2' = z3' = 0, and z2
2012*8fb009dcSAndroid Build Coastguard Worker // = z3 = 0 gives z2' = z3' = 0. The statement was quantified over the
2013*8fb009dcSAndroid Build Coastguard Worker // underlying field, so it applies to Curve25519 itself and the quadratic
2014*8fb009dcSAndroid Build Coastguard Worker // twist of Curve25519. It was not proven in Coq that prime-field arithmetic
2015*8fb009dcSAndroid Build Coastguard Worker // correctly simulates extension-field arithmetic on prime-field values.
2016*8fb009dcSAndroid Build Coastguard Worker // The decoding of the byte array representation of e was not considered.
2017*8fb009dcSAndroid Build Coastguard Worker // Specification of Montgomery curves in affine coordinates:
2018*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Spec/MontgomeryCurve.v#L27>
2019*8fb009dcSAndroid Build Coastguard Worker // Proof that these form a group that is isomorphic to a Weierstrass curve:
2020*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/AffineProofs.v#L35>
2021*8fb009dcSAndroid Build Coastguard Worker // Coq transcription and correctness proof of the loop (where scalarbits=255):
2022*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZ.v#L118>
2023*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L278>
2024*8fb009dcSAndroid Build Coastguard Worker // preconditions: 0 <= e < 2^255 (not necessarily e < order), fe_invert(0) = 0
2025*8fb009dcSAndroid Build Coastguard Worker fe_frombytes(&x1, point);
2026*8fb009dcSAndroid Build Coastguard Worker fe_1(&x2);
2027*8fb009dcSAndroid Build Coastguard Worker fe_0(&z2);
2028*8fb009dcSAndroid Build Coastguard Worker fe_copy(&x3, &x1);
2029*8fb009dcSAndroid Build Coastguard Worker fe_1(&z3);
2030*8fb009dcSAndroid Build Coastguard Worker
2031*8fb009dcSAndroid Build Coastguard Worker unsigned swap = 0;
2032*8fb009dcSAndroid Build Coastguard Worker int pos;
2033*8fb009dcSAndroid Build Coastguard Worker for (pos = 254; pos >= 0; --pos) {
2034*8fb009dcSAndroid Build Coastguard Worker // loop invariant as of right before the test, for the case where x1 != 0:
2035*8fb009dcSAndroid Build Coastguard Worker // pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 is nonzero
2036*8fb009dcSAndroid Build Coastguard Worker // let r := e >> (pos+1) in the following equalities of projective points:
2037*8fb009dcSAndroid Build Coastguard Worker // to_xz (r*P) === if swap then (x3, z3) else (x2, z2)
2038*8fb009dcSAndroid Build Coastguard Worker // to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3)
2039*8fb009dcSAndroid Build Coastguard Worker // x1 is the nonzero x coordinate of the nonzero point (r*P-(r+1)*P)
2040*8fb009dcSAndroid Build Coastguard Worker unsigned b = 1 & (e[pos / 8] >> (pos & 7));
2041*8fb009dcSAndroid Build Coastguard Worker swap ^= b;
2042*8fb009dcSAndroid Build Coastguard Worker fe_cswap(&x2, &x3, swap);
2043*8fb009dcSAndroid Build Coastguard Worker fe_cswap(&z2, &z3, swap);
2044*8fb009dcSAndroid Build Coastguard Worker swap = b;
2045*8fb009dcSAndroid Build Coastguard Worker // Coq transcription of ladderstep formula (called from transcribed loop):
2046*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZ.v#L89>
2047*8fb009dcSAndroid Build Coastguard Worker // <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L131>
2048*8fb009dcSAndroid Build Coastguard Worker // x1 != 0 <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L217>
2049*8fb009dcSAndroid Build Coastguard Worker // x1 = 0 <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L147>
2050*8fb009dcSAndroid Build Coastguard Worker fe_sub(&tmp0l, &x3, &z3);
2051*8fb009dcSAndroid Build Coastguard Worker fe_sub(&tmp1l, &x2, &z2);
2052*8fb009dcSAndroid Build Coastguard Worker fe_add(&x2l, &x2, &z2);
2053*8fb009dcSAndroid Build Coastguard Worker fe_add(&z2l, &x3, &z3);
2054*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&z3, &tmp0l, &x2l);
2055*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&z2, &z2l, &tmp1l);
2056*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&tmp0, &tmp1l);
2057*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&tmp1, &x2l);
2058*8fb009dcSAndroid Build Coastguard Worker fe_add(&x3l, &z3, &z2);
2059*8fb009dcSAndroid Build Coastguard Worker fe_sub(&z2l, &z3, &z2);
2060*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&x2, &tmp1, &tmp0);
2061*8fb009dcSAndroid Build Coastguard Worker fe_sub(&tmp1l, &tmp1, &tmp0);
2062*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&z2, &z2l);
2063*8fb009dcSAndroid Build Coastguard Worker fe_mul121666(&z3, &tmp1l);
2064*8fb009dcSAndroid Build Coastguard Worker fe_sq_tl(&x3, &x3l);
2065*8fb009dcSAndroid Build Coastguard Worker fe_add(&tmp0l, &tmp0, &z3);
2066*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&z3, &x1, &z2);
2067*8fb009dcSAndroid Build Coastguard Worker fe_mul_tll(&z2, &tmp1l, &tmp0l);
2068*8fb009dcSAndroid Build Coastguard Worker }
2069*8fb009dcSAndroid Build Coastguard Worker // here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) else (x2, z2)
2070*8fb009dcSAndroid Build Coastguard Worker fe_cswap(&x2, &x3, swap);
2071*8fb009dcSAndroid Build Coastguard Worker fe_cswap(&z2, &z3, swap);
2072*8fb009dcSAndroid Build Coastguard Worker
2073*8fb009dcSAndroid Build Coastguard Worker fe_invert(&z2, &z2);
2074*8fb009dcSAndroid Build Coastguard Worker fe_mul_ttt(&x2, &x2, &z2);
2075*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(out, &x2);
2076*8fb009dcSAndroid Build Coastguard Worker }
2077*8fb009dcSAndroid Build Coastguard Worker
x25519_scalar_mult(uint8_t out[32],const uint8_t scalar[32],const uint8_t point[32])2078*8fb009dcSAndroid Build Coastguard Worker static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
2079*8fb009dcSAndroid Build Coastguard Worker const uint8_t point[32]) {
2080*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_X25519_NEON)
2081*8fb009dcSAndroid Build Coastguard Worker if (CRYPTO_is_NEON_capable()) {
2082*8fb009dcSAndroid Build Coastguard Worker x25519_NEON(out, scalar, point);
2083*8fb009dcSAndroid Build Coastguard Worker return;
2084*8fb009dcSAndroid Build Coastguard Worker }
2085*8fb009dcSAndroid Build Coastguard Worker #elif defined(BORINGSSL_FE25519_ADX)
2086*8fb009dcSAndroid Build Coastguard Worker if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() &&
2087*8fb009dcSAndroid Build Coastguard Worker CRYPTO_is_ADX_capable()) {
2088*8fb009dcSAndroid Build Coastguard Worker x25519_scalar_mult_adx(out, scalar, point);
2089*8fb009dcSAndroid Build Coastguard Worker return;
2090*8fb009dcSAndroid Build Coastguard Worker }
2091*8fb009dcSAndroid Build Coastguard Worker #endif
2092*8fb009dcSAndroid Build Coastguard Worker
2093*8fb009dcSAndroid Build Coastguard Worker x25519_scalar_mult_generic(out, scalar, point);
2094*8fb009dcSAndroid Build Coastguard Worker }
2095*8fb009dcSAndroid Build Coastguard Worker
X25519_keypair(uint8_t out_public_value[32],uint8_t out_private_key[32])2096*8fb009dcSAndroid Build Coastguard Worker void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) {
2097*8fb009dcSAndroid Build Coastguard Worker RAND_bytes(out_private_key, 32);
2098*8fb009dcSAndroid Build Coastguard Worker
2099*8fb009dcSAndroid Build Coastguard Worker // All X25519 implementations should decode scalars correctly (see
2100*8fb009dcSAndroid Build Coastguard Worker // https://tools.ietf.org/html/rfc7748#section-5). However, if an
2101*8fb009dcSAndroid Build Coastguard Worker // implementation doesn't then it might interoperate with random keys a
2102*8fb009dcSAndroid Build Coastguard Worker // fraction of the time because they'll, randomly, happen to be correctly
2103*8fb009dcSAndroid Build Coastguard Worker // formed.
2104*8fb009dcSAndroid Build Coastguard Worker //
2105*8fb009dcSAndroid Build Coastguard Worker // Thus we do the opposite of the masking here to make sure that our private
2106*8fb009dcSAndroid Build Coastguard Worker // keys are never correctly masked and so, hopefully, any incorrect
2107*8fb009dcSAndroid Build Coastguard Worker // implementations are deterministically broken.
2108*8fb009dcSAndroid Build Coastguard Worker //
2109*8fb009dcSAndroid Build Coastguard Worker // This does not affect security because, although we're throwing away
2110*8fb009dcSAndroid Build Coastguard Worker // entropy, a valid implementation of scalarmult should throw away the exact
2111*8fb009dcSAndroid Build Coastguard Worker // same bits anyway.
2112*8fb009dcSAndroid Build Coastguard Worker out_private_key[0] |= ~248;
2113*8fb009dcSAndroid Build Coastguard Worker out_private_key[31] &= ~64;
2114*8fb009dcSAndroid Build Coastguard Worker out_private_key[31] |= ~127;
2115*8fb009dcSAndroid Build Coastguard Worker
2116*8fb009dcSAndroid Build Coastguard Worker X25519_public_from_private(out_public_value, out_private_key);
2117*8fb009dcSAndroid Build Coastguard Worker }
2118*8fb009dcSAndroid Build Coastguard Worker
X25519(uint8_t out_shared_key[32],const uint8_t private_key[32],const uint8_t peer_public_value[32])2119*8fb009dcSAndroid Build Coastguard Worker int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
2120*8fb009dcSAndroid Build Coastguard Worker const uint8_t peer_public_value[32]) {
2121*8fb009dcSAndroid Build Coastguard Worker static const uint8_t kZeros[32] = {0};
2122*8fb009dcSAndroid Build Coastguard Worker x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
2123*8fb009dcSAndroid Build Coastguard Worker // The all-zero output results when the input is a point of small order.
2124*8fb009dcSAndroid Build Coastguard Worker return constant_time_declassify_int(
2125*8fb009dcSAndroid Build Coastguard Worker CRYPTO_memcmp(kZeros, out_shared_key, 32)) != 0;
2126*8fb009dcSAndroid Build Coastguard Worker }
2127*8fb009dcSAndroid Build Coastguard Worker
X25519_public_from_private(uint8_t out_public_value[32],const uint8_t private_key[32])2128*8fb009dcSAndroid Build Coastguard Worker void X25519_public_from_private(uint8_t out_public_value[32],
2129*8fb009dcSAndroid Build Coastguard Worker const uint8_t private_key[32]) {
2130*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_X25519_NEON)
2131*8fb009dcSAndroid Build Coastguard Worker if (CRYPTO_is_NEON_capable()) {
2132*8fb009dcSAndroid Build Coastguard Worker static const uint8_t kMongomeryBasePoint[32] = {9};
2133*8fb009dcSAndroid Build Coastguard Worker x25519_NEON(out_public_value, private_key, kMongomeryBasePoint);
2134*8fb009dcSAndroid Build Coastguard Worker return;
2135*8fb009dcSAndroid Build Coastguard Worker }
2136*8fb009dcSAndroid Build Coastguard Worker #endif
2137*8fb009dcSAndroid Build Coastguard Worker
2138*8fb009dcSAndroid Build Coastguard Worker uint8_t e[32];
2139*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(e, private_key, 32);
2140*8fb009dcSAndroid Build Coastguard Worker e[0] &= 248;
2141*8fb009dcSAndroid Build Coastguard Worker e[31] &= 127;
2142*8fb009dcSAndroid Build Coastguard Worker e[31] |= 64;
2143*8fb009dcSAndroid Build Coastguard Worker
2144*8fb009dcSAndroid Build Coastguard Worker ge_p3 A;
2145*8fb009dcSAndroid Build Coastguard Worker x25519_ge_scalarmult_base(&A, e);
2146*8fb009dcSAndroid Build Coastguard Worker
2147*8fb009dcSAndroid Build Coastguard Worker // We only need the u-coordinate of the curve25519 point. The map is
2148*8fb009dcSAndroid Build Coastguard Worker // u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y).
2149*8fb009dcSAndroid Build Coastguard Worker fe_loose zplusy, zminusy;
2150*8fb009dcSAndroid Build Coastguard Worker fe zminusy_inv;
2151*8fb009dcSAndroid Build Coastguard Worker fe_add(&zplusy, &A.Z, &A.Y);
2152*8fb009dcSAndroid Build Coastguard Worker fe_sub(&zminusy, &A.Z, &A.Y);
2153*8fb009dcSAndroid Build Coastguard Worker fe_loose_invert(&zminusy_inv, &zminusy);
2154*8fb009dcSAndroid Build Coastguard Worker fe_mul_tlt(&zminusy_inv, &zplusy, &zminusy_inv);
2155*8fb009dcSAndroid Build Coastguard Worker fe_tobytes(out_public_value, &zminusy_inv);
2156*8fb009dcSAndroid Build Coastguard Worker CONSTTIME_DECLASSIFY(out_public_value, 32);
2157*8fb009dcSAndroid Build Coastguard Worker }
2158