comparison nss/lib/freebl/ecl/ecp_mont.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 /* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
6 * code implementation. */
7
8 #include "mpi.h"
9 #include "mplogic.h"
10 #include "mpi-priv.h"
11 #include "ecl-priv.h"
12 #include "ecp.h"
13 #include <stdlib.h>
14 #include <stdio.h>
15
16 /* Construct a generic GFMethod for arithmetic over prime fields with
17 * irreducible irr. */
18 GFMethod *
19 GFMethod_consGFp_mont(const mp_int *irr)
20 {
21 mp_err res = MP_OKAY;
22 GFMethod *meth = NULL;
23 mp_mont_modulus *mmm;
24
25 meth = GFMethod_consGFp(irr);
26 if (meth == NULL)
27 return NULL;
28
29 mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
30 if (mmm == NULL) {
31 res = MP_MEM;
32 goto CLEANUP;
33 }
34
35 meth->field_mul = &ec_GFp_mul_mont;
36 meth->field_sqr = &ec_GFp_sqr_mont;
37 meth->field_div = &ec_GFp_div_mont;
38 meth->field_enc = &ec_GFp_enc_mont;
39 meth->field_dec = &ec_GFp_dec_mont;
40 meth->extra1 = mmm;
41 meth->extra2 = NULL;
42 meth->extra_free = &ec_GFp_extra_free_mont;
43
44 mmm->N = meth->irr;
45 mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
46
47 CLEANUP:
48 if (res != MP_OKAY) {
49 GFMethod_free(meth);
50 return NULL;
51 }
52 return meth;
53 }
54
55 /* Wrapper functions for generic prime field arithmetic. */
56
57 /* Field multiplication using Montgomery reduction. */
58 mp_err
59 ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
60 const GFMethod *meth)
61 {
62 mp_err res = MP_OKAY;
63
64 #ifdef MP_MONT_USE_MP_MUL
65 /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
66 * is not implemented and we have to use mp_mul and s_mp_redc directly
67 */
68 MP_CHECKOK(mp_mul(a, b, r));
69 MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
70 #else
71 mp_int s;
72
73 MP_DIGITS(&s) = 0;
74 /* s_mp_mul_mont doesn't allow source and destination to be the same */
75 if ((a == r) || (b == r)) {
76 MP_CHECKOK(mp_init(&s));
77 MP_CHECKOK(s_mp_mul_mont
78 (a, b, &s, (mp_mont_modulus *) meth->extra1));
79 MP_CHECKOK(mp_copy(&s, r));
80 mp_clear(&s);
81 } else {
82 return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
83 }
84 #endif
85 CLEANUP:
86 return res;
87 }
88
89 /* Field squaring using Montgomery reduction. */
90 mp_err
91 ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
92 {
93 return ec_GFp_mul_mont(a, a, r, meth);
94 }
95
96 /* Field division using Montgomery reduction. */
97 mp_err
98 ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
99 const GFMethod *meth)
100 {
101 mp_err res = MP_OKAY;
102
103 /* if A=aZ represents a encoded in montgomery coordinates with Z and #
104 * and \ respectively represent multiplication and division in
105 * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
106 * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
107 MP_CHECKOK(ec_GFp_div(a, b, r, meth));
108 MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
109 if (a == NULL) {
110 MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
111 }
112 CLEANUP:
113 return res;
114 }
115
116 /* Encode a field element in Montgomery form. See s_mp_to_mont in
117 * mpi/mpmontg.c */
118 mp_err
119 ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
120 {
121 mp_mont_modulus *mmm;
122 mp_err res = MP_OKAY;
123
124 mmm = (mp_mont_modulus *) meth->extra1;
125 MP_CHECKOK(mp_copy(a, r));
126 MP_CHECKOK(s_mp_lshd(r, MP_USED(&mmm->N)));
127 MP_CHECKOK(mp_mod(r, &mmm->N, r));
128 CLEANUP:
129 return res;
130 }
131
132 /* Decode a field element from Montgomery form. */
133 mp_err
134 ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
135 {
136 mp_err res = MP_OKAY;
137
138 if (a != r) {
139 MP_CHECKOK(mp_copy(a, r));
140 }
141 MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
142 CLEANUP:
143 return res;
144 }
145
146 /* Free the memory allocated to the extra fields of Montgomery GFMethod
147 * object. */
148 void
149 ec_GFp_extra_free_mont(GFMethod *meth)
150 {
151 if (meth->extra1 != NULL) {
152 free(meth->extra1);
153 meth->extra1 = NULL;
154 }
155 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)