A Java Implementation of Prime and Binary Fields I. S. Gutierrez and R. L. Villanueva 1Abstract— This paper introduces a Java software library intended to be used by cryptographers, programmers and practitioners. Basically, the library provides efficient implementations for performing calculations on finite fields. The main operations supported are addition; multiplication, division, square roots and they are speeded-up for parameters specified by standardization entities. The programming library is presented as a set of classes and the main algorithms implemented on them and their performance. Keywords— Java language, Finite fields, Prime fields, Binary fields, Computation, Efficiency. L I. INTRODUCCIÓN OS CUERPOS finitos son una clase de estructura algebraica abstracta. Intuitivamente hablando, un cuerpo finito es un conjunto finito dotado de dos operaciones binarias, generalmente llamadas adición y multiplicación, las cuales satisfacen ciertas propiedades, tales como asociatividad, conmutatividad, existencia de elementos neutros, existencia de inversos y la distribución de la multiplicación con respecto a la suma. Algunos ejemplos de cuerpos son los números reales ℝ y para un número primo , el conjunto ℤ de las clases residuales módulo . Un caso especial de este es el cuerpo binario ℤ , también notado con . Los cuerpos finitos tienen una gran cantidad de aplicaciones que van desde la construcción matemática de algoritmos criptográficos, algoritmos de la teoría de codificación hasta la recientemente teoría de codificación lineal aleatoria en redes, [7]. La implementación de estas estructuras matemáticas dio como resultado una librería, la cual es el tema central de este trabajo. Esta puede ser útil por matemáticos y criptógrafos entre otros, ya que proporciona los elementos básicos para la construcción de otras estructuras matemáticas, algoritmos criptográficos, o cualquier otra aplicación relevante. En este artículo se presenta una implementación eficiente de los cuerpos finitos destinada a ser útil para cualquier profesional dedicado a crear aplicaciones en las que los cuerpos finito jueguen un papel importante, especialmente los que utilizan cuerpo binarios. La organización del trabajo es la siguiente: en la sección II se describe la organización de las clases de la librería, en la sección III se describe con detalle los algoritmos implementados, en la sección IV se analizan los tiempos de las operaciones implementadas y finalmente, en la sección V se hacen conclusiones y se presentan algunos posibles frentes de trabajo futuro. I. S. Gutierrez, Universidad del Norte, Departamento de Matemáticas y Estadística, Barranquilla, Colombia, [email protected] II. DESCRIPCIÓN GENERAL DE LAS CLASES Esta sección presenta las razones del diseño considerado durante el proceso de construcción de la librería de software. En primer lugar, el lenguaje de programación elegido es Java, y la razón detrás de esta selección radica en algunas propiedades espaciales de Java, como por ejemplo, la portabilidad, la interoperabilidad y la facilidad de codificación. Estas características facilitan la construcción de un buen diseño, un grupo cohesionado de clases de Java, que se representan en la Figura 1. La librería comprende en su diseño tres clases principales: Field, FieldElement y Polynomial. En primer lugar, la clase Field define cuatro métodos importantes: getOrder, para devolver el orden de un cuerpo; generateRandomElement, para generar aleatoriamente un elemento del cuerpo; getOne y getZero, para retornar, respectivamente, los módulos de los grupos multiplicativo y aditivo. En segundo lugar, la clase FieldElement encapsula el comportamiento esperado de un elemento de un cuerpo finito. Cada clase concreta que hereda de la clase FieldElement debe implementar los métodos definidos en la clase FieldElement, los cuales se describirán más adelante. Por último, Polynomial es una clase concreta que representa un polinomio. Esta clase está asociada con la clase FieldElement, ya que un polinomio se construye a partir de un arreglo de elementos del cuerpo. En ella se proporcionan diferentes procedimientos para las operaciones básicas entre polinomios. III. CUERPOS FINITOS Formalmente, un cuerpo finito es un conjunto no vacío F dotado con dos operaciones binarias, suma y multiplicación, de tal manera que: • (F,+) es un grupo abeliano o conmutativo, con elemento neutro 0. • (F\{0},⋅) es un grupo abeliano, con elemento neutro 1. • Para todo a, b, c en F se satisface a⋅(b+c)= a⋅b+a⋅c. El menor número natural , tal que ⋅ 1 = 0, es llamado la característica de F. Para un cuerpo finito se satisface siempre tiene que la característica es un número primo. El cuerpo característica 2. Para cada primo y cada natural existe (salvo elementos, donde isomorfía) un único cuerpo F, con = es su característica, [9]. Más aún, cualquier cuerpo finito con elementos es isomorfo al cuerpo de descomposición = − sobre el cuerpo , es decir, el cuerpo del polinomio R. L. Villanueva, Universidad Simón Bolívar, Departamento de Ingeniería de Sistemas y Ciencias de la Computación, Barranquilla, Colombia, [email protected] donde el polinomio tiene todas sus raíces. En este caso o GF( ) para denotarlo (El cuerpo de Galois). Si escribimos = 1, entonces llamamos a F un cuerpo primo. = 0, si p| 1, si p ∤ y −1, si p ∤ y es un QR mod p es un QNR mod p Figura 1. Diagrama de las clases. Teorema III.3. (Euler, [6] Teorema 2.2.13.) Seguidamente describimos la implementación en Java de las clases destinadas a proporcionar la aritmética de los cuerpos finitos. Estas se denominan: GFPField, GFPElement, GF2nElement, GF2nElementPolynomial, GF2Field y GF2Polynomial. Sea p≠2 un número primo y a∈ℤ. Entonces A. Cuerpos Primos. Como muestra la Figura 1, existen dos clases de Java en las cuales se implementa la aritmética de los cuerpos primos. A saber, la clase GFPField, la cual es una representación de programación de los cuerpos primos e incluye funciones destinadas a calcular los valores dependientes en un cuerpo. La clase GFPElement es básicamente una representación de los elementos de los cuerpos primos. Estas dos clases utilizan la clase de Java BigInteger, la cual proporciona algoritmos eficientes para realizar la aritmética de precisión de cualquier orden, para extender su funcionalidad. La mayoría de las funciones implementadas en estas clases son sencillas, salvo el algoritmo de la raíz cuadrada, cuyo funcionamiento se basa en el algoritmo introducido por F. Wang, Y. Nogami y Y. Morikawa en [11]. Antes de discutir este algoritmo, introducimos alguna notación. Definición III.1. Sea ≠ 2 un número primo y a∈ℤ, tal que ( , ) = 1. Entonces la congruencia ≡ (1) tiene dos soluciones o ninguna. Si (1) tiene como solución, entonces se llama un residuo cuadrático (QR); en otro caso es un residuo no-cuadrático (QNR). Definición III.2. Sea ≠ 2 un número primo y a∈ℤ. Entonces se define así: el símbolo de Legendre ≡ (2) El algoritmo de la raíz cuadrada comprende dos métodos: El primero tiene como objetivo verificar si un elemento es un QR o un QNR y el segundo calcula la raíz cuadrada del elemento QR. El primer método se basa en la observación que ( donde , ) ≡ ≡ , ∈ ℤ. El Algoritmo 1 contiene la prueba de residuos cuadráticos. Los pasos (1), (2) y (3) se emplean para acelerar el cálculo de = , ver [11]. Algoritmo 1: Prueba de residuos cuadráticos Entrada: ∈ Salida: 1 si es QR o -1 si no lo es. 1: Factorice = 2 . Esta operación se realiza en el constructor de la clase GFPField, ya que esta depende del cuerpo 2: 3: 4: 5: 6: 7: 8: t ← x ( )/ t ← x ⋅ x ( )/ x ← t ⋅t if x = 1 o (x = −1 y T > 0) then return 1 For i = 1 hasta − 1 do x ← x 9: 10: 11: = −1 then return 1 return -1 ,y = Sea y un elemento QNR y sean y = , … , y = = −1, los valores dados por el test de residuo cuadrático, cuando es aplicado a y. Sea ahora x un elemento QR y sean ,…,x = , x = = −1, los valores x = , x = obtenidos al aplicar el test de residuo cuadrático a x. Note que = x y =1y = = x y = ±1. Definamos, = √ = x y , si = 1. En otro caso = y = y x y . Por lo tanto, = , , y = 1, entonces √ =√ ∙y (b) y = ∙ ∙y ( )/ . . Como resultado, (3) = −1, entonces y = 1, y por lo tanto ∙ , en consecuencia ∙√ ∙ y ∙ ( )/ . √ =y = y ∙X∙ (4) El Algoritmo 2 muestra como se calcula la raíz cuadrada de un elemento QR. Algoritmo 2: Raíz cuadrada en Entrada: ∈ . Salida: √ , if is QR. 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: [x]/〈 〉, donde 〈 〉 denota el ideal generado por el polinomio binario irreducible f de grado m. En consecuencia, cada elemento de tiene la forma ( ) + 〈 〉, donde = −1 ∙ B. Cuerpos Binarios De manera general, la Clase GF2Field representa cuerpos binarios. Sin embargo, los elementos de un cuerpo binario se pueden implementar mediante el uso de diferentes bases, esto es, por un polinomio o una base normal [9], [4]. De esta manera, se define una clase abstracta GF2nElement que representa un elemento en general, pero este sólo se implementa mediante el uso de elementos de bases polinómicas. Matemáticamente hablando, se verifica que ≅ =1 En el -ésimo paso se obtiene que = ∙y ∙ x = ±1, donde es 1 o un producto de subsecuencias de valores y , y ,..., y . Consideremos dos casos: (a) t ←t ∙y return t . 19: 20: If x . Elija un elemento QNR y calcule , , … , . La operación de factorización se realiza una vez, siempre que se inicializa un objeto GFPField t ← x ( )/ t ← x ⋅ x ( )/ x ← t ⋅t if x = 1, then return t i=0 while ≠ −1 do i←i+1 x ← x ⋅x ← − 1, ← 1, ← 1 for = 0 up to t do ← for j=0 up to − 1 do ← ∙ ← −1 if = −1 then ← − 1, ← + 1 for j=0 hasta − 1 do ( )= + ⋯+ + es representado como el arreglo , … , , ). ( En el software, ( ) e s representado como ( [0], [1], … , [ − 1]), donde cada B[i] es una palabra de W-bit y = / . Sin perder generalidad, asumimos que ≡ 0 , con W=32. Dado que la aritmética de un cuerpo binario se lleva a cabo a través de la aritmética polinómica, se introduce la clase GF2nPolynomial. Esta proviene de la clase Polynomial y se discutirá en breve. B[0] bm-1 … b(t-1)w Figura 2. B[1] b((t-1)w)-1 … b(t-2)w Representación de ∈ … B[t-1] bw-1 … b1b0 [ ] como un arreglo de t palabras. [ ] de grado m, La suma de dos polinomios ( ), ( ) ∈ representados respectivamente por ( ,…, , ) y + ,…, + ( , … , , ) es calculada como ( , + ). El Algoritmo 3 describe como este producto es implementado. Algoritmo 3: Suma de dos polinomios en [ ]. [ ] Entrada: Dos polinomios ( ), ( ) ∈ representados por los arreglos A y B respectivamente. Salida: ( ) = ( ) + ( ), donde el grado de c(x) es a lo más m-1. 1: for i= − 1 up to 0 do 2: c[i] ← A[i]⨁B[i] 3: return C Como puede notarse, el Algoritmo 3 es muy eficiente, ya que este solo requiere corres sobre cada posición una vez y realizar una operación XOR entre ellos. La multiplicación de dos polinomios ( ), ( ) ∈ [x] requiere de un algoritmo más complejo que el anterior, ya que la multiplicación se basa en la suma de varios polinomios aumentados. Salida: ( ) = b( ) . Antes de introducir la técnica general para calcular la multiplicación, observe que si los polinomios son iguales, entonces esta operación se optimiza mediante la observación que ( ) = + ⋯+ + , donde ( ) = + ⋯+ + . Por lo tanto, la representación de arreglo de bits de ( ) se obtiene fácilmente mediante la introducción de un cero entre dos bits consecutivos de la representación de ( ), ver [7]. Una ilustración se tiene en la siguiente figura. Para calcular la multiplicación de dos polinomios ( )= + ⋯+ + y ( )= + ⋯+ + Note que Figura 3. Representación de ( ) . ( )∙ ( )= Con el fin de realizar esta operación de manera eficiente, se construye una tabla de pre computo, la cual es definida por T[i] = r, donde r, i son números enteros no negativos (visto como bits) que representan polinomios, donde r es el cuadrado de i. Por ejemplo, T[20]=261 representa el cuadrado del polinomio 20 = (0000. . .00010100)2 = + , el cual es igual a 261 = (0000. . .100010000) = + . ( ) ( ) (5) Ahora la introducción de un w tal que w | W, esto es, W = w , la ecuación (5) se puede generalizar como: En particular, esta tabla tiene una complejidad de orden O(2 ), donde n es el número de bits utilizados para representar a i. El Algoritmo 4 trabaja con una tabla de 256 valores 256, que se define así: T[0] = 0, T[1] = 1, T[2] = 4, T[3] = 5, T [4] = 16, T [5] =17, ⋮ T [255] = 21845. [ ]. Algoritmo 4: El cuadrado de un Polinomio en Entrada: Un polinomio b( ) ∈ un arreglo B. El Algoritmo 5 es muy importante, ya que es una forma optima para pre-calcular una a(x) ∙ w (x) para todos los polinomios tales [ ] representado por que w (x) tiene grado a lo más w-1, con w = 4. Algoritmo 5: Calcula ( ) ∙ ( ) para todo polinomio tal que ( ) tiene grado a lo más 3. Entrada: Un polinomio ( ) representado por un arreglo. Salida: Una matriz P de 16 filas, donde la i-ésima fila ) representa ( , , + + =( , + ) ∙ ( ). Hasta el momento se han discutido las operaciones básicas entre polinomios binarios, pero no los elementos de cuerpos binarios. Estos son sólo polinomios reducidos por un polinomio irreducible, por lo tanto GF2ElementPolynomial, que, a su vez, contiene un objeto de GF2nPolynomial y a otro de GF2nField, que representan los elementos de un cuerpo binario. Recuerde que los cuerpos finitos en general pueden ser construidos utilizando trinomios o pentanomios irreductibles, ya que los cuerpos del mismo orden son isomorfos [9]. + ( ) un polinomio irreducible, donde Sea ( ) = ( ) es un polinomio binario con grado a lo más m-1 y ( ) [ ], con grado 2m-2. La operación ( ) b( ) ∈ se fundamenta en la siguiente observación [8]: ( )≡ ( ) El algoritmo (6) muestra cómo es efectuado la multiplicación de dos polinomios con w = 4, ver [8]. Este se implementa en la clase GF2Polynomial. Vale la pena mencionar que el paso 2 de este algoritmo se realiza una sola vez, ya que este es llamado sólo si P no es nulo. Algoritmo 6: Multiplicación de dos polinomios mediante el pre-cálculo con polinomios de grados a lo más 3. i.e. w=4. Entrada: Dos polinomios a( ), b( ) representados por arreglos. Salida: ( ) ∙ ( ). + . (7) El Algoritmo 7 realiza la reducción siempre que f(x) sea un trinomio. Por otro lado, el Algoritmo 8 hace lo mismo pero f(x) es un pentanomio. + Algoritmo 7: Reducción módulo ( ) = 0<t<m. Entrada: Un polinomio binario ( ) = + b( ) ∈ [ ]. ⋯+ ( ). Salida: ( ) ≡ ( ) + 1, con + ≡ + + + ≡ + + + ≡ + + + ⋮ De lo anterior se sigue el siguiente algoritmo: Algoritmo 9: Reducción módulo ( ) = Entrada: Un polinomio ( ) ∈ (B[0], B[1],…, B[k-1]). ( ). Salida: ( ) ≡ ( ) + Algoritmo 8: Reducción módulo ( ) = + 1, con 0< < < <m. Entrada: Un polinomio binario ( ) = + b( ) ∈ [ ]. ⋯+ ( ). Salida: ( ) ≡ ( ) + + + + 1. [ ], representado por + + Aplicando el mismo razonamiento para ( ) = + + 1, t=8, m=233. Suponga que el siguiente polinomio tiene que + +⋯+ + . ser reducido ( ) = ) para , , ,…, Considere entonces la palabra ( ( ): reducirla ≡ + ⋮ ≡ + ≡ + Como consecuencia de ello, se implementó el Algoritmo 10. De la misma manera, fueron implementados otros algoritmos similares para ( ) = + + + + 1, ( ) = + + 1 and ( ) = + + + + 1. Cuando los términos del medio están cerca uno del otro, esta operación se puede realizar de manera eficiente mediante la reducción de una palabra a la vez [8]. En particular, los polinomios definidos por el Instituto Nacional de Estándares y Tecnología (NIST) tienen esta condición. Considere ( ) = + + + , t=6. Suponga que [10] = ( , ( )= + + ⋯+ Entonces, + 1, por lo tanto , ,…, ) de + se reduce. Algoritmo 10: Reducción módulo ( ) = Entrada: Un polinomio (B[0], B[1],…, B[k-1]). Salida: ( ) ≡ ( ) ( )∈ ( ). + + 1. [ ], representado por a la introducida para computar el cuadrado de un polinomio binario, para realizar la extracción de bits. Por ejemplo, S[10101 ] = S[21 ] = 111 = 7 . Además un método llamado Calculate(E,O), donde E, O son yα respectivamente. Este arreglos que representan α método se emplea para calcular α + α √x y su comportamiento depende del polinomio de reducción empleado. Algoritmo 11 presenta el algoritmo implementado: Algoritmo 11: Raíz cuadrada de un elemento α ∈ , Entrada: Un elemento de un cuerpo α ∈ representado por (A[0], A[1],…, A[k-1]). . Salida: √α. Otra importante operación es la raíz cuadrada de un elemento . Es bien conocido que para α ∈ [x], α = α, por de = √α , lo cual requeriría m-1 elevaciones al tanto α cuadrado si la raíz cuadrada se implementase mediante esa fórmula. No obstante, cuando m es impar, un método más eficiente y elegante resulta de la siguiente observación [5]: α= ax. Note que la ecuación de arriba puede escribirse como: ( ( )/ a x + )/ a x = α + x α , donde ( )/ ( )/ =∑ a x y α =∑ a x. Como consecuencia, la raíz cuadrada se puede computar mediante la extracción de los bits apropiados de la , representación binaria de α con el fin de obtener α y α x y finalmente realizar luego realizar la multiplicación α √ la adición α + α √x. Nótese que √x puede ser precomputado tan pronto como el objeto correspondiente es instanciado, a saber, GF2Field. α Además nótese que la eficiencia de la operación raíz cuadrada depende en gran medida de la operación α √x. Avanzi [2] estudió esta última operación y notó que si el polinomio irreducible es de la forma f(x) = xQ(x) + 1, donde Q(x) tiene grado a lo mas (m-1)/2, α + α √x , con √x = xQ(x), tendría grado a los más m-1. Por consiguiente, una operación de reducción se ahorraría. Y que la multiplicación α √x podría ser computada mediante sumas y desplazamientos si la representación binaria de √x tiene pocos unos. Para implementar estas observaciones eficientemente se introdujo una tabla de búsqueda S de 2 valores, muy similar Finalmente el algoritmo 12 presenta la computación del . Este se basa en el algoritmo extendido inverso α de α ∈ de Euclides para polinomios binarios. . Algoritmo 12: Inverso de un elemento α ∈ , representado por (A[0], Entrada: Un elemento α ∈ A[1],…, A[k-1]). Salida: α . TABLA III. TIEMPOS PARA CUERPOS PRIMOS – NUESTRA LIBRERÍA. Número bits 43 adic 600 Operaciones (ns) mult cuad raíz 750 650 250 47 1100 1050 800 300 10350 89 950 600 650 600 12500 Inve 6700 127 750 700 700 950 14450 163 1050 1100 1000 1650 19900 233 1200 1600 1250 3600 38000 409 1350 2000 2650 10500 54400 571 1850 3100 2800 24300 76950 TABLA IV. TIEMPOS PARA CUERPOS BINARIOS – FLEXYPROVIDER. Número bits 43 47 83 127 163 163 191 233 233 409 571 Polinomio irreducible 43,6,4,3,0 47,5,0 83,29,25,3,0 127,1,0 163,7,6,3,0 163,57,49,29,0 191,9,0 233,74,0 233,159,0 409,87,0 571,10,5,2,0 adic 1450 1550 2000 2050 3300 3500 3600 4600 3600 4450 22700 Operaciones (ns) mult cuad raíz 3350 850 2600 3250 900 2100 8200 1000 6500 8400 1000 8150 16600 1400 17850 18300 1650 17300 17750 1650 13250 23900 2150 22750 21250 1700 23400 58100 2950 143100 293500 5700 900350 inve 4750 5300 10500 18600 22050 21050 25350 35800 30100 73550 575400 TABLA V. TIEMPOS PARA CUERPOS BINARIOS - BOUNCY CASTLE. IV. RESULTADOS DE RENDIMIENTO Esta sección muestra los tiempos de cada una de las operaciones previamente introducidas, sí mismo los tiempos consumidos por otras implementaciones, tales como la implementación Bouncy Castle [12] y la implementación FlexyProvider [13]. Estas pruebas se realizaron sobre una maquina con un procesador Intel Core I5 con rapidez de 2.5 GHz. Número bits 43 47 83 127 163 163 191 233 233 409 571 adic 3200 2850 2100 1900 2150 2400 3300 6250 Operaciones (ns) mult raíz 2400 1500 2350 1250 1800 1200 1500 1100 2000 1550 2400 1550 3650 2200 9100 5700 inve 13900 14950 18150 17100 24400 31650 245950 828600 adic 1000 mult 1200 Operaciones (ns) cuad raíz 700 550 47 1300 1450 800 5700 8550 Inve 7250 89 1450 1400 1100 1300 13100 127 1100 1450 800 1250 15600 163 1550 1850 1150 2600 18850 233 1600 2500 1550 3050 27600 409 2100 3850 2150 27900 87650 571 2950 4350 2800 36800 553000 mult 5350 35500 16100 10900 17800 10600 8150 11900 16700 25700 55250 Número bits Polinomio irreducible adic mult 43 47 83 127 163 163 191 233 233 409 571 43,6,4,3,0 47,5,0 83,29,25,3,0 127,1,0 163,7,6,3,0 163,57,49,29,0 191,9,0 233,74,0 233,159,0 409,87,0 571,10,5,2,0 750 700 1250 1850 1400 2250 2450 2100 2250 2600 2450 2800 2400 6000 6350 5500 8950 7750 6200 9300 11150 31000 TABLA II. TIEMPOS PARA CUERPOS PRIMOS – BOUNCY CASTLE. Número bits 43 adic 2250 2850 2950 3200 3400 2950 2100 2350 2400 3550 35600 Operaciones (ns) cuad raíz 2700 12400 18250 758850 6450 263600 2800 12500 2950 30900 2650 27200 2100 11400 2350 19150 2550 35050 3650 102250 5700 1242450 inve 2950 17200 45500 59300 78100 64300 53850 125400 68600 174200 787400 TABLA VI. TIEMPOS PARA CUERPOS BINARIOS – NUESTRA LIBRERÍA. TABLA I. TIEMPOS PARA CUERPOS PRIMOS – FLEXYPROVIDER. Número bits 43 47 89 127 163 233 409 571 Polinomio irreducible 43,6,4,3,0 47,5,0 83,29,25,3,0 127,1,0 163,7,6,3,0 163,57,49,29,0 191,9,0 233,74,0 233,159,0 409,87,0 571,10,5,2,0 Operaciones (ns) cuad raíz 850 800 1400 1300 650 2000 1700 1000 2050 1100 44350 3650 2500 4800 5150 6050 6300 6950 7150 7100 10300 30200 inve 3850 3650 7950 12200 18600 17700 23800 25600 24850 61400 288850 Por un lado, para probar cuerpos finitos lo siguiente es realizado: • • Un número primo de x bits es generado mediante el uso de un método provisto por la clase BigInteger. Para cada una de las implementaciones siendo analizadas, correspondientes objetos FieldElement son instanciados y luego operados muchas veces. • Los tiempos de cada una de las operaciones son promediados y estos se muestran en las tablas I, II, III respectivamente. Por otro lado, para probar cuerpos binarios lo siguiente es realizado: • • • Un cuerpo binario se construyen usando un + + + pentanomio irreducible, es decir, + o un trinomio irreducible + + . Por ejemplo, para 43 bits el pentanomio irreducible + + + + es empleado. Para cada una de las implementaciones siendo analizadas, correspondientes objetos FieldElement son instanciados y luego operados muchas veces. Los tiempos de ejecución para cada una de las operaciones son promediadas y estos se muestran en la tablas IV, V,VI. científicos de la computación, y profesionales que deseen construir aplicaciones, construcciones matemáticas o cualquier otro tipo de cosas usando cuerpos primos o binarios. Además de aquellos atributos de calidad, la librería fue concebida para ser eficiente lo que conllevó a la implementación de varios trucos previamente introducidos en la literatura así como algunos nuevos. Como resultado de eso, los tiempos de cada una de las operaciones así como se mostró son considerablemente competitivas cuando se comparan a otras dos implementaciones de java reputadas y ampliamente usadas. Cómo trabajos futuros, se planea hacer mejoramientos e introducción de nuevas características a la librería así como la liberación del código fuente. Adicionalmente, se planea la construcción de un proveedor para JCA. REFERENCIAS [1] Note que los polinomios irreducibles empleados para la construir los cuerpos binarios son “square root friendly”, lo cual ayuda a mejorar la eficiencia de ciertas operaciones. Adicionalmente, note que las dos implementaciones consideradas en nuestra comparación son usadas masivamente por programadores como proveedores (Patrón de diseño) cuando se usa JCA (Java Cryptography Arquitectura, por sus siglas en ingles) [13], [14] y [15]. A partir de los tiempos obtenidos para cada una de las operaciones implementadas puede ser expresado que es necesario un mejoramiento de otras implementaciones ampliamente conocidas y reputadas ya que el rendimiento de la librería introducida es competitivo. Además, es valioso mencionar que aunque otros resultados más eficientes se han reportados en la literatura, aquellas implementaciones se han realizado sobre lenguajes de programación, tales como C o Assembly, los cuales son fuertemente dependientes del sistema operativo o la arquitectura de la maquina. Por tanto, su usabilidad and extensibilidad son limitadas - desde un punto de vista del software, hay siempre un “trade-off” entre los atributos de calidad cuando una unidad de software es diseñada, en otras palabras, aquellos atributos escogidos como prioritarios le dan forma a dicha unidad de software. V. CONCLUSIONES Una implementación de cuerpos primos y binarios sobre java se introduce. El conjunto de clases introducidas se idearon teniendo en cuenta los atributos de calidad extensibilidad, modificabilidad, usabilidad e interoperabilidad. Estos atributos de calidad facilitan el mejoramientos y futuras construcciones en la librería sin reinventar la rueda. Además, esta colección de clases fue pensada para ser de utilidad para matemáticos, [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] D. F. Aranha, J. Lopez and D. Hankerson Efficient Software Implementation of Binary Field Arithmetic Using Vector Instruction Sets, in Proc. of First International Conference on Cryptology and Information Security in Latin America (Latincrypt 2010), Puebla, Mexico, August 811, 2010. R. Avanzi, Another Look at Squares Roots and Traces (and Quadratic Equations) in Fields of Even Characteristic. In Proc. 4th International Workshop (SAC 2007), 2007. R. Avanzi, N. Thriault, Effects of Optimizations for Software Implementations of Small Binary Field Arithmetic, in Proc. First International Workshop Arithmetic of Finite Fields (WAIFI 2007), June pp. 21-22, 2007. J.P Deschamps, J.L. Imana and G. Sutter, Hardware Implementation of Finite-Field Arithmetic, McGraw-Hill Professional, 1. Ed, 2009. K. Fong, D. Hankerson, J. Lopez and Alfred Menezes Field inversion and point halving revisited, IEEE Transactions on Computers, Vol. 53, pp.1047-1059, 2003. I. Gutierrez Garcia and W. Willems. Una introducción a la criptografía de clave pública, Segunda Edición, Ediciones Uninorte, 2011. I. Gutierrez Garcia and Y. Zuleta. An algorithm to generate binary Gabidulin codes using SAGE. IEEE latin America transactions, Vol. 13, No. 5, pp. 1469-1477, May 2015. D. Hankerson, A. Menezes and S. Vanstone, Guide to Elliptic Curve Cryptography, Springer-Verlag, 2004. R. Lidl and H. Niederreiter, Finite Fields, Encyclopedia of Mathematics and its applications, vol. 20, Addison-Wesley, Reading, 1983. J. Taverne and A. Faz-Hernandez and D. F. Aranha and F. RodrguezHenrquez and D. Hankerson and J. Lopez. Speeding scalar multiplication over binary elliptic curves using the new carry-less multiplication instruction, Journal of Cryptographic Engineering, Volume 1, Number 3, pp. 187-199, 2011. F. Wang, Y. Nogami, and Y. Morikawa, A High-Speed Square Root Computation in Finite Fields with Application to Elliptic Curve Cryptosystem, Memoirs of the Faculty of Engineering, Okayama University, Vol.39, pp. 82-92, January, 2005. M. Welschenbach , Cryptography in C and C++, 2. Ed., Apress, 2005. https://www.bouncycastle.org/java.html https://www.flexiprovider.de/overview.html http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/Cr yptoSpec.html Ismael Segundo Gutiérrez García, recibió su título de Máster en Matemáticas en Universidad del Norte – Universidad del Valle, el grado de Dr. rer. nat. En la Universidad Johannes Gutenberg de Mainz - Alemania. Sus áreas de interés son los Grupos finitos soluble, la teoría clásica de códigos y las aplicaciones de cuerpos finitos en codificación lineal aleatoria en redes. Ricardo Luis Villanueva Polanco, recibió su título de Ingeniero de Sistemas en la Universidad del Norte, el título de Máster en Ciencias de la computación en la Universidad de los Andes, Bogotá – Colombia y actualmente adelanta estudios de doctorado en Royal Holloway, University en Londres. Sus áreas de interés son Criptografía y seguridad en la Información.