source: comparacioncriptosistemas/binary_field.H @ 1b57940

interfaz
Last change on this file since 1b57940 was 1b57940, checked in by Alejandro <amujica@…>, 9 years ago

Primeros intentos

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2  Copyright (C) 2015
3  Alejandro Mujica (amujica en cenditel.gob.ve)
4  José Ángel 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 clase tipo
24  plantilla para representar campos finitos binarios. Con el fin de definir
25  operaciones aritméticas sobre números pertenecientes al campo y obtener
26  sus resultados dentro del campo.
27
28  Creado por:        Alejandro J. Mujica
29  Fecha de creación:
30*/
31
32# ifndef BINARY_FIELD_H
33# define BINARY_FIELD_H
34
35# include <cmath>
36# include <random>
37# include <stdexcept>
38
39/**
40 *  Plantilla que representa un campo finito binario.
41 *
42 *  @param Number_Type Tipo numérico que se va a restringir. Debe ser un tipo
43 *                     de los enteros de la biblioteca estándar de C++.
44 *
45 *  @param K   Valor constante que representa el máximo número del
46 *                     campo.
47 *
48 *  @author Alejandro J. Mujica (amujica en cenditel punto gob punto ve).
49 *  @author José Angel Contreras (jancontreras en cenditel punto gob punto ve).
50 */
51template <typename Number_Type, uint8_t K>
52class Binary_Field
53{
54  static_assert(std::is_integral<Number_Type>::value,
55                "template argument is not an integral type");
56
57  typedef std::uniform_int_distribution<Number_Type> unif_dist_t;
58
59  static constexpr uint8_t P = 2;
60
61  static constexpr Number_Type MAX_VALUE = std::pow(P, K);
62
63  static constexpr Number_Type LAST_BIT = std::pow(2, K - 1);
64
65  static constexpr uint8_t TABLE_SIZE = 64;
66
67  static constexpr uint64_t BIT_TABLE[] =
68    {
69       1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
70       16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
71       8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912,
72       1073741824, 2147483648, 4294967296, 8589934592, 17179869184,
73       34359738368, 68719476736, 137438953472, 274877906944, 549755813888,
74       1099511627776, 2199023255552, 4398046511104, 8796093022208,
75       17592186044416, 35184372088832, 70368744177664, 140737488355328,
76       281474976710656, 562949953421312, 1125899906842624, 2251799813685248,
77       4503599627370496, 9007199254740992, 18014398509481984,
78       36028797018963968, 72057594037927936, 144115188075855872,
79       288230376151711744, 576460752303423488, 1152921504606846976,
80       2305843009213693952, 4611686018427387904, 9223372036854775808,
81       9223372036854775808
82    };
83
84  number_t irreducible_polynomial;
85
86  void generate_irreducible_polynomial();
87
88public:
89  Field();
90
91  /// Tipo de número que maneja el campo.
92  typedef Number_Type number_t;
93
94  /// Retorna el máximo valor soportado por el campo.
95  number_t max_value() const
96  {
97    return MAX_VALUE;
98  }
99
100  /// Efectúa la suma de dos números dentro del campo.
101  number_t sum(const number_t &, const number_t &) const;
102
103  /// Efectúa la resta de dos números dentro del campo.
104  number_t sub(const number_t &, const number_t &) const;
105
106  /// Efectúa la multiplicación de dos números dentro del campo.
107  number_t mul(const number_t &, const number_t &) const;
108
109  /// Efectúa la división de dos números dentro del campo.
110  number_t div(const number_t &, const number_t &) const;
111
112  /// Calcula el opuesto de un número dentro del campo.
113  number_t op(const number_t &) const;
114
115  /// Calcula el inverso numérico de un número dentro del campo.
116  number_t inv(const number_t &) const;
117
118  /// Genera un número aleatorio dentro del campo.
119  template <class Random_Number_Generator>
120  number_t get_random(Random_Number_Generator &) const;
121
122  number_t operator () (const number_t & n)
123  {
124    return n % MAX_VALUE;
125  }
126};
127
128template <typename Number_Type, uint8_t K>
129void Binary_Field<Number_Type, K>::generate_irreducible_polynomial()
130{
131  irreducible_polynomial |= std::pow(2, 0);
132  irreducible_polynomial |= std::pow(2, 1);
133  irreducible_polynomial |= std::pow(2, 5);
134  irreducible_polynomial |= std::pow(2, 6);
135  irreducible_polynomial |= std::pow(2, 8);
136}
137
138template <typename Number_Type, uint8_t K> 
139Binary_Field<Number_Type, K>::Binary_Field()
140  : irreducible_polynomial(number_t(0))
141{
142  generate_irreducible_polynomial();
143}
144
145/**
146 *  @param a Primer elemento en la suma.
147 *  @param b Segundo elemento en la suma.
148 *  @return suma dentro del campo.
149 */
150template <typename Number_Type, uint8_t K> Number_Type
151Binary_Field<Number_Type, K>::sum(const number_t & a, const number_t & b) const
152{
153  return (a ^ b) % MAX_VALUE;
154}
155
156/**
157 *  @param a Minuendo.
158 *  @param b Sustraendo.
159 *  @return resta dentro del campo.
160 */
161template <typename Number_Type, uint8_t K> Number_Type
162Binary_Field<Number_Type, K>::sub(const number_t & a, const number_t & b) const
163{
164  return (a + op(b)) % MAX_VALUE;
165}
166
167/**
168 *  @param a Multiplicando.
169 *  @param b Multiplicador.
170 *  @return producto dentro del campo.
171 */
172template <typename Number_Type, uint8_t K> Number_Type
173Binary_Field<Number_Type, K>::mul(const number_t & a, const number_t & b) const
174{
175  return (a * b) % MAX_VALUE;
176}
177
178/**
179 *  @param a Dividendo.
180 *  @param b Divisor.
181 *  @return cociente dentro del campo.
182 */
183template <typename Number_Type, uint8_t K> Number_Type
184Binary_Field<Number_Type, K>::div(const number_t & _a,
185                                  const number_t & _b) const
186{
187  number_t ret = number_t(0);
188
189  number_t carry;
190
191  number_t a(_a);
192  number_t b(_b);
193
194  for (uint8_t i = 0; i < K; ++i)
195    {
196      if (b & 1)
197        ret ^= a;
198
199      carry = a & LAST_BIT;
200
201      a <<= 1;
202
203      if (carry)
204        a ^= irreducible_polynomial;
205
206      b >>= 1;
207    }
208
209  return ret;
210}
211
212/**
213 *  @param a Número.
214 *  @return Opuesto numérico dentro del campo. Tal que a + (-a) = 0.
215 */
216template <typename Number_Type, uint8_t K> Number_Type
217Binary_Field<Number_Type, K>::op(const number_t & n) const
218{
219  return MAX_VALUE - n;
220}
221
222/**
223 *  @param a Número.
224 *  @return Inverso numérico dentro del campo.  Tal que a * a^(-1) = 1.
225 */
226template <typename Number_Type, uint8_t K> Number_Type
227Binary_Field<Number_Type, K>::inv(const number_t & n) const
228{
229  if (n == number_t(0))
230    throw std::logic_error("0 has not numeric inverse");
231
232  number_t inv = number_t(0);
233
234  while ((inv * n) % MAX_VALUE != number_t(1))
235    ++inv;
236
237  return inv;
238}
239
240/**
241 *  @param rng Generador de números aleatorios. Éste debe ser uno de los
242 *             generadores de la biblioteca estándar de C++.
243 *  @return Número aleatorio dentro del campo uniformemente distribuido.
244 */
245template <typename Number_Type, uint8_t K>
246template <class Random_Number_Generator> Number_Type
247Binary_Field<Number_Type, K>::get_random(Random_Number_Generator & rng) const
248{
249  unif_dist_t unif_dist(0, MAX_VALUE);
250
251  return unif_dist(rng);
252}
253
254# endif // BINARY_FIELD_H
255
Note: See TracBrowser for help on using the repository browser.