annotate deps/Platinum/ThirdParty/Neptune/ThirdParty/axTLS/crypto/bigint.c @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
2 * Copyright (c) 2007, Cameron Rich
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
3 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
4 * All rights reserved.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
5 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
8 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
9 * * Redistributions of source code must retain the above copyright notice,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
10 * this list of conditions and the following disclaimer.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
11 * * Redistributions in binary form must reproduce the above copyright notice,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
12 * this list of conditions and the following disclaimer in the documentation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
13 * and/or other materials provided with the distribution.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
14 * * Neither the name of the axTLS project nor the names of its contributors
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
15 * may be used to endorse or promote products derived from this software
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
16 * without specific prior written permission.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
17 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
29 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
30
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
31 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
32 * @defgroup bigint_api Big Integer API
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
33 * @brief The bigint implementation as used by the axTLS project.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
34 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
35 * The bigint library is for RSA encryption/decryption as well as signing.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
36 * This code tries to minimise use of malloc/free by maintaining a small
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
37 * cache. A bigint context may maintain state by being made "permanent".
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
38 * It be be later released with a bi_depermanent() and bi_free() call.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
39 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
40 * It supports the following reduction techniques:
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
41 * - Classical
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
42 * - Barrett
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
43 * - Montgomery
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
44 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
45 * It also implements the following:
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
46 * - Karatsuba multiplication
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
47 * - Squaring
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
48 * - Sliding window exponentiation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
49 * - Chinese Remainder Theorem (implemented in rsa.c).
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
50 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
51 * All the algorithms used are pretty standard, and designed for different
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
52 * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
53 * may need to be tested for negativity.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
54 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
55 * This library steals some ideas from Jef Poskanzer
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
56 * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
57 * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
58 * detail from "The Handbook of Applied Cryptography"
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
59 * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
60 * @{
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
61 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
62
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
63 #include <stdlib.h>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
64 #include <limits.h>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
65 #include <string.h>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
66 #include <stdio.h>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
67 #include <time.h>
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
68 #include "bigint.h"
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
69
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
70 #define V1 v->comps[v->size-1] /**< v1 for division */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
71 #define V2 v->comps[v->size-2] /**< v2 for division */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
72 #define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
73 #define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
74
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
75 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
76 static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
77 static bigint *alloc(BI_CTX *ctx, int size);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
78 static bigint *trim(bigint *bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
79 static void more_comps(bigint *bi, int n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
80 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
81 defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
82 static bigint *comp_right_shift(bigint *biR, int num_shifts);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
83 static bigint *comp_left_shift(bigint *biR, int num_shifts);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
84 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
85
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
86 #ifdef CONFIG_BIGINT_CHECK_ON
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
87 static void check(const bigint *bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
88 #else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
89 #define check(A) /**< disappears in normal production mode */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
90 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
91
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
92
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
93 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
94 * @brief Start a new bigint context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
95 * @return A bigint context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
96 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
97 BI_CTX *bi_initialize(void)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
98 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
99 /* calloc() sets everything to zero */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
100 BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
101
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
102 /* the radix */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
103 ctx->bi_radix = alloc(ctx, 2);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
104 ctx->bi_radix->comps[0] = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
105 ctx->bi_radix->comps[1] = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
106 bi_permanent(ctx->bi_radix);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
107 return ctx;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
108 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
109
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
110 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
111 * @brief Close the bigint context and free any resources.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
112 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
113 * Free up any used memory - a check is done if all objects were not
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
114 * properly freed.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
115 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
116 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
117 void bi_terminate(BI_CTX *ctx)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
118 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
119 bi_depermanent(ctx->bi_radix);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
120 bi_free(ctx, ctx->bi_radix);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
121
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
122 if (ctx->active_count != 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
123 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
124 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
125 printf("bi_terminate: there were %d un-freed bigints\n",
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
126 ctx->active_count);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
127 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
128 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
129 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
130
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
131 bi_clear_cache(ctx);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
132 free(ctx);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
133 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
134
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
135 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
136 *@brief Clear the memory cache.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
137 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
138 void bi_clear_cache(BI_CTX *ctx)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
139 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
140 bigint *p, *pn;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
141
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
142 if (ctx->free_list == NULL)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
143 return;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
144
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
145 for (p = ctx->free_list; p != NULL; p = pn)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
146 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
147 pn = p->next;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
148 free(p->comps);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
149 free(p);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
150 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
151
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
152 ctx->free_count = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
153 ctx->free_list = NULL;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
154 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
155
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
156 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
157 * @brief Increment the number of references to this object.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
158 * It does not do a full copy.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
159 * @param bi [in] The bigint to copy.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
160 * @return A reference to the same bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
161 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
162 bigint *bi_copy(bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
163 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
164 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
165 if (bi->refs != PERMANENT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
166 bi->refs++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
167 return bi;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
168 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
169
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
170 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
171 * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
172 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
173 * For this object to be freed, bi_depermanent() must be called.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
174 * @param bi [in] The bigint to be made permanent.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
175 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
176 void bi_permanent(bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
177 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
178 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
179 if (bi->refs != 1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
180 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
181 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
182 printf("bi_permanent: refs was not 1\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
183 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
184 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
185 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
186
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
187 bi->refs = PERMANENT;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
188 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
189
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
190 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
191 * @brief Take a permanent object and make it eligible for freedom.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
192 * @param bi [in] The bigint to be made back to temporary.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
193 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
194 void bi_depermanent(bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
195 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
196 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
197 if (bi->refs != PERMANENT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
198 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
199 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
200 printf("bi_depermanent: bigint was not permanent\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
201 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
202 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
203 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
204
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
205 bi->refs = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
206 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
207
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
208 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
209 * @brief Free a bigint object so it can be used again.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
210 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
211 * The memory itself it not actually freed, just tagged as being available
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
212 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
213 * @param bi [in] The bigint to be freed.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
214 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
215 void bi_free(BI_CTX *ctx, bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
216 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
217 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
218 if (bi->refs == PERMANENT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
219 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
220 return;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
221 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
222
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
223 if (--bi->refs > 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
224 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
225 return;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
226 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
227
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
228 bi->next = ctx->free_list;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
229 ctx->free_list = bi;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
230 ctx->free_count++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
231
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
232 if (--ctx->active_count < 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
233 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
234 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
235 printf("bi_free: active_count went negative "
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
236 "- double-freed bigint?\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
237 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
238 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
239 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
240 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
241
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
242 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
243 * @brief Convert an (unsigned) integer into a bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
244 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
245 * @param i [in] The (unsigned) integer to be converted.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
246 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
247 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
248 bigint *int_to_bi(BI_CTX *ctx, comp i)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
249 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
250 bigint *biR = alloc(ctx, 1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
251 biR->comps[0] = i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
252 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
253 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
254
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
255 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
256 * @brief Do a full copy of the bigint object.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
257 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
258 * @param bi [in] The bigint object to be copied.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
259 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
260 bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
261 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
262 bigint *biR = alloc(ctx, bi->size);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
263 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
264 memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
265 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
266 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
267
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
268 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
269 * @brief Perform an addition operation between two bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
270 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
271 * @param bia [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
272 * @param bib [in] Another bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
273 * @return The result of the addition.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
274 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
275 bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
276 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
277 int n;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
278 comp carry = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
279 comp *pa, *pb;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
280
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
281 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
282 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
283
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
284 n = max(bia->size, bib->size);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
285 more_comps(bia, n+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
286 more_comps(bib, n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
287 pa = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
288 pb = bib->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
289
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
290 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
291 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
292 comp sl, rl, cy1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
293 sl = *pa + *pb++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
294 rl = sl + carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
295 cy1 = sl < *pa;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
296 carry = cy1 | (rl < sl);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
297 *pa++ = rl;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
298 } while (--n != 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
299
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
300 *pa = carry; /* do overflow */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
301 bi_free(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
302 return trim(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
303 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
304
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
305 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
306 * @brief Perform a subtraction operation between two bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
307 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
308 * @param bia [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
309 * @param bib [in] Another bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
310 * @param is_negative [out] If defined, indicates that the result was negative.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
311 * is_negative may be null.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
312 * @return The result of the subtraction. The result is always positive.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
313 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
314 bigint *bi_subtract(BI_CTX *ctx,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
315 bigint *bia, bigint *bib, int *is_negative)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
316 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
317 int n = bia->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
318 comp *pa, *pb, carry = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
319
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
320 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
321 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
322
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
323 more_comps(bib, n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
324 pa = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
325 pb = bib->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
326
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
327 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
328 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
329 comp sl, rl, cy1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
330 sl = *pa - *pb++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
331 rl = sl - carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
332 cy1 = sl > *pa;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
333 carry = cy1 | (rl > sl);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
334 *pa++ = rl;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
335 } while (--n != 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
336
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
337 if (is_negative) /* indicate a negative result */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
338 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
339 *is_negative = carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
340 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
341
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
342 bi_free(ctx, trim(bib)); /* put bib back to the way it was */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
343 return trim(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
344 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
345
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
346 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
347 * Perform a multiply between a bigint an an (unsigned) integer
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
348 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
349 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
350 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
351 int j = 0, n = bia->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
352 bigint *biR = alloc(ctx, n + 1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
353 comp carry = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
354 comp *r = biR->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
355 comp *a = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
356
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
357 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
358
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
359 /* clear things to start with */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
360 memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
361
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
362 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
363 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
364 long_comp tmp = *r + (long_comp)a[j]*b + carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
365 *r++ = (comp)tmp; /* downsize */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
366 carry = (comp)(tmp >> COMP_BIT_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
367 } while (++j < n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
368
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
369 *r = carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
370 bi_free(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
371 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
372 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
373
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
374 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
375 * @brief Does both division and modulo calculations.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
376 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
377 * Used extensively when doing classical reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
378 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
379 * @param u [in] A bigint which is the numerator.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
380 * @param v [in] Either the denominator or the modulus depending on the mode.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
381 * @param is_mod [n] Determines if this is a normal division (0) or a reduction
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
382 * (1).
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
383 * @return The result of the division/reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
384 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
385 bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
386 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
387 int n = v->size, m = u->size-n;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
388 int j = 0, orig_u_size = u->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
389 uint8_t mod_offset = ctx->mod_offset;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
390 comp d;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
391 bigint *quotient, *tmp_u;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
392 comp q_dash;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
393
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
394 check(u);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
395 check(v);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
396
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
397 /* if doing reduction and we are < mod, then return mod */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
398 if (is_mod && bi_compare(v, u) > 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
399 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
400 bi_free(ctx, v);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
401 return u;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
402 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
403
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
404 quotient = alloc(ctx, m+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
405 tmp_u = alloc(ctx, n+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
406 v = trim(v); /* make sure we have no leading 0's */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
407 d = (comp)((long_comp)COMP_RADIX/(V1+1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
408
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
409 /* clear things to start with */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
410 memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
411
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
412 /* normalise */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
413 if (d > 1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
414 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
415 u = bi_int_multiply(ctx, u, d);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
416
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
417 if (is_mod)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
418 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
419 v = ctx->bi_normalised_mod[mod_offset];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
420 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
421 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
422 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
423 v = bi_int_multiply(ctx, v, d);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
424 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
425 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
426
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
427 if (orig_u_size == u->size) /* new digit position u0 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
428 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
429 more_comps(u, orig_u_size + 1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
430 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
431
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
432 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
433 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
434 /* get a temporary short version of u */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
435 memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
436
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
437 /* calculate q' */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
438 if (U(0) == V1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
439 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
440 q_dash = COMP_RADIX-1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
441 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
442 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
443 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
444 q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
445 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
446
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
447 if (v->size > 1 && V2)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
448 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
449 /* we are implementing the following:
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
450 if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
451 q_dash*V1)*COMP_RADIX) + U(2))) ... */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
452 comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
453 (long_comp)q_dash*V1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
454 if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
455 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
456 q_dash--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
457 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
458 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
459
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
460 /* multiply and subtract */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
461 if (q_dash)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
462 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
463 int is_negative;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
464 tmp_u = bi_subtract(ctx, tmp_u,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
465 bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
466 more_comps(tmp_u, n+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
467
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
468 Q(j) = q_dash;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
469
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
470 /* add back */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
471 if (is_negative)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
472 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
473 Q(j)--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
474 tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
475
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
476 /* lop off the carry */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
477 tmp_u->size--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
478 v->size--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
479 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
480 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
481 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
482 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
483 Q(j) = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
484 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
485
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
486 /* copy back to u */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
487 memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
488 } while (++j <= m);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
489
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
490 bi_free(ctx, tmp_u);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
491 bi_free(ctx, v);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
492
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
493 if (is_mod) /* get the remainder */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
494 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
495 bi_free(ctx, quotient);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
496 return bi_int_divide(ctx, trim(u), d);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
497 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
498 else /* get the quotient */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
499 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
500 bi_free(ctx, u);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
501 return trim(quotient);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
502 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
503 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
504
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
505 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
506 * Perform an integer divide on a bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
507 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
508 static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
509 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
510 int i = biR->size - 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
511 (void)ctx; /* unused */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
512 long_comp r = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
513
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
514 check(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
515
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
516 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
517 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
518 r = (r<<COMP_BIT_SIZE) + biR->comps[i];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
519 biR->comps[i] = (comp)(r / denom);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
520 r %= denom;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
521 } while (--i >= 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
522
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
523 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
524 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
525
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
526 #ifdef CONFIG_BIGINT_MONTGOMERY
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
527 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
528 * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
529 * where B^-1(B-1) mod N=1. Actually, only the least significant part of
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
530 * N' is needed, hence the definition N0'=N' mod b. We reproduce below the
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
531 * simple algorithm from an article by Dusse and Kaliski to efficiently
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
532 * find N0' from N0 and b */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
533 static comp modular_inverse(bigint *bim)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
534 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
535 int i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
536 comp t = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
537 comp two_2_i_minus_1 = 2; /* 2^(i-1) */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
538 long_comp two_2_i = 4; /* 2^i */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
539 comp N = bim->comps[0];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
540
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
541 for (i = 2; i <= COMP_BIT_SIZE; i++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
542 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
543 if ((long_comp)N*t%two_2_i >= two_2_i_minus_1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
544 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
545 t += two_2_i_minus_1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
546 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
547
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
548 two_2_i_minus_1 <<= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
549 two_2_i <<= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
550 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
551
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
552 return (comp)(COMP_RADIX-t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
553 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
554 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
555
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
556 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
557 defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
558 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
559 * Take each component and shift down (in terms of components)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
560 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
561 static bigint *comp_right_shift(bigint *biR, int num_shifts)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
562 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
563 int i = biR->size-num_shifts;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
564 comp *x = biR->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
565 comp *y = &biR->comps[num_shifts];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
566
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
567 check(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
568
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
569 if (i <= 0) /* have we completely right shifted? */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
570 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
571 biR->comps[0] = 0; /* return 0 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
572 biR->size = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
573 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
574 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
575
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
576 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
577 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
578 *x++ = *y++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
579 } while (--i > 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
580
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
581 biR->size -= num_shifts;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
582 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
583 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
584
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
585 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
586 * Take each component and shift it up (in terms of components)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
587 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
588 static bigint *comp_left_shift(bigint *biR, int num_shifts)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
589 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
590 int i = biR->size-1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
591 comp *x, *y;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
592
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
593 check(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
594
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
595 if (num_shifts <= 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
596 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
597 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
598 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
599
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
600 more_comps(biR, biR->size + num_shifts);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
601
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
602 x = &biR->comps[i+num_shifts];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
603 y = &biR->comps[i];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
604
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
605 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
606 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
607 *x-- = *y--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
608 } while (i--);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
609
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
610 memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE); /* zero LS comps */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
611 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
612 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
613 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
614
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
615 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
616 * @brief Allow a binary sequence to be imported as a bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
617 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
618 * @param data [in] The data to be converted.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
619 * @param size [in] The number of bytes of data.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
620 * @return A bigint representing this data.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
621 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
622 bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
623 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
624 bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
625 int i, j = 0, offset = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
626
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
627 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
628
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
629 for (i = size-1; i >= 0; i--)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
630 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
631 biR->comps[offset] += data[i] << (j*8);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
632
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
633 if (++j == COMP_BYTE_SIZE)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
634 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
635 j = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
636 offset ++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
637 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
638 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
639
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
640 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
641 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
642
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
643 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
644 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
645 * @brief The testharness uses this code to import text hex-streams and
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
646 * convert them into bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
647 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
648 * @param data [in] A string consisting of hex characters. The characters must
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
649 * be in upper case.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
650 * @return A bigint representing this data.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
651 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
652 bigint *bi_str_import(BI_CTX *ctx, const char *data)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
653 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
654 int size = strlen(data);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
655 bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
656 int i, j = 0, offset = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
657 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
658
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
659 for (i = size-1; i >= 0; i--)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
660 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
661 int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
662 biR->comps[offset] += num << (j*4);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
663
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
664 if (++j == COMP_NUM_NIBBLES)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
665 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
666 j = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
667 offset ++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
668 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
669 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
670
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
671 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
672 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
673
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
674 void bi_print(const char *label, bigint *x)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
675 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
676 int i, j;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
677
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
678 if (x == NULL)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
679 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
680 printf("%s: (null)\n", label);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
681 return;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
682 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
683
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
684 printf("%s: (size %d)\n", label, x->size);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
685 for (i = x->size-1; i >= 0; i--)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
686 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
687 for (j = COMP_NUM_NIBBLES-1; j >= 0; j--)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
688 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
689 comp mask = 0x0f << (j*4);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
690 comp num = (x->comps[i] & mask) >> (j*4);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
691 putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
692 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
693 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
694
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
695 printf("\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
696 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
697 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
698
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
699 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
700 * @brief Take a bigint and convert it into a byte sequence.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
701 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
702 * This is useful after a decrypt operation.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
703 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
704 * @param x [in] The bigint to be converted.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
705 * @param data [out] The converted data as a byte stream.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
706 * @param size [in] The maximum size of the byte stream. Unused bytes will be
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
707 * zeroed.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
708 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
709 void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
710 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
711 int i, j, k = size-1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
712
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
713 check(x);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
714 memset(data, 0, size); /* ensure all leading 0's are cleared */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
715
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
716 for (i = 0; i < x->size; i++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
717 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
718 for (j = 0; j < COMP_BYTE_SIZE; j++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
719 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
720 comp mask = 0xff << (j*8);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
721 int num = (x->comps[i] & mask) >> (j*8);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
722 data[k--] = num;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
723
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
724 if (k < 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
725 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
726 break;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
727 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
728 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
729 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
730
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
731 bi_free(ctx, x);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
732 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
733
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
734 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
735 * @brief Pre-calculate some of the expensive steps in reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
736 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
737 * This function should only be called once (normally when a session starts).
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
738 * When the session is over, bi_free_mod() should be called. bi_mod_power()
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
739 * relies on this function being called.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
740 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
741 * @param bim [in] The bigint modulus that will be used.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
742 * @param mod_offset [in] There are three moduluii that can be stored - the
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
743 * standard modulus, and its two primes p and q. This offset refers to which
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
744 * modulus we are referring to.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
745 * @see bi_free_mod(), bi_mod_power().
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
746 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
747 void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
748 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
749 int k = bim->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
750 comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
751 #ifdef CONFIG_BIGINT_MONTGOMERY
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
752 bigint *R, *R2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
753 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
754
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
755 ctx->bi_mod[mod_offset] = bim;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
756 bi_permanent(ctx->bi_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
757 ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
758 bi_permanent(ctx->bi_normalised_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
759
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
760 #if defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
761 /* set montgomery variables */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
762 R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1); /* R */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
763 R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1); /* R^2 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
764 ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2); /* R^2 mod m */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
765 ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R); /* R mod m */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
766
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
767 bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
768 bi_permanent(ctx->bi_R_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
769
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
770 ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
771
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
772 #elif defined (CONFIG_BIGINT_BARRETT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
773 ctx->bi_mu[mod_offset] =
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
774 bi_divide(ctx, comp_left_shift(
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
775 bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
776 bi_permanent(ctx->bi_mu[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
777 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
778 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
779
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
780 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
781 * @brief Used when cleaning various bigints at the end of a session.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
782 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
783 * @param mod_offset [in] The offset to use.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
784 * @see bi_set_mod().
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
785 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
786 void bi_free_mod(BI_CTX *ctx, int mod_offset)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
787 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
788 bi_depermanent(ctx->bi_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
789 bi_free(ctx, ctx->bi_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
790 #if defined (CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
791 bi_depermanent(ctx->bi_RR_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
792 bi_depermanent(ctx->bi_R_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
793 bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
794 bi_free(ctx, ctx->bi_R_mod_m[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
795 #elif defined(CONFIG_BIGINT_BARRETT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
796 bi_depermanent(ctx->bi_mu[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
797 bi_free(ctx, ctx->bi_mu[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
798 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
799 bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
800 bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
801 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
802
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
803 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
804 * Perform a standard multiplication between two bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
805 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
806 static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
807 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
808 int i, j, i_plus_j;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
809 int n = bia->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
810 int t = bib->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
811 bigint *biR = alloc(ctx, n + t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
812 comp *sr = biR->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
813 comp *sa = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
814 comp *sb = bib->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
815
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
816 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
817 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
818
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
819 /* clear things to start with */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
820 memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
821 i = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
822
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
823 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
824 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
825 comp carry = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
826 comp b = *sb++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
827 i_plus_j = i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
828 j = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
829
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
830 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
831 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
832 long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
833 sr[i_plus_j++] = (comp)tmp; /* downsize */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
834 carry = (comp)(tmp >> COMP_BIT_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
835 } while (++j < n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
836
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
837 sr[i_plus_j] = carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
838 } while (++i < t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
839
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
840 bi_free(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
841 bi_free(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
842 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
843 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
844
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
845 #ifdef CONFIG_BIGINT_KARATSUBA
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
846 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
847 * Karatsuba improves on regular multiplication due to only 3 multiplications
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
848 * being done instead of 4. The additional additions/subtractions are O(N)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
849 * rather than O(N^2) and so for big numbers it saves on a few operations
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
850 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
851 static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
852 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
853 bigint *x0, *x1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
854 bigint *p0, *p1, *p2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
855 int m;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
856
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
857 if (is_square)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
858 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
859 m = (bia->size + 1)/2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
860 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
861 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
862 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
863 m = (max(bia->size, bib->size) + 1)/2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
864 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
865
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
866 x0 = bi_clone(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
867 x0->size = m;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
868 x1 = bi_clone(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
869 comp_right_shift(x1, m);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
870 bi_free(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
871
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
872 /* work out the 3 partial products */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
873 if (is_square)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
874 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
875 p0 = bi_square(ctx, bi_copy(x0));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
876 p2 = bi_square(ctx, bi_copy(x1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
877 p1 = bi_square(ctx, bi_add(ctx, x0, x1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
878 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
879 else /* normal multiply */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
880 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
881 bigint *y0, *y1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
882 y0 = bi_clone(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
883 y0->size = m;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
884 y1 = bi_clone(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
885 comp_right_shift(y1, m);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
886 bi_free(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
887
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
888 p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
889 p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
890 p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
891 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
892
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
893 p1 = bi_subtract(ctx,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
894 bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
895
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
896 comp_left_shift(p1, m);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
897 comp_left_shift(p2, 2*m);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
898 return bi_add(ctx, p1, bi_add(ctx, p0, p2));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
899 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
900 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
901
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
902 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
903 * @brief Perform a multiplication operation between two bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
904 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
905 * @param bia [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
906 * @param bib [in] Another bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
907 * @return The result of the multiplication.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
908 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
909 bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
910 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
911 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
912 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
913
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
914 #ifdef CONFIG_BIGINT_KARATSUBA
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
915 if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
916 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
917 return regular_multiply(ctx, bia, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
918 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
919
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
920 return karatsuba(ctx, bia, bib, 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
921 #else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
922 return regular_multiply(ctx, bia, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
923 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
924 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
925
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
926 #ifdef CONFIG_BIGINT_SQUARE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
927 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
928 * Perform the actual square operion. It takes into account overflow.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
929 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
930 static bigint *regular_square(BI_CTX *ctx, bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
931 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
932 int t = bi->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
933 int i = 0, j;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
934 bigint *biR = alloc(ctx, t*2);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
935 comp *w = biR->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
936 comp *x = bi->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
937 comp carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
938
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
939 memset(w, 0, biR->size*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
940
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
941 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
942 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
943 long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
944 comp u = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
945 w[2*i] = (comp)tmp;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
946 carry = (comp)(tmp >> COMP_BIT_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
947
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
948 for (j = i+1; j < t; j++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
949 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
950 long_comp xx = (long_comp)x[i]*x[j];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
951 long_comp xx2 = 2*xx;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
952 long_comp blob = (long_comp)w[i+j]+carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
953
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
954 if (u) /* previous overflow */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
955 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
956 blob += COMP_RADIX;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
957 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
958
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
959
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
960 u = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
961 tmp = xx2 + blob;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
962
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
963 /* check for overflow */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
964 if ((COMP_MAX-xx) < xx || (COMP_MAX-xx2) < blob)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
965 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
966 u = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
967 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
968
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
969 w[i+j] = (comp)tmp;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
970 carry = (comp)(tmp >> COMP_BIT_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
971 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
972
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
973 w[i+t] += carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
974
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
975 if (u)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
976 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
977 w[i+t+1] = 1; /* add carry */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
978 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
979 } while (++i < t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
980
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
981 bi_free(ctx, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
982 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
983 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
984
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
985 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
986 * @brief Perform a square operation on a bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
987 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
988 * @param bia [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
989 * @return The result of the multiplication.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
990 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
991 bigint *bi_square(BI_CTX *ctx, bigint *bia)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
992 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
993 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
994
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
995 #ifdef CONFIG_BIGINT_KARATSUBA
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
996 if (bia->size < SQU_KARATSUBA_THRESH)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
997 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
998 return regular_square(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
999 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1000
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1001 return karatsuba(ctx, bia, NULL, 1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1002 #else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1003 return regular_square(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1004 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1005 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1006 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1007
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1008 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1009 * @brief Compare two bigints.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1010 * @param bia [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1011 * @param bib [in] Another bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1012 * @return -1 if smaller, 1 if larger and 0 if equal.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1013 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1014 int bi_compare(bigint *bia, bigint *bib)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1015 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1016 int r, i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1017
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1018 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1019 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1020
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1021 if (bia->size > bib->size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1022 r = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1023 else if (bia->size < bib->size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1024 r = -1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1025 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1026 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1027 comp *a = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1028 comp *b = bib->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1029
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1030 /* Same number of components. Compare starting from the high end
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1031 * and working down. */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1032 r = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1033 i = bia->size - 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1034
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1035 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1036 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1037 if (a[i] > b[i])
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1038 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1039 r = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1040 break;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1041 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1042 else if (a[i] < b[i])
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1043 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1044 r = -1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1045 break;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1046 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1047 } while (--i >= 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1048 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1049
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1050 return r;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1051 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1052
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1053 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1054 * Allocate and zero more components. Does not consume bi.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1055 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1056 static void more_comps(bigint *bi, int n)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1057 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1058 if (n > bi->max_comps)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1059 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1060 bi->max_comps = max(bi->max_comps * 2, n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1061 bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1062 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1063
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1064 if (n > bi->size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1065 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1066 memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1067 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1068
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1069 bi->size = n;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1070 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1071
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1072 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1073 * Make a new empty bigint. It may just use an old one if one is available.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1074 * Otherwise get one off the heap.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1075 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1076 static bigint *alloc(BI_CTX *ctx, int size)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1077 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1078 bigint *biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1079
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1080 /* Can we recycle an old bigint? */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1081 if (ctx->free_list != NULL)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1082 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1083 biR = ctx->free_list;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1084 ctx->free_list = biR->next;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1085 ctx->free_count--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1086
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1087 if (biR->refs != 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1088 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1089 #ifdef CONFIG_SSL_FULL_MODE
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1090 printf("alloc: refs was not 0\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1091 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1092 abort(); /* create a stack trace from a core dump */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1093 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1094
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1095 more_comps(biR, size);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1096 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1097 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1098 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1099 /* No free bigints available - create a new one. */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1100 biR = (bigint *)malloc(sizeof(bigint));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1101 biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1102 biR->max_comps = size; /* give some space to spare */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1103 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1104
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1105 biR->size = size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1106 biR->refs = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1107 biR->next = NULL;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1108 ctx->active_count++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1109 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1110 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1111
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1112 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1113 * Work out the highest '1' bit in an exponent. Used when doing sliding-window
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1114 * exponentiation.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1115 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1116 static int find_max_exp_index(bigint *biexp)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1117 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1118 int i = COMP_BIT_SIZE-1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1119 comp shift = COMP_RADIX/2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1120 comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1121
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1122 check(biexp);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1123
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1124 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1125 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1126 if (test & shift)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1127 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1128 return i+(biexp->size-1)*COMP_BIT_SIZE;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1129 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1130
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1131 shift >>= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1132 } while (--i != 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1133
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1134 return -1; /* error - must have been a leading 0 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1135 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1136
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1137 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1138 * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1139 * exponentiation.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1140 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1141 static int exp_bit_is_one(bigint *biexp, int offset)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1142 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1143 comp test = biexp->comps[offset / COMP_BIT_SIZE];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1144 int num_shifts = offset % COMP_BIT_SIZE;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1145 comp shift = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1146 int i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1147
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1148 check(biexp);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1149
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1150 for (i = 0; i < num_shifts; i++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1151 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1152 shift <<= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1153 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1154
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1155 return test & shift;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1156 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1157
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1158 #ifdef CONFIG_BIGINT_CHECK_ON
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1159 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1160 * Perform a sanity check on bi.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1161 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1162 static void check(const bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1163 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1164 if (bi->refs <= 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1165 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1166 printf("check: zero or negative refs in bigint\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1167 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1168 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1169
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1170 if (bi->next != NULL)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1171 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1172 printf("check: attempt to use a bigint from "
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1173 "the free list\n");
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1174 abort();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1175 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1176 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1177 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1178
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1179 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1180 * Delete any leading 0's (and allow for 0).
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1181 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1182 static bigint *trim(bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1183 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1184 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1185
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1186 while (bi->comps[bi->size-1] == 0 && bi->size > 1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1187 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1188 bi->size--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1189 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1190
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1191 return bi;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1192 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1193
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1194 #if defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1195 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1196 * @brief Perform a single montgomery reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1197 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1198 * @param bixy [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1199 * @return The result of the montgomery reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1200 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1201 bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1202 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1203 int i = 0, n;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1204 uint8_t mod_offset = ctx->mod_offset;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1205 bigint *bim = ctx->bi_mod[mod_offset];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1206 comp mod_inv = ctx->N0_dash[mod_offset];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1207
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1208 check(bixy);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1209
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1210 if (ctx->use_classical) /* just use classical instead */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1211 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1212 return bi_mod(ctx, bixy);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1213 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1214
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1215 n = bim->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1216
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1217 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1218 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1219 bixy = bi_add(ctx, bixy, comp_left_shift(
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1220 bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1221 } while (++i < n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1222
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1223 comp_right_shift(bixy, n);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1224
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1225 if (bi_compare(bixy, bim) >= 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1226 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1227 bixy = bi_subtract(ctx, bixy, bim, NULL);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1228 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1229
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1230 return bixy;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1231 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1232
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1233 #elif defined(CONFIG_BIGINT_BARRETT)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1234 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1235 * Stomp on the most significant components to give the illusion of a "mod base
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1236 * radix" operation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1237 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1238 static bigint *comp_mod(bigint *bi, int mod)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1239 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1240 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1241
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1242 if (bi->size > mod)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1243 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1244 bi->size = mod;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1245 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1246
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1247 return bi;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1248 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1249
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1250 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1251 * Barrett reduction has no need for some parts of the product, so ignore bits
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1252 * of the multiply. This routine gives Barrett its big performance
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1253 * improvements over Classical/Montgomery reduction methods.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1254 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1255 static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1256 int inner_partial, int outer_partial)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1257 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1258 int i = 0, j, n = bia->size, t = bib->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1259 bigint *biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1260 comp carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1261 comp *sr, *sa, *sb;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1262
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1263 check(bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1264 check(bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1265
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1266 biR = alloc(ctx, n + t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1267 sa = bia->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1268 sb = bib->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1269 sr = biR->comps;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1270
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1271 if (inner_partial)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1272 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1273 memset(sr, 0, inner_partial*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1274 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1275 else /* outer partial */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1276 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1277 if (n < outer_partial || t < outer_partial) /* should we bother? */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1278 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1279 bi_free(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1280 bi_free(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1281 biR->comps[0] = 0; /* return 0 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1282 biR->size = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1283 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1284 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1285
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1286 memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1287 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1288
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1289 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1290 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1291 comp *a = sa;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1292 comp b = *sb++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1293 long_comp tmp;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1294 int i_plus_j = i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1295 carry = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1296 j = n;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1297
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1298 if (outer_partial && i_plus_j < outer_partial)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1299 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1300 i_plus_j = outer_partial;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1301 a = &sa[outer_partial-i];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1302 j = n-(outer_partial-i);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1303 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1304
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1305 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1306 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1307 if (inner_partial && i_plus_j >= inner_partial)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1308 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1309 break;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1310 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1311
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1312 tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1313 sr[i_plus_j++] = (comp)tmp; /* downsize */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1314 carry = (comp)(tmp >> COMP_BIT_SIZE);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1315 } while (--j != 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1316
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1317 sr[i_plus_j] = carry;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1318 } while (++i < t);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1319
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1320 bi_free(ctx, bia);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1321 bi_free(ctx, bib);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1322 return trim(biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1323 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1324
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1325 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1326 * @brief Perform a single Barrett reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1327 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1328 * @param bi [in] A bigint.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1329 * @return The result of the Barrett reduction.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1330 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1331 bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1332 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1333 bigint *q1, *q2, *q3, *r1, *r2, *r;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1334 uint8_t mod_offset = ctx->mod_offset;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1335 bigint *bim = ctx->bi_mod[mod_offset];
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1336 int k = bim->size;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1337
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1338 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1339 check(bim);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1340
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1341 /* use Classical method instead - Barrett cannot help here */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1342 if (bi->size > k*2)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1343 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1344 return bi_mod(ctx, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1345 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1346
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1347 q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1348
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1349 /* do outer partial multiply */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1350 q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1351 q3 = comp_right_shift(q2, k+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1352 r1 = comp_mod(bi, k+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1353
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1354 /* do inner partial multiply */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1355 r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1356 r = bi_subtract(ctx, r1, r2, NULL);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1357
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1358 /* if (r >= m) r = r - m; */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1359 if (bi_compare(r, bim) >= 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1360 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1361 r = bi_subtract(ctx, r, bim, NULL);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1362 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1363
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1364 return r;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1365 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1366 #endif /* CONFIG_BIGINT_BARRETT */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1367
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1368 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1369 /*
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1370 * Work out g1, g3, g5, g7... etc for the sliding-window algorithm
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1371 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1372 static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1373 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1374 int k = 1, i;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1375 bigint *g2;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1376
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1377 for (i = 0; i < window-1; i++) /* compute 2^(window-1) */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1378 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1379 k <<= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1380 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1381
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1382 ctx->g = (bigint **)malloc(k*sizeof(bigint *));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1383 ctx->g[0] = bi_clone(ctx, g1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1384 bi_permanent(ctx->g[0]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1385 g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1386
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1387 for (i = 1; i < k; i++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1388 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1389 ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2)));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1390 bi_permanent(ctx->g[i]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1391 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1392
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1393 bi_free(ctx, g2);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1394 ctx->window = k;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1395 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1396 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1397
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1398 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1399 * @brief Perform a modular exponentiation.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1400 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1401 * This function requires bi_set_mod() to have been called previously. This is
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1402 * one of the optimisations used for performance.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1403 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1404 * @param bi [in] The bigint on which to perform the mod power operation.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1405 * @param biexp [in] The bigint exponent.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1406 * @return The result of the mod exponentiation operation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1407 * @see bi_set_mod().
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1408 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1409 bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1410 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1411 int i = find_max_exp_index(biexp), j, window_size = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1412 bigint *biR = int_to_bi(ctx, 1);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1413
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1414 #if defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1415 uint8_t mod_offset = ctx->mod_offset;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1416 if (!ctx->use_classical)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1417 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1418 /* preconvert */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1419 bi = bi_mont(ctx,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1420 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset])); /* x' */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1421 bi_free(ctx, biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1422 biR = ctx->bi_R_mod_m[mod_offset]; /* A */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1423 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1424 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1425
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1426 check(bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1427 check(biexp);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1428
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1429 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1430 for (j = i; j > 32; j /= 5) /* work out an optimum size */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1431 window_size++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1432
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1433 /* work out the slide constants */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1434 precompute_slide_window(ctx, window_size, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1435 #else /* just one constant */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1436 ctx->g = (bigint **)malloc(sizeof(bigint *));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1437 ctx->g[0] = bi_clone(ctx, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1438 ctx->window = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1439 bi_permanent(ctx->g[0]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1440 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1441
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1442 /* if sliding-window is off, then only one bit will be done at a time and
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1443 * will reduce to standard left-to-right exponentiation */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1444 do
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1445 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1446 if (exp_bit_is_one(biexp, i))
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1447 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1448 int l = i-window_size+1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1449 int part_exp = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1450
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1451 if (l < 0) /* LSB of exponent will always be 1 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1452 l = 0;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1453 else
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1454 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1455 while (exp_bit_is_one(biexp, l) == 0)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1456 l++; /* go back up */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1457 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1458
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1459 /* build up the section of the exponent */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1460 for (j = i; j >= l; j--)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1461 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1462 biR = bi_residue(ctx, bi_square(ctx, biR));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1463 if (exp_bit_is_one(biexp, j))
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1464 part_exp++;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1465
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1466 if (j != l)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1467 part_exp <<= 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1468 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1469
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1470 part_exp = (part_exp-1)/2; /* adjust for array */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1471 biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1472 i = l-1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1473 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1474 else /* square it */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1475 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1476 biR = bi_residue(ctx, bi_square(ctx, biR));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1477 i--;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1478 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1479 } while (i >= 0);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1480
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1481 /* cleanup */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1482 for (i = 0; i < ctx->window; i++)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1483 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1484 bi_depermanent(ctx->g[i]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1485 bi_free(ctx, ctx->g[i]);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1486 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1487
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1488 free(ctx->g);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1489 bi_free(ctx, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1490 bi_free(ctx, biexp);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1491 #if defined CONFIG_BIGINT_MONTGOMERY
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1492 return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1493 #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1494 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1495 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1496 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1497
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1498 #ifdef CONFIG_SSL_CERT_VERIFICATION
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1499 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1500 * @brief Perform a modular exponentiation using a temporary modulus.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1501 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1502 * We need this function to check the signatures of certificates. The modulus
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1503 * of this function is temporary as it's just used for authentication.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1504 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1505 * @param bi [in] The bigint to perform the exp/mod.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1506 * @param bim [in] The temporary modulus.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1507 * @param biexp [in] The bigint exponent.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1508 * @return The result of the mod exponentiation operation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1509 * @see bi_set_mod().
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1510 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1511 bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1512 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1513 bigint *biR, *tmp_biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1514
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1515 /* Set up a temporary bigint context and transfer what we need between
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1516 * them. We need to do this since we want to keep the original modulus
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1517 * which is already in this context. This operation is only called when
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1518 * doing peer verification, and so is not expensive :-) */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1519 BI_CTX *tmp_ctx = bi_initialize();
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1520 bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1521 tmp_biR = bi_mod_power(tmp_ctx,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1522 bi_clone(tmp_ctx, bi),
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1523 bi_clone(tmp_ctx, biexp));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1524 biR = bi_clone(ctx, tmp_biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1525 bi_free(tmp_ctx, tmp_biR);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1526 bi_free_mod(tmp_ctx, BIGINT_M_OFFSET);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1527 bi_terminate(tmp_ctx);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1528
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1529 bi_free(ctx, bi);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1530 bi_free(ctx, bim);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1531 bi_free(ctx, biexp);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1532 return biR;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1533 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1534 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1535
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1536 #ifdef CONFIG_BIGINT_CRT
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1537 /**
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1538 * @brief Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1539 *
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1540 * @param ctx [in] The bigint session context.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1541 * @param bi [in] The bigint to perform the exp/mod.
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1542 * @param dP [in] CRT's dP bigint
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1543 * @param dQ [in] CRT's dQ bigint
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1544 * @param p [in] CRT's p bigint
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1545 * @param q [in] CRT's q bigint
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1546 * @param qInv [in] CRT's qInv bigint
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1547 * @return The result of the CRT operation
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1548 */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1549 bigint *bi_crt(BI_CTX *ctx, bigint *bi,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1550 bigint *dP, bigint *dQ,
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1551 bigint *p, bigint *q, bigint *qInv)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1552 {
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1553 bigint *m1, *m2, *h;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1554
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1555 /* Montgomery has a condition the 0 < x, y < m and these products violate
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1556 * that condition. So disable Montgomery when using CRT */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1557 #if defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1558 ctx->use_classical = 1;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1559 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1560 ctx->mod_offset = BIGINT_P_OFFSET;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1561 m1 = bi_mod_power(ctx, bi_copy(bi), dP);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1562
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1563 ctx->mod_offset = BIGINT_Q_OFFSET;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1564 m2 = bi_mod_power(ctx, bi, dQ);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1565
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1566 h = bi_subtract(ctx, bi_add(ctx, m1, p), bi_copy(m2), NULL);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1567 h = bi_multiply(ctx, h, qInv);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1568 ctx->mod_offset = BIGINT_P_OFFSET;
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1569 h = bi_residue(ctx, h);
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1570 #if defined(CONFIG_BIGINT_MONTGOMERY)
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1571 ctx->use_classical = 0; /* reset for any further operation */
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1572 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1573 return bi_add(ctx, m2, bi_multiply(ctx, q, h));
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1574 }
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1575 #endif
3425707ddbf6 Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff changeset
1576 /** @} */