source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqr.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 5.4 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include "bn_lcl.h"
12
13/* r must not be a */
14/*
15 * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
16 */
17int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
18{
19 int max, al;
20 int ret = 0;
21 BIGNUM *tmp, *rr;
22
23 bn_check_top(a);
24
25 al = a->top;
26 if (al <= 0) {
27 r->top = 0;
28 r->neg = 0;
29 return 1;
30 }
31
32 BN_CTX_start(ctx);
33 rr = (a != r) ? r : BN_CTX_get(ctx);
34 tmp = BN_CTX_get(ctx);
35 if (!rr || !tmp)
36 goto err;
37
38 max = 2 * al; /* Non-zero (from above) */
39 if (bn_wexpand(rr, max) == NULL)
40 goto err;
41
42 if (al == 4) {
43#ifndef BN_SQR_COMBA
44 BN_ULONG t[8];
45 bn_sqr_normal(rr->d, a->d, 4, t);
46#else
47 bn_sqr_comba4(rr->d, a->d);
48#endif
49 } else if (al == 8) {
50#ifndef BN_SQR_COMBA
51 BN_ULONG t[16];
52 bn_sqr_normal(rr->d, a->d, 8, t);
53#else
54 bn_sqr_comba8(rr->d, a->d);
55#endif
56 } else {
57#if defined(BN_RECURSION)
58 if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
59 BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
60 bn_sqr_normal(rr->d, a->d, al, t);
61 } else {
62 int j, k;
63
64 j = BN_num_bits_word((BN_ULONG)al);
65 j = 1 << (j - 1);
66 k = j + j;
67 if (al == j) {
68 if (bn_wexpand(tmp, k * 2) == NULL)
69 goto err;
70 bn_sqr_recursive(rr->d, a->d, al, tmp->d);
71 } else {
72 if (bn_wexpand(tmp, max) == NULL)
73 goto err;
74 bn_sqr_normal(rr->d, a->d, al, tmp->d);
75 }
76 }
77#else
78 if (bn_wexpand(tmp, max) == NULL)
79 goto err;
80 bn_sqr_normal(rr->d, a->d, al, tmp->d);
81#endif
82 }
83
84 rr->neg = 0;
85 /*
86 * If the most-significant half of the top word of 'a' is zero, then the
87 * square of 'a' will max-1 words.
88 */
89 if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
90 rr->top = max - 1;
91 else
92 rr->top = max;
93 if (r != rr && BN_copy(r, rr) == NULL)
94 goto err;
95
96 ret = 1;
97 err:
98 bn_check_top(rr);
99 bn_check_top(tmp);
100 BN_CTX_end(ctx);
101 return (ret);
102}
103
104/* tmp must have 2*n words */
105void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
106{
107 int i, j, max;
108 const BN_ULONG *ap;
109 BN_ULONG *rp;
110
111 max = n * 2;
112 ap = a;
113 rp = r;
114 rp[0] = rp[max - 1] = 0;
115 rp++;
116 j = n;
117
118 if (--j > 0) {
119 ap++;
120 rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
121 rp += 2;
122 }
123
124 for (i = n - 2; i > 0; i--) {
125 j--;
126 ap++;
127 rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
128 rp += 2;
129 }
130
131 bn_add_words(r, r, r, max);
132
133 /* There will not be a carry */
134
135 bn_sqr_words(tmp, a, n);
136
137 bn_add_words(r, r, tmp, max);
138}
139
140#ifdef BN_RECURSION
141/*-
142 * r is 2*n words in size,
143 * a and b are both n words in size. (There's not actually a 'b' here ...)
144 * n must be a power of 2.
145 * We multiply and return the result.
146 * t must be 2*n words in size
147 * We calculate
148 * a[0]*b[0]
149 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
150 * a[1]*b[1]
151 */
152void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
153{
154 int n = n2 / 2;
155 int zero, c1;
156 BN_ULONG ln, lo, *p;
157
158 if (n2 == 4) {
159# ifndef BN_SQR_COMBA
160 bn_sqr_normal(r, a, 4, t);
161# else
162 bn_sqr_comba4(r, a);
163# endif
164 return;
165 } else if (n2 == 8) {
166# ifndef BN_SQR_COMBA
167 bn_sqr_normal(r, a, 8, t);
168# else
169 bn_sqr_comba8(r, a);
170# endif
171 return;
172 }
173 if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
174 bn_sqr_normal(r, a, n2, t);
175 return;
176 }
177 /* r=(a[0]-a[1])*(a[1]-a[0]) */
178 c1 = bn_cmp_words(a, &(a[n]), n);
179 zero = 0;
180 if (c1 > 0)
181 bn_sub_words(t, a, &(a[n]), n);
182 else if (c1 < 0)
183 bn_sub_words(t, &(a[n]), a, n);
184 else
185 zero = 1;
186
187 /* The result will always be negative unless it is zero */
188 p = &(t[n2 * 2]);
189
190 if (!zero)
191 bn_sqr_recursive(&(t[n2]), t, n, p);
192 else
193 memset(&t[n2], 0, sizeof(*t) * n2);
194 bn_sqr_recursive(r, a, n, p);
195 bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
196
197 /*-
198 * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
199 * r[10] holds (a[0]*b[0])
200 * r[32] holds (b[1]*b[1])
201 */
202
203 c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
204
205 /* t[32] is negative */
206 c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
207
208 /*-
209 * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
210 * r[10] holds (a[0]*a[0])
211 * r[32] holds (a[1]*a[1])
212 * c1 holds the carry bits
213 */
214 c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
215 if (c1) {
216 p = &(r[n + n2]);
217 lo = *p;
218 ln = (lo + c1) & BN_MASK2;
219 *p = ln;
220
221 /*
222 * The overflow will stop before we over write words we should not
223 * overwrite
224 */
225 if (ln < (BN_ULONG)c1) {
226 do {
227 p++;
228 lo = *p;
229 ln = (lo + 1) & BN_MASK2;
230 *p = ln;
231 } while (ln == 0);
232 }
233 }
234}
235#endif
Note: See TracBrowser for help on using the repository browser.