/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/crypto/limbs/limbs.inl
Line  | Count  | Source  | 
1  |  | /* Copyright 2016 Brian Smith.  | 
2  |  |  *  | 
3  |  |  * Permission to use, copy, modify, and/or distribute this software for any  | 
4  |  |  * purpose with or without fee is hereby granted, provided that the above  | 
5  |  |  * copyright notice and this permission notice appear in all copies.  | 
6  |  |  *  | 
7  |  |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES  | 
8  |  |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF  | 
9  |  |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY  | 
10  |  |  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES  | 
11  |  |  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION  | 
12  |  |  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN  | 
13  |  |  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */  | 
14  |  |  | 
15  |  | #include "limbs.h"  | 
16  |  | #include "ring-core/check.h"  | 
17  |  |  | 
18  |  | #if defined(_MSC_VER) && !defined(__clang__)  | 
19  |  | #pragma warning(push, 3)  | 
20  |  | #include <intrin.h>  | 
21  |  | #pragma warning(pop)  | 
22  |  |  | 
23  |  | /* MSVC 2015 RC, when compiling for x86 with /Ox (at least), miscompiles  | 
24  |  |  * _addcarry_u32(c, 0, prod_hi, &x) like so:  | 
25  |  |  *  | 
26  |  |  *     add eax,esi ; The previous add that might have set the carry flag.  | 
27  |  |  *     xor esi,esi ; OOPS! Carry flag is now reset!  | 
28  |  |  *     mov dword ptr [edi-4],eax  | 
29  |  |  *     adc esi,dword ptr [prod_hi]  | 
30  |  |  *  | 
31  |  |  * We test with MSVC 2015 update 2, so make sure we're using a version at least  | 
32  |  |  * as new as that. */  | 
33  |  | #if _MSC_FULL_VER < 190023918  | 
34  |  | #error "MSVC 2015 Update 2 or later is required."  | 
35  |  | #endif  | 
36  |  | typedef uint8_t Carry;  | 
37  |  | #if LIMB_BITS == 64  | 
38  |  | #pragma intrinsic(_addcarry_u64, _subborrow_u64)  | 
39  |  | #define RING_CORE_ADDCARRY_INTRINSIC _addcarry_u64  | 
40  |  | #define RING_CORE_SUBBORROW_INTRINSIC _subborrow_u64  | 
41  |  | #elif LIMB_BITS == 32  | 
42  |  | #pragma intrinsic(_addcarry_u32, _subborrow_u32)  | 
43  |  | #define RING_CORE_ADDCARRY_INTRINSIC _addcarry_u32  | 
44  |  | #define RING_CORE_SUBBORROW_INTRINSIC _subborrow_u32  | 
45  |  | typedef uint64_t DoubleLimb;  | 
46  |  | #endif  | 
47  |  | #else  | 
48  |  | typedef Limb Carry;  | 
49  |  | #if LIMB_BITS == 64  | 
50  |  | typedef __uint128_t DoubleLimb;  | 
51  |  | #elif LIMB_BITS == 32  | 
52  |  | typedef uint64_t DoubleLimb;  | 
53  |  | #endif  | 
54  |  | #endif  | 
55  |  |  | 
56  |  | /* |*r = a + b + carry_in|, returning carry out bit. |carry_in| must be 0 or 1.  | 
57  |  |  */  | 
58  | 0  | static inline Carry limb_adc(Limb *r, Limb a, Limb b, Carry carry_in) { | 
59  | 0  |   dev_assert_secret(carry_in == 0 || carry_in == 1);  | 
60  | 0  |   Carry ret;  | 
61  |  | #if defined(RING_CORE_ADDCARRY_INTRINSIC)  | 
62  |  |   ret = RING_CORE_ADDCARRY_INTRINSIC(carry_in, a, b, r);  | 
63  |  | #else  | 
64  | 0  |   DoubleLimb x = (DoubleLimb)a + b + carry_in;  | 
65  | 0  |   *r = (Limb)x;  | 
66  | 0  |   ret = (Carry)(x >> LIMB_BITS);  | 
67  | 0  | #endif  | 
68  | 0  |   dev_assert_secret(ret == 0 || ret == 1);  | 
69  | 0  |   return ret;  | 
70  | 0  | } Unexecuted instantiation: montgomery.c:limb_adc Unexecuted instantiation: gfp_p384.c:limb_adc Unexecuted instantiation: limbs.c:limb_adc Unexecuted instantiation: p256-nistz.c:limb_adc  | 
71  |  |  | 
72  |  | /* |*r = a + b|, returning carry bit. */  | 
73  | 0  | static inline Carry limb_add(Limb *r, Limb a, Limb b) { | 
74  | 0  |   Carry ret;  | 
75  |  | #if defined(RING_CORE_ADDCARRY_INTRINSIC)  | 
76  |  |   ret = RING_CORE_ADDCARRY_INTRINSIC(0, a, b, r);  | 
77  |  | #else  | 
78  | 0  |   DoubleLimb x = (DoubleLimb)a + b;  | 
79  | 0  |   *r = (Limb)x;  | 
80  | 0  |   ret = (Carry)(x >> LIMB_BITS);  | 
81  | 0  | #endif  | 
82  | 0  |   dev_assert_secret(ret == 0 || ret == 1);  | 
83  | 0  |   return ret;  | 
84  | 0  | } Unexecuted instantiation: montgomery.c:limb_add Unexecuted instantiation: gfp_p384.c:limb_add Unexecuted instantiation: limbs.c:limb_add Unexecuted instantiation: p256-nistz.c:limb_add  | 
85  |  |  | 
86  |  | /* |*r = a - b - borrow_in|, returning the borrow out bit. |borrow_in| must be  | 
87  |  |  * 0 or 1. */  | 
88  | 0  | static inline Carry limb_sbb(Limb *r, Limb a, Limb b, Carry borrow_in) { | 
89  | 0  |   dev_assert_secret(borrow_in == 0 || borrow_in == 1);  | 
90  | 0  |   Carry ret;  | 
91  |  | #if defined(RING_CORE_SUBBORROW_INTRINSIC)  | 
92  |  |   ret = RING_CORE_SUBBORROW_INTRINSIC(borrow_in, a, b, r);  | 
93  |  | #else  | 
94  | 0  |   DoubleLimb x = (DoubleLimb)a - b - borrow_in;  | 
95  | 0  |   *r = (Limb)x;  | 
96  | 0  |   ret = (Carry)((x >> LIMB_BITS) & 1);  | 
97  | 0  | #endif  | 
98  | 0  |   dev_assert_secret(ret == 0 || ret == 1);  | 
99  | 0  |   return ret;  | 
100  | 0  | } Unexecuted instantiation: montgomery.c:limb_sbb Unexecuted instantiation: gfp_p384.c:limb_sbb Unexecuted instantiation: limbs.c:limb_sbb Unexecuted instantiation: p256-nistz.c:limb_sbb  | 
101  |  |  | 
102  |  | /* |*r = a - b|, returning borrow bit. */  | 
103  | 0  | static inline Carry limb_sub(Limb *r, Limb a, Limb b) { | 
104  | 0  |   Carry ret;  | 
105  |  | #if defined(RING_CORE_SUBBORROW_INTRINSIC)  | 
106  |  |   ret = RING_CORE_SUBBORROW_INTRINSIC(0, a, b, r);  | 
107  |  | #else  | 
108  | 0  |   DoubleLimb x = (DoubleLimb)a - b;  | 
109  | 0  |   *r = (Limb)x;  | 
110  | 0  |   ret = (Carry)((x >> LIMB_BITS) & 1);  | 
111  | 0  | #endif  | 
112  | 0  |   dev_assert_secret(ret == 0 || ret == 1);  | 
113  | 0  |   return ret;  | 
114  | 0  | } Unexecuted instantiation: montgomery.c:limb_sub Unexecuted instantiation: gfp_p384.c:limb_sub Unexecuted instantiation: limbs.c:limb_sub Unexecuted instantiation: p256-nistz.c:limb_sub  | 
115  |  |  | 
116  |  | static inline Carry limbs_add(Limb r[], const Limb a[], const Limb b[],  | 
117  | 0  |                               size_t num_limbs) { | 
118  | 0  |   debug_assert_nonsecret(num_limbs >= 1);  | 
119  | 0  |   Carry carry = limb_add(&r[0], a[0], b[0]);  | 
120  | 0  |   for (size_t i = 1; i < num_limbs; ++i) { | 
121  | 0  |     carry = limb_adc(&r[i], a[i], b[i], carry);  | 
122  | 0  |   }  | 
123  | 0  |   return carry;  | 
124  | 0  | } Unexecuted instantiation: montgomery.c:limbs_add Unexecuted instantiation: gfp_p384.c:limbs_add Unexecuted instantiation: limbs.c:limbs_add Unexecuted instantiation: p256-nistz.c:limbs_add  | 
125  |  |  | 
126  |  | /* |r -= s|, returning the borrow. */  | 
127  |  | static inline Carry limbs_sub(Limb r[], const Limb a[], const Limb b[],  | 
128  | 0  |                               size_t num_limbs) { | 
129  | 0  |   debug_assert_nonsecret(num_limbs >= 1);  | 
130  | 0  |   Carry borrow = limb_sub(&r[0], a[0], b[0]);  | 
131  | 0  |   for (size_t i = 1; i < num_limbs; ++i) { | 
132  | 0  |     borrow = limb_sbb(&r[i], a[i], b[i], borrow);  | 
133  | 0  |   }  | 
134  | 0  |   return borrow;  | 
135  | 0  | } Unexecuted instantiation: montgomery.c:limbs_sub Unexecuted instantiation: gfp_p384.c:limbs_sub Unexecuted instantiation: limbs.c:limbs_sub Unexecuted instantiation: p256-nistz.c:limbs_sub  | 
136  |  |  | 
137  | 0  | static inline void limbs_copy(Limb r[], const Limb a[], size_t num_limbs) { | 
138  | 0  |   for (size_t i = 0; i < num_limbs; ++i) { | 
139  | 0  |     r[i] = a[i];  | 
140  | 0  |   }  | 
141  | 0  | } Unexecuted instantiation: montgomery.c:limbs_copy Unexecuted instantiation: gfp_p384.c:limbs_copy Unexecuted instantiation: limbs.c:limbs_copy Unexecuted instantiation: p256-nistz.c:limbs_copy  | 
142  |  |  | 
143  |  | static inline void limbs_select(Limb r[], const Limb table[],  | 
144  |  |                                 size_t num_limbs, size_t num_entries,  | 
145  | 0  |                                 crypto_word_t index) { | 
146  | 0  |   for (size_t i = 0; i < num_limbs; ++i) { | 
147  | 0  |     r[i] = 0;  | 
148  | 0  |   }  | 
149  |  | 
  | 
150  | 0  |   for (size_t e = 0; e < num_entries; ++e) { | 
151  | 0  |     Limb equal = constant_time_eq_w(index, e);  | 
152  | 0  |     for (size_t i = 0; i < num_limbs; ++i) { | 
153  | 0  |       r[i] = constant_time_select_w(equal, table[(e * num_limbs) + i], r[i]);  | 
154  | 0  |     }  | 
155  | 0  |   }  | 
156  | 0  | } Unexecuted instantiation: montgomery.c:limbs_select Unexecuted instantiation: gfp_p384.c:limbs_select Unexecuted instantiation: limbs.c:limbs_select Unexecuted instantiation: p256-nistz.c:limbs_select  | 
157  |  |  | 
158  | 0  | static inline void limbs_zero(Limb r[], size_t num_limbs) { | 
159  | 0  |   for (size_t i = 0; i < num_limbs; ++i) { | 
160  | 0  |     r[i] = 0;  | 
161  | 0  |   }  | 
162  | 0  | } Unexecuted instantiation: montgomery.c:limbs_zero Unexecuted instantiation: gfp_p384.c:limbs_zero Unexecuted instantiation: limbs.c:limbs_zero Unexecuted instantiation: p256-nistz.c:limbs_zero  |