summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_add_sub.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_add_sub.c')
-rw-r--r--src/lib/libcrypto/bn/bn_add_sub.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/lib/libcrypto/bn/bn_add_sub.c b/src/lib/libcrypto/bn/bn_add_sub.c
new file mode 100644
index 0000000000..5c9d5a2b1a
--- /dev/null
+++ b/src/lib/libcrypto/bn/bn_add_sub.c
@@ -0,0 +1,178 @@
1/* $OpenBSD: bn_add_sub.c,v 1.1 2025/05/25 04:30:55 jsing Exp $ */
2/*
3 * Copyright (c) 2023,2024,2025 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <openssl/bn.h>
19
20#include "bn_internal.h"
21
22/*
23 * bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b
24 * are both arrays of words. Any carry resulting from the addition is returned.
25 */
26#ifndef HAVE_BN_ADD_WORDS
27BN_ULONG
28bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
29{
30 BN_ULONG carry = 0;
31
32 while (n >= 4) {
33 bn_qwaddqw(a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0],
34 carry, &carry, &r[3], &r[2], &r[1], &r[0]);
35 a += 4;
36 b += 4;
37 r += 4;
38 n -= 4;
39 }
40 while (n > 0) {
41 bn_addw_addw(a[0], b[0], carry, &carry, &r[0]);
42 a++;
43 b++;
44 r++;
45 n--;
46 }
47
48 return carry;
49}
50#endif
51
52/*
53 * bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b
54 * are both arrays of words. Any borrow resulting from the subtraction is
55 * returned.
56 */
57#ifndef HAVE_BN_SUB_WORDS
58BN_ULONG
59bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
60{
61 BN_ULONG borrow = 0;
62
63 while (n >= 4) {
64 bn_qwsubqw(a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0],
65 borrow, &borrow, &r[3], &r[2], &r[1], &r[0]);
66 a += 4;
67 b += 4;
68 r += 4;
69 n -= 4;
70 }
71 while (n > 0) {
72 bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]);
73 a++;
74 b++;
75 r++;
76 n--;
77 }
78
79 return borrow;
80}
81#endif
82
83/*
84 * bn_sub_borrow() computes a[i] - b[i], returning the resulting borrow only.
85 */
86#ifndef HAVE_BN_SUB_WORDS_BORROW
87BN_ULONG
88bn_sub_words_borrow(const BN_ULONG *a, const BN_ULONG *b, size_t n)
89{
90 BN_ULONG borrow = 0;
91 BN_ULONG r;
92
93 while (n >= 4) {
94 bn_qwsubqw(a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0],
95 borrow, &borrow, &r, &r, &r, &r);
96 a += 4;
97 b += 4;
98 n -= 4;
99 }
100 while (n > 0) {
101 bn_subw_subw(a[0], b[0], borrow, &borrow, &r);
102 a++;
103 b++;
104 n--;
105 }
106
107 return borrow;
108}
109#endif
110
111/*
112 * bn_add_words_masked() computes r[] = a[] + (b[] & mask), where a, b and r are
113 * arrays of words with length n (r may be the same as a or b).
114 */
115#ifndef HAVE_BN_ADD_WORDS_MASKED
116BN_ULONG
117bn_add_words_masked(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
118 BN_ULONG mask, size_t n)
119{
120 BN_ULONG carry = 0;
121
122 /* XXX - consider conditional/masked versions of bn_addw_addw/bn_qwaddqw. */
123
124 while (n >= 4) {
125 bn_qwaddqw(a[3], a[2], a[1], a[0], b[3] & mask, b[2] & mask,
126 b[1] & mask, b[0] & mask, carry, &carry, &r[3], &r[2],
127 &r[1], &r[0]);
128 a += 4;
129 b += 4;
130 r += 4;
131 n -= 4;
132 }
133 while (n > 0) {
134 bn_addw_addw(a[0], b[0] & mask, carry, &carry, &r[0]);
135 a++;
136 b++;
137 r++;
138 n--;
139 }
140
141 return carry;
142}
143#endif
144
145/*
146 * bn_sub_words_masked() computes r[] = a[] - (b[] & mask), where a, b and r are
147 * arrays of words with length n (r may be the same as a or b).
148 */
149#ifndef HAVE_BN_SUB_WORDS_MASKED
150BN_ULONG
151bn_sub_words_masked(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
152 BN_ULONG mask, size_t n)
153{
154 BN_ULONG borrow = 0;
155
156 /* XXX - consider conditional/masked versions of bn_subw_subw/bn_qwsubqw. */
157
158 /* Compute conditional r[i] = a[i] - b[i]. */
159 while (n >= 4) {
160 bn_qwsubqw(a[3], a[2], a[1], a[0], b[3] & mask, b[2] & mask,
161 b[1] & mask, b[0] & mask, borrow, &borrow, &r[3], &r[2],
162 &r[1], &r[0]);
163 a += 4;
164 b += 4;
165 r += 4;
166 n -= 4;
167 }
168 while (n > 0) {
169 bn_subw_subw(a[0], b[0] & mask, borrow, &borrow, &r[0]);
170 a++;
171 b++;
172 r++;
173 n--;
174 }
175
176 return borrow;
177}
178#endif