source: comparacioncriptosistemas/reescrituraDeCodigo/finitefield2.H

interfaz
Last change on this file was 7576857, checked in by Fundación CENDITEL <cenditel@…>, 8 years ago

Se mueven archivos de reescritura al directorio reescrituraDeCodigo

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2  Copyright (C) 2015
3  Alejandro Mujica (amujica en cenditel.gob.ve)
4  José Angel Contreras (jancontreras en cenditel.gob.ve)
5  Antonio Araujo (aaraujo en cenditel.gob.ve)
6  Pedro Buitrago (pbuitrago en cenditel.gob.ve)
7 
8  CENDITEL Fundación Centro Nacional de Desarrollo e Investigación en
9  Tecnologías Libres
10 
11  Este programa es software libre; Usted puede usarlo bajo los términos de la
12  licencia de software GPL versión 2.0 de la Free Software Foundation.
13 
14  Este programa se distribuye con la esperanza de que sea útil, pero SIN
15  NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o
16  ADECUACIÓN A UN PROPÓSITO PARTICULAR.
17  Consulte la licencia GPL para más detalles. Usted debe recibir una copia
18  de la GPL junto con este programa; si no, escriba a la Free Software
19  Foundation Inc. 51 Franklin Street,5 Piso, Boston, MA 02110-1301, USA.
20*/
21
22/*
23  Este archivo contiene la definición e implementación de una plantilla de clase
24  para representar campos finitos con carácterística p = 2. Con el fin de
25  definir operaciones aritméticas sobre números pertenecientes al campo y
26  obtener sus resultados dentro éste.
27
28  Creado por:        Alejandro J. Mujica
29  Fecha de creación:
30*/
31
32# ifndef FINITEFIELD2_H
33# define FINITEFIELD2_H
34
35# include <cmath>
36# include <stdexcept>
37
38# include <finitefield.H>
39
40/**
41 *  Plantilla que representa un campo finito con característica @f$p = 2@f$.
42 *
43 *  @tparam NumberT Tipo numérico que se va a restringir.
44 *
45 *  @tparam N   Valor constante para la potencia de dos que definirá el tamaño
46 *              del campo. Por lo tanto, el tamaño del campo estará definido
47 *              por @f$2^N@f$.
48 *
49 *  @pre NumberT debe ser un tipo de los enteros sin signo de la biblioteca
50 *       estándar de C++
51 *  @pre 0 <= N <= 64
52 *
53 *  @see FiniteField FieldNumber
54 *
55 *  @author Alejandro J. Mujica (amujica en cenditel punto gob punto ve).
56 *  @author José Angel Contreras (jancontreras en cenditel punto gob punto ve).
57 */
58template <typename NumberT, unsigned short N>
59class FiniteField2 : public FiniteField<NumberT, 2, N>
60{
61  static_assert(0 <= N and N <= 64, "N must be a value less than 64");
62
63  static constexpr unsigned short TABLE_SIZE = 65; // Desde 2^0 hasta 2^64
64
65  static constexpr uint64_t POWER2_TABLE[TABLE_SIZE] =
66    {
67       1u, 2u, 4u, 8u, 16u, 32u, 64u, 128u, 256u, 512u, 1024u, 2048u, 4096u,
68       8192u, 16384u, 32768u, 65536u, 131072u, 262144u, 524288u, 1048576u,
69       2097152u, 4194304u, 8388608u, 16777216u, 33554432u, 67108864u,
70       134217728u, 268435456u, 536870912u, 1073741824u, 2147483648u,
71       4294967296u, 8589934592u, 17179869184u, 34359738368u, 68719476736u,
72       137438953472u, 274877906944u, 549755813888u, 1099511627776u,
73       2199023255552u, 4398046511104u, 8796093022208u, 17592186044416u,
74       35184372088832u, 70368744177664u, 140737488355328u, 281474976710656u,
75       562949953421312u, 1125899906842624u, 2251799813685248u,
76       4503599627370496u, 9007199254740992u, 18014398509481984u,
77       36028797018963968u, 72057594037927936u, 144115188075855872u,
78       288230376151711744u, 576460752303423488u, 1152921504606846976u,
79       2305843009213693952u, 4611686018427387904u, 9223372036854775808u,
80       18446744073709551615u
81    };
82
83  using UnifDistType = std::uniform_int_distribution<NumberT>;
84
85public:
86  /// Tipo de número que maneja el campo.
87  using NumberType = NumberT;
88
89private:
90  NumberType irreducible_polynomial;
91
92  void generate_irreducible_polynomial();
93
94public:
95  FiniteField2();
96
97  /// Efectúa la suma de dos números dentro del campo.
98  NumberType sum(const NumberType &, const NumberType &) const;
99
100  /// Efectúa la resta de dos números dentro del campo.
101  NumberType sub(const NumberType &, const NumberType &) const;
102
103  /// Efectúa la multiplicación de dos números dentro del campo.
104  NumberType mul(const NumberType &, const NumberType &) const;
105
106  /// Efectúa la división de dos números dentro del campo.
107  NumberType div(const NumberType &, const NumberType &) const;
108
109  /// Calcula el opuesto de un número dentro del campo.
110  NumberType op(const NumberType &) const;
111
112  /// Calcula el inverso numérico de un número dentro del campo.
113  NumberType inv(const NumberType &) const;
114};
115
116template <typename NumberT, unsigned short N>
117void FiniteField2<NumberT, N>::generate_irreducible_polynomial()
118{
119  irreducible_polynomial |= POWER2_TABLE[0];
120  irreducible_polynomial |= POWER2_TABLE[1];
121  irreducible_polynomial |= POWER2_TABLE[5];
122  irreducible_polynomial |= POWER2_TABLE[6];
123  irreducible_polynomial |= POWER2_TABLE[8];
124}
125
126template <typename NumberT, unsigned short N> 
127FiniteField2<NumberT, N>::FiniteField2()
128  : irreducible_polynomial(NumberType(0))
129{
130  generate_irreducible_polynomial();
131}
132
133/**
134 *  @param a Primer elemento en la suma.
135 *  @param b Segundo elemento en la suma.
136 *  @return suma dentro del campo.
137 */
138template <typename NumberT, unsigned short N> NumberT
139FiniteField2<NumberT, N>::sum(const NumberType & a, const NumberType & b) const
140{
141  return (a ^ b);
142}
143
144/**
145 *  @param a Minuendo.
146 *  @param b Sustraendo.
147 *  @return resta dentro del campo.
148 */
149template <typename NumberT, unsigned short N> NumberT
150FiniteField2<NumberT, N>::sub(const NumberType & a, const NumberType & b) const
151{
152  return (a ^ b);
153}
154
155/**
156 *  @param a Multiplicando.
157 *  @param b Multiplicador.
158 *  @return producto dentro del campo.
159 */
160template <typename NumberT, unsigned short N> NumberT
161FiniteField2<NumberT, N>::mul(const NumberType & a, const NumberType & b) const
162{
163  NumberType _a(a);
164  NumberType _b(b);
165  NumberType ret(0);
166
167  for (unsigned short i = 0; i < N; ++i)
168    {
169      if (_b & 1) // ¿Es impar?
170        ret ^= _a;
171
172      _a <<= 1;
173
174      if (_a >= this->size())
175        _a ^= irreducible_polynomial;
176
177      _b >>= 1;
178    }
179 
180  return ret;
181}
182
183/**
184 *  @param a Dividendo.
185 *  @param b Divisor.
186 *  @return cociente dentro del campo.
187 */
188template <typename NumberT, unsigned short N> NumberT
189FiniteField2<NumberT, N>::div(const NumberType & _a,
190                                  const NumberType & _b) const
191{
192  NumberType ret = NumberType(0);
193
194  NumberType carry;
195
196  NumberType a(_a);
197  NumberType b(_b);
198
199  for (unsigned short i = 0; i < N; ++i)
200    {
201      if (b & 1)
202        ret ^= a;
203
204      //      carry = a & LAST_BIT;
205
206      a <<= 1;
207
208      if (carry)
209        a ^= irreducible_polynomial;
210
211      b >>= 1;
212    }
213
214  return ret;
215}
216
217/**
218 *  @param a Número.
219 *  @return Opuesto numérico dentro del campo. Tal que @f$a + op(a) = 0@f$.
220 */
221template <typename NumberT, unsigned short N> NumberT
222FiniteField2<NumberT, N>::op(const NumberType & n) const
223{
224  return this->size() - n;
225}
226
227/**
228 *  @param a Número.
229 *  @return Inverso numérico dentro del campo.  Tal que @f$a * inv(a) = 1@f$.
230 */
231template <typename NumberT, unsigned short N> NumberT
232FiniteField2<NumberT, N>::inv(const NumberType & n) const
233{
234  if (n == NumberType(0))
235    throw std::logic_error("0 has not numeric inverse");
236
237  NumberType inv = NumberType(0);
238
239  while ((inv * n) % this->size() != NumberType(1))
240    ++inv;
241
242  return inv;
243}
244
245# endif // FINITEFIELD2_H
246
Note: See TracBrowser for help on using the repository browser.