Você está na página 1de 20

Programa Insitucional de Bolsas de Iniciao Cientca - PIBIC/CNPq

Relatrio Parcial de Atividades

Criptossistemas baseados em emparelhamentos bilineares sobre curvas elpticas

Aluno: Matheus Fernandes de Oliveira (RA 034766)

Orientador: Prof. Dr. Marco Aurlio Amaral Henriques

08/2005 a 01/2006

Sumrio
1 Introduo 2 Tcnicas de Criptograa 2.1 2.2 Criptograa Simtrica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Criptograa Assimtrica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 4 4 5 6 7 7 8 8 8 9 12 13 15 15 15 19 19

3 Criptograa de Curvas Elpticas 4 Aritmtica sobre Corpos Finitos 5 Aritmtica de Curvas Elpticas 6 Emparelhamentos Bilineares sobre Curvas Elpticas 6.1 6.2 6.3 Divisores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Principais propriedades dos emparelhamentos bilineares . . . . . . . . . . Criptossistemas baseados em Emparelhamentos Bilineares sobre Curvas Elpticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 Detalhes da implementao 7.1 7.2 Camada1 - Aritmtica no corpo nito . . . . . . . . . . . . . . . . . . . . Camada 2 - Operaes sobre a Curva Elptica . . . . . . . . . . . . . . . .

8 Concluses e Trabalhos Futuros A Cdigos A.1 Aritmtica no Corpo Finito Arquivo d_2163.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 Aritmtica no Corpo Finito Arquivo d_2163.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3 Operaes sobre a Curva Arquivo ecc_arith.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.4 Operaes sobre a Curva Arquivo ecc_arith.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Resumo Emparelhamentos bilineares sobre curvas elpticas tm recebido considervel ateno por parte da comunidade cientca e de empresas envolvidas com criptograa. Aliando ecincia e segurana, os emparelhamentos permitem a soluo de antigos problemas e viabilizam novos paradigmas tais como a criptograa baseada em identidades. O presente relatrio tem como objetivo documentar a primeira etapa do projeto de iniciao cientca nanciado pelo programa PIBIC/CNPq cuja nalidade estudar, implementar e avaliar criptossistemas baseados no Emparelhamento de Tate.

Introduo

O projeto de pesquisa Implementao de criptossistemas baseados em emparelhamentos bilineares sobre curvas elpticas tem como objetivo pesquisar e desenvolver formas ecientes de implementar o emparelhamento de Tate. Com base nesse emparelhamento, pretende-se fazer a implementao de um sistema de codicao/autenticao de dados. Para cumprir os objetivos do projeto, foi elaborado um cronograma de execuo. Tal cronograma previa na primeira etapa do trabalho o levantamento de material bibliogrco, estudo dos emparelhamentos bilineares sobre curvas elpticas, implementao das camadas de software relativas aritmtica no corpo nito e operaes na curva elptica, bem como a elaborao deste relatrio parcial de atividades. Esse plano de trabalho foi cumprido e neste relatrio so descritos os aspectos mais relevantes da etapa inicial do projeto de iniciao cientca. Este relatrio estruturado da seguinte forma. Na seo 2 faz-se uma breve introduo criptograa. A seo 3 apresenta uma descrio do uso de curvas elpticas para ns criptogrcos. A aritmtica sobre corpo nitos descrita na seo 4. Na seo 5 apresentada a aritmtica de curvas elpticas. Na seo 6 introduz-se o conceito de emparelhamento bilinear. A seo 7 descreve detalhes da implementao feita at o momento, como algoritmos utilizados e testes realizados. Os avanos obtidos na primeira etapa do projeto e os trabalhos futuros so descritos na seo 8. Finalmente, o apndice A apresenta a listagem das camadas implementadas.

Tcnicas de Criptograa

Criptograa consiste na cincia de escrever em cifra ou em cdigo. Utilizando tcnicas criptogrcas, possvel que uma mensagem seja compreensvel apenas s partes interessadas: emissor e destinatrio. O uso de criptograa antigo. Segundo Menezes et al.[1], h quase quatro mil anos os egpcios j escreviam hierglifos de uma forma especial a m de que apenas algumas pessoas pudessem compreender a mensagem original. Ao longo dos anos, novas tcnicas criptogrcas se desenvolveram e passaram a ser aplicadas em assuntos que variavam desde a diplomacia at assuntos blicos. Atualmente, quando se vislumbra a populao mundial cada vez mais conectada por dispositivos eletrnicos, cenrio onde tambm se encontram vrus, hackers, espionagem e fraudes eletrnicas, urge que a segurana esteja mais presente nas comunicaes. diante desse contexto que a antiga arte de criptografar tem evoludo e apresentado tcnicas capazes de atender s necessidades de segurana atuais com ecincia e conabilidade. De acordo com Stallings [2], quando se faz uso de algum algoritmo criptogrco, procura-se basicamente um servio capaz de assegurar:

autenticao: forma de certicar que a entidade com quem se comunica realmente quem ela diz ser; controle de acesso: previne o uso no autorizado de determinados recursos; sigilo: impede o acesso no autorizado de dados enviados; integridade dos dados: assegura que os dados recebidos so idnticos aos que foram enviados por uma entidade autorizada; no repdio: impede que uma das entidades envolvidas negue sua participao em toda ou parte da comunicao. As duas tcnicas mais comuns de criptograa consistem na criptograa simtrica e criptograa assimtrica.

2.1

Criptograa Simtrica

Utiliza uma nica chave secreta, cuja cpia ca sob a posse do emissor e do destinatrio. Essa chave utilizada para codicao e decodicao. Os algoritmos mais comuns para criptograa simtrica so DES, RC4 e AES.

2.2

Criptograa Assimtrica

Tambm conhecida como criptograa de chave pblica, utiliza duas chaves fortemente relacionadas: chave pblica e chave privada. Tais denominaes so bastante apropriadas, pois o primeiro tipo de chave (chave pblica) de conhecimento geral, ao passo que o segundo (chave privada) mantido em sigilo pelo proprietrio. O esquema de Rivest-Shamir-Adleman (RSA) [2] tem sido largamente utilizado no campo da criptograa de chave pblica. A segurana do RSA baseia-se na intratabilidade da fatorao de nmeros inteiros grandes. Apesar de bastante utilizado, o RSA tem garantido nveis de segurana satisfatrios custa de chaves cada vez maiores. Como conseqncia, o tempo de execuo do algoritmo torna-se tambm maior. Por isso, nos ltimos anos tem ganhado cada vez mais destaque no campo da criptograa de chave pblica os criptossistemas baseados em curvas elpticas.

Criptograa de Curvas Elpticas

Curvas elpticas tm uma longa histria [3]. Elas j foram utilizadas para resolver vrios problemas, como o famoso ltimo Teorema de Fermat [4], por exemplo. Uma curva elptica sobre nmeros reais pode ser denida como um conjunto de pontos da forma (x, y ) que satisfazem a equao: y 2 + a1 xy + a3 y = x3 + a2 x2 + a4 x + a6 (1)

mais um ponto extra, chamado ponto no innito, denotado por O. Os coecientes ai , neste caso, so reais. Mais detalhes da aritmtica envolvida na criptograa sobre curvas elpticas sero discutidos posteriormente. Em 1985, Neal Koblitz e Victor Miller propuseram independentemente o uso de curvas elpticas para desenvolver sistemas de criptograa de chave pblica. Desde ento vrias 4

pesquisas tm evidenciado a segurana e a ecincia que advm do uso de curvas elpticas para ns criptogrcos. No nal dos anos noventa, criptossistemas baseados em curvas elpticas comearam a receber aceitao de companhias privadas e rgos pblicos [3]. A segurana de um sistema de criptograa baseado em curvas elpticas - ECC (Elliptic Curve Cryptography) - baseia-se no problema do logaritmo discreto em tais curvas [5]. Uma das vantagens do uso de ECC em detrimento do RSA se encontra no tamanho das chaves utilizadas. De acordo com o tutorial sobre ECC da empresa Certicom [6], uma chave ECC de 163 bits oferece o mesmo nvel de segurana de uma chave RSA de 1024 bits.

Aritmtica sobre Corpos Finitos

A apresentao a respeito de corpos nitos, aritmtica de curvas elpticas e emparelhamentos bilineares explicita apenas as caractersticas mais importantes desses tpicos. Um estudo mais profundo e minucioso foi feito acerca desses mesmos assuntos de forma a permitir sua total compreenso e assim viabilizar sua implementao. Para isso, foi organizado um material mais extenso, com as principais bibliograas existentes e vrios artigos publicados sobre o assunto, material este no apresentado aqui por questes de espao. Corpos so abstraes dos sistemas numricos e suas propriedades essenciais [3]. Eles so formados por um conjunto F e de duas operaes binrias - adio (denotada por +) e multiplicao (denotada por ) - que satisfazem as seguintes propriedades: (F, +) um grupo abeliano com elemento identidade denotado por 0; (F\{0}, ) um grupo abeliano com elemento identidade denotado por 1; a propriedade distributiva vlida, ou seja, (a + b) c = a c + b c para todo a, b, c F. Se o conjunto F nito, ento o corpo nito. No projeto em desenvolvimento, foram utilizados corpos binrios, ou corpos de caracterstica dois, denotados por F2m , sendo m um inteiro chamado extenso do corpo. No nosso caso, utilizamos m = 163. Esse valor foi escolhido com base nos valores recomendados pelo NIST [7], rgo reponsvel pelo estabelecimento de padres no campo de criptograa. A escolha de corpos binrios bastante vantajosa em vrias situaes, j que a representao interna dos dados nos computadores tambm binria. Para representao dos elementos do corpo, utilizou-se a base polinomial. Dessa forma, os elementos do corpo F2m so polinmios binrios (polinmios cujos coecientes esto no corpo F2 = {0, 1}) com grau no mximo igual a m 1: F2m = {am1 xm1 + am2 xm2 + + a2 x2 + a1 x1 + a0 : ai {0, 1}}. (2)

Um elemento importante na aritmtica de corpo nito o polinmio irredutvel de grau m. Na implementao feita, o polinmio utilizado foi f (x) = x163 + x7 + x6 + x3 + 1. O polinmio dito irredutvel porque no pode ser fatorado como o produto de polinmios binrios cujo grau seja menor que m. Uma tabela com polinmios irredutveis pode ser encontrada em [3]. A adio (e subtrao) de elementos do corpo F2m feita como na adio usual de polinmios, com coecientes reduzidos mdulo 2. O mesmo ocorre com a multiplicao de elementos do corpo, mas a reduo feita com o polinmio irredutvel f (x).

Aritmtica de Curvas Elpticas

Uma curva elptica j foi exemplicada anteriormente na seo 3 para o caso dos nmeros reais. De um modo geral, uma curva elptica E sobre um corpo Fpm (p um primo) denida pela equao 1, com ai Fp , mais um ponto extra, denominado ponto no innito, O e = 0, onde o discriminante da curva [5]. Para a curva supersingular E/F2m : y 2 + y = x3 + ax + b seguem as operaes: 1. identidade: P + O = O + P para todo P E (F2m ); 2. negativo: Se P = (x, y ) E (F2m ) e se (x, y ) + (x, y + c) = O, ento o ponto (x, y + c) denotado por P e chamado negativo de P ; 3. adio de pontos: Seja P = (x1 , y1 ) E (F2m ) e Q = (x2 , y2 ) E (F2m ), onde P = Q. Ento P + Q = (x3 , y3 ), onde: x3 = y1 + y2 x1 + x2
2

(3)

+ x1 + x2

(4)

y3 =

y 1 + y2 x1 + x2

(x1 + x3 ) + y1 + c;

(5)

4. duplicao de pontos: Seja P = (x1 , y1 ) E (F2m ), com P = P . Ento 2P = (x3 , y3 ), onde 2 x1 2 + a (6) x3 = c x1 2 + a c

y3 =

(x1 + x3 ) + y1 + c.

(7)

O nmero de pontos de uma curva elptica E (Fq ), representado por #E (Fq ), chamado ordem da curva. A ordem de um ponto P E (Fq ) o menor inteiro positivo r que multiplicado pelo ponto P (multiplicao por escalar) resulta no ponto no innito, ou seja, [r]P = O. Com isso, dene-se o subgrupo de torso, o qual contm os pontos de ordem mltipla de r, denotado por: E (Fq )[r] = {P E (Fq ) | [r]P = O}. (8)

Um outro conceito importante a respeito de curvas elpticas, de acordo com Maas [8], o grau de imerso. Denio 1 Seja E (Fq ) uma curva elptica denida sobre o corpo Fq . Seja r um inteiro positivo, coprimo a q , tal que E (Fq ) contm um ponto de ordem r. Em implementaes criptogrcas, r geralmente um nmero primo grande que divida a ordem da curva, ou seja, r | #E (Fq ). Seja k o menor inteiro que satisfaz r | q k 1. O valor de k consiste no grau de imerso da curva.

Emparelhamentos Bilineares sobre Curvas Elpticas

Um emparelhamento bilinear denido como um isomorsmo que mapeia elementos de um conjunto de pontos de uma curva E (Fq ) para um subgrupo de um corpo de extenso de Fq . O emparelhamento mais utilizado atualmente o emparelhamento de Tate, cuja denio formal ser feita a seguir.

6.1

Divisores

Divisores so utilizados na denio de emparelhamentos. Sero apresentadas apenas as propriedades mais importantes referentes aos divisores, como encontrado na referncia [9]. Seja E (Fq ) uma curva elptica. Um divisor D a soma formal : D=
P E

np (P )

(9)

onde np Z. O grau de um divisor denido como: deg (D) = e a soma o ponto: sum(D) = [np ]P E (Fq ). (11) np Z (10)

O grupo de divisores de E (Fq ) denotado por Div (E ). O suporte de um divisor dado pelo conjunto de pontos: supp(D) = {P E | np = 0}. (12)

H um subconjunto especial de Div (E ), no qual todo divisor possui grau zero, denotado por Div 0 (E ). Um divisor D dito principal se e somente se seu grau nulo e sua soma igual ao ponto no innito, O. Dois divisores D1 e D2 so equivalentes, D1 D2 , se a diferena entre eles D2 D1 um divisor principal. Uma funo racional g : F F F tem a forma g (x, y ) = N (x, y ) , D(x, y ) (13)

onde N (x, y ) e D(x, y ) so duas funes nas variveis x e y . Diz-se que uma funo tem um zero no ponto P quando ela se anula em P e um plo quando assume o valor innito em P . Denio 2 Seja E (Fq ) uma curva elptica que contm um subgrupo de ordem r, grau de imerso k e um mltiplo de r que divide q k 1. Seja P E (Fq )[ ], Q E (Fqk ), f uma funo racional com divisor que satisfaz f = (P ) (O) e D (Q) (O) um divisor com suporte disjunto de f . Ento o emparelhamento de Tate de ordem a funo racional e : E (Fq ) E (Fqk ) F q k , denida por: e (P, Q) f (D)(q 7
k

1)/

(14)

6.2

Principais propriedades dos emparelhamentos bilineares


e (P1 + P2 , Q) = e (P1 , Q) e (P2 , Q) e e (P, Q1 + Q2 ) = e (P, Q1 ) e (P, Q2 ) (16) para todo P, P1 , P2 E (Fq )[ ] e todo Q, Q1 , Q2 E (Fqk ). O smbolo denota uma multiplicao. Dessa forma: e ([a]P, Q) = e (P, [a]Q) = e (P, Q)a para todo a Z; (17) (15)

Bilinearidade:

No-degenerado: se e (P, Q) = 1 para todo Q E (Fqk ), ento P = D. E para cada P = D Q E (Fqk )[ ] de forma que e (P, Q) = 1; Compatibilidade: seja = h , P E (Fq )[ ] e Q E (Fqk )[ ]. Ento e (hP, Q) = e (P, Q)h .

6.3

Criptossistemas baseados em Emparelhamentos Bilineares sobre Curvas Elpticas

Sistemas criptogrcos baseados em identidades, como proposto por Boneh e Franklin [3], requerem um mapeamento bilinear, como o emparelhamento de Tate. Muitos criptossistemas interessantes podem ser implementados tomando como base um emparelhamento bilinear, como o esquema chamado criptoassinatura [10]. Uma excelente referncia para esse assunto a pgina na Web do professor Paulo Barreto, Pairing-Based Cripto Lounge [11].

Detalhes da implementao

Aps a construo do embasamento terico, o projeto direcionou-se para a fase de implementao, que foi esquematizada em camadas (Fig.1). Aplicaes Emparelhamento de Tate Operaes sobre a curva Aritmtica no corpo de extenso Aritmtica no corpo nito Figura 1: Esquema da implementao

A codicao das rotinas est sendo feita na linguagem ANSI-C em um desktop Pentium 4. Os programas foram compilados com GCC verso 3.4.5, utilizando as ags -03 -fomit-frame-pointer -unroll-loops. O objetivo da ag O3 realizar otimizaes de forma que sejam reduzidos o tamanho do cdigo e o tempo de execuo. A ag fomit-frame-pointer indica que o uso do registrador frame pointer no necessrio. O registrador adicional implica um ganho de velocidade do programa. Enm, unroll-loops procura otimizar os loops nos quais o nmero de iteraes pode ser determinado em tempo de compilao. 8

Atualmente j esto prontas e testadas as camadas referentes Aritmtica no corpo nito e Operaes sobre a curva. O cdigo referente a essas camadas encontra-se no apndice A ao nal deste documento. A camada referente Aritmtica no corpo de extenso j est sendo implementada. To logo esteja pronta, sero implementadas as duas camadas restantes. Os detalhes referentes s camadas implementadas, como escolha dos algoritmos e rotinas de testes, sero apresentados a seguir.

7.1

Camada1 - Aritmtica no corpo nito

A implementao dessa camada baseou-se em algumas denies encontradas no livro de Michael Rosing [12]. Aplicaes criptogrcas exigem o uso de nmeros cujas representaes requerem um nmero de bits que excedem a capacidade de armazenamento dos tipos pr-denidos na linguagem C. Os elementos do corpo binrio F2163 necessitam, de acordo com a equao 2, de 163 bits para serem representados. Considerando que cada palavra da mquina utilizada possui 32 bits, foi denido um novo tipo, chamado BigInt. Para a denio desse novo tipo, foi necessrio considerar o nmero de bits que cada instncia de um BigInt deveria possuir. Esse cuidado se deve ao seguinte fato: um polinmio do corpo considerado pode ser armazenado em, no mximo, 6 palavras de 32 bits, mas caso sejam multiplicados dois polinmios cujo grau seja elevado, ento so necessrias mais palavras a m de que o resultado da multiplicao possa ser armazenado. Essa mesma necessidade por maior espao de armazenamento tambm ocorre para o caso de elevar o polinmio ao quadrado. O esquema da estrutura BigInt encontra-se na Fig.2. 0101 1100
P alavra da ma quina

0101 1100

0101 1100

0101 1100

Figura 2: Estrutura BigInt

A denio do novo tipo implicou a nescessidade de criar rotinas que implementassem operaes bsicas entre as estruturas BigInt : poly_null: anula todos os bits da estrutura BigInt ; poly_copy: faz a cpia de um BigInt em outro BigInt ; poly_cmp: verica se duas estruturas BigInt so iguais ou no. As funes listadas acima so simples e foram facilmente testadas. Para facilitar os testes das demais funes, foram denidas rotinas de entrada e sada: in_poly: l uma palavra por vez, at completar o tamanho do BigInt ; out_poly: imprime na tela o contedo de uma estrutura BigInt no formato hexadecimal. Por exemplo, se uma das palavras da estrutura for a seguinte: 1001 0000 0011 1001 0000 0110 0101 1110 Ento a funo out_poly produz a sada: 0x9039065E; 9

out_poly2: imprime na tela o contedo de uma estrutura BigInt na forma de polinmios. No caso do exemplo anterior, a sada seria: x^31+ x^28+ x^21 + x^20 + x^19 + x^16 + x^10 + x^11 + x^6 + x^4 + x^3 + x^2 + x^1. Essa forma de sada muito til para realizao de testes das rotinas mais avanadas. Os polinmios do corpo binrio foram representados na estrutura BigInt, o que permitiu efetuar as operaes bsicas: poly_rightShift: desloca todos os bits do polinmio uma posio direita. Na Fig.3 encontra-se o exemplo do que ocorre para uma palavra do polinmio (considerando que o ltimo bit da palavra anterior era igual a 0); 0000 0001 0010 1010 0000 0000 1111 0010 0000 0000 1001 0101 0000 0000 0111 1001 Figura 3: Exemplo da operao de shift direita em uma palavra

poly_leftShift: desloca todos os bits do polinmio uma posio esquerda. Na Fig.4 encontra-se o exemplo do que ocorre para uma palavra do polinmio; 0000 0001 0010 1010 0000 0000 1111 0010 0000 0010 0101 0100 0000 0001 1110 0100 Figura 4: Exemplo da operao de shift esquerda em uma palavra

poly_add: A adio de polinmios binrios muito simples, j que ela consistem apenas da operao XOR, denotada por (Fig. 5). importante lembrar que num corpo binrio a operao de subtrao a mesma da adio; 110110 010010

011110

100111

101000

110101

Figura 5: Exemplo de adio de polinmios binrios

poly_mult: utilizou-se o mtodo mais eciente de multiplicao de polinmios binrios, conhecido como right-to-left comb method [3]. Esse mtodo bastante interessante e baseia-se na observao de que se b(x) xk j foi calculado para algum k [0, W 1], onde W o nmero de bits da palavra de mquina, ento b(x) xW j +k pode ser facilmente obtido acrescentando j palavras zeradas direita da representao de b(x) xk . A funo poly_mult utiliza as funes auxiliares adjust_poly e poly_addEspecial, que tm como objetivo somar apenas algumas partes do polinmio que est sendo multiplicado ao resultado da multiplicao; 10

poly_reduction: operaes como elevar ao quadrado e multiplicao tm como resultado polinmios cujo grau, na maioria das vezes, excede a extenso do corpo. Por isso, deve-se efetuar a reduo modular disponibilizada por esta funo; poly_inverse: calcula o inverso de um polinmio do corpo. Por exemplo, se p(x) um polinmio binrio, seu polinmio inverso p1 (x), de forma que p(x) p1 (x) 1 mod f (x), onde f (x) o polinmio irredutvel do corpo. Utiliza as funes auxiliares cond_poly, cond_polyAux e isOne, cujas nalidades so vericar o grau do polinmio que est sendo invertido; poly_div: realiza a diviso de dois polinmos. Se a(x) e b(x) so dois polinmios (x) do corpo binrio, ento c(x) o resultado da operao c(x) = a b(x) ; poly_sqr: eleva ao quadrado um polinmio binrio. Note que, como as operaes no corpo binrio so todas reduzidas mdulo 2, a operao de elevar ao quadrado pode ser efetuada entremeando com zeros os coecientes do polinmio, conforme mostrado na Fig. 6; am1 am2 0 am1 0 am2 0 0 a1 0 a0 a1 a0

Figura 6: Elevando ao quadrado um polinmio binrio a(x) = am1 xm1 + . . . + a2 x2 + a1 x + a0

poly_sqrt: calcula a raiz quadrada de um polinmio. Essa rotina ser importante no clculo do Emparelhamento de Tate, como se pode ver no algoritmo 3 em [13]. Utiliza a funo auxiliar interleave_zeros, a qual insere zeros entre os coecientes de uma palavra do polinmio que est sendo elevado ao quadrado; poly_random: gera um polinmio aleatrio de grau no mximo igual a 162 (a extenso do corpo binrio utilizado m = 163). As rotinas de testes das operaes com polinmios foram realizadas considerando vrios casos, que abrageram desde as condies triviais at as mais complexas. Foram testados os casos que envolviam limites, como polinmios de grau baixo e de grau elevado. A vericao dos resultados foi feita manualmente, utilizando diferentes funes da calculadora HP 49G+, em especial as funes que realizam arimttica modular e polinomial. Foram realizados testes nos quais as funes utilizadas eram diferentes, mas esperava-se resultados idnticos. Por exemplo, os resultados de elevar ao quadrado foram iguais aos resultados da multiplicao de dois polinmios idnticos. Testou-se ainda o caso de operaes inversas, como por exemplo as razes quadradas, que ao serem elevadas ao quadrado resultaram no polinmio original. Tambm os resultados da operao de diviso foram multiplicados pelo denominador, quando ento se obteve o numerador da diviso, como esperado. importante lembrar que, apesar de estar sendo considerado o corpo F2163 , as rotinas dessa primeira camada so genricas e podem ser utilizadas para corpos diferentes.

11

7.2

Camada 2 - Operaes sobre a Curva Elptica

Aps formada a base que permite manipular nmeros grandes e polinmios do corpo binrio, foi possvel implementar as operaes sobre a curva elptica em coordenadas am (pontos da forma (x, y )): y 2 + y = x3 + x. (18)

A curva descrita pela Eq.18 de interesse para o clculo eciente do Emparelhamento de Tate, como se pode ver na referncia [13]. As operaes com pontos da curva elptica so: adio, duplicao e multiplicao por escalar. Tais operaes foram descritas com detalhes na seo 5. Para representao de um ponto em coordenadas am, foi denida a estrutura POINT, na qual duas estruturas BigInt guardam os valores das coordenadas x e y . Antes de codicar as operaes sobre a curva, foram implementadas rotinas bsicas: point_copy: faz a cpia de um ponto; point_out: imprime as coordenadas de um ponto da curva em formato hexadecimal (utiliza a funo out_poly da camada de aritmtica no corpo nito); point_random: utilizando a funo da camada anterior que gera polinnios aleatrios, essa rotina gera um ponto aleatrio da curva. Note, no entanto, que no basta escolher as coordenadas x e y aleatoriamente. Elas devem satisfazer a Eq.18. Por isso, o procedimento consistiu em gerar a coordenada x de um ponto e partir da calcular o segundo membro da equao da curva elptica, cujo valor ser denotado por . Tem-se agora que y 2 + y = , que uma equao quadrtica em y . Baseado no algoritmo publicado em [14], foi possvel implementar o mtodo que fornece a soluo da referida equao quadrtica e assim obter a coordenada y do ponto; point_valid: verica se as coordenadas do ponto satisfazem equao da curva (Eq.18). Essa rotina de grande importncia durante os testes das operaes com pontos da curva elptica. Utilizando as rotinas auxiliares acima descritas, foi possvel implementar as operaes sobre a curva: point_neg: retorna o negativo de um ponto pertencente curva; point_add: efetua a adio de dois pontos da curva elptica; point_add: duplica um ponto da curva; point_mult: multiplica um ponto P da curva por um escalar k que possua t bits, conforme encontrado na referncia [3] e listado no algoritmo 1. Os testes referentes camada de operaes sobre a curva so mais difceis de vericar em relao aos testes da camada inferior. Para efetuar a adio de pontos, por exemplo, necessrio que sejam realizadas vrias operaes com as coordenadas dos pontos, como adio, diviso e reduo polinomial. Os resultados de alguns testes novamente foram vericados manualmente com a calculadora HP 49G+. Outros testes consistiram em: somar um ponto P com seu negativo P e vericar se o resultado era o ponto no innito; 12

Algoritmo 1 Mtodo para multiplicao escalar de pontos da curva Entrada: k = (kt1 , . . . , k1 , k0 ), P E (Fq ). Sada: O valor de kP em Q. 1: Q O . 2: for i from 0 downto t 1 do 3: if ki = 1 then 4: Q Q + P. 5: end if 6: P 2P . 7: end for 8: return (Q).

duplicar o ponto P : Q = 2P . Duplicar o resultado: R1 = 2Q = 4P . Depois, somar duas vezes a Q o ponto P : R2 = Q + P + P e vericar se R1 e R2 eram iguais; calcular 2P + P (uma duplicao e uma adio) e 3P (multiplicao por escalar) e vericar se os resultados so idnticos. duplicar o ponto P , somar com seu negativo P e vericar se resulta no prprio ponto P , pois 2P + (P ) = P . Esse teste interessante, pois utiliza as funes point_double, point_neg e point_add. Vrios outros testes que utilizavam diferentes operaes para obter os mesmos resultados nais foram realizados, alm dos testes descritos acima. Aps correo de alguns erros e repetio das rotinas de testes, os resultados indicaram a correo das funes implementadas.

Concluses e Trabalhos Futuros

As camadas implementadas at o momento constituem uma base para implementao de criptossistemas baseados em emparelhamentos bilineares sobre curvas elpticas. Um cronograma foi elaborado para sistematizar as atividades da primeira etapa do projeto de pesquisa. No primeiro momento, as atividades consistiram em pesquisar acerca dos seguintes assuntos: criptograa, uso de curvas elpticas para ns criptogrcos, teoria dos divisores, emparelhamentos bilineares e criptograa baseada em identidades. Logo em seguida, as atividades se direcionaram para a fase de implementao e testes das camadas de software que permitissem formar uma base para o sistema criptogrco baseado no emparelhamento bilinear. Com esse intuito, foram implementadas as camadas referentes aritmtica no corpo nito e operaes sobre curvas elpticas. Em seguida, vericou-se o funcionamento dessas mesmas camadas atravs de testes variados. Agora o trabalho continua na fase de implementao, mas direcionado s camadas superiores e que fazem uso das camadas j implementadas. De acordo com o cronograma inicial, o principal objetivo a ser atingido nos prximo meses ser implementar e testar as camadas referentes aritmtica no corpo de extenso, emparelhamento de Tate e, enm, o criptossistema.

13

Referncias
[1] Alfred J. Menezes, Paul C. van Oorschot and Scott A. Vasntone. Handbook of Applied Cryptography. CRC Press, 1996. [2] Willian Stallings. Cryptography and Network Security. Addison-Wesley, 2003. [3] Alfred Menezes, Darrel Hankerson and Scott Vanstone. Guide to Elliptic Curve Cryptography. Springer Professional Computing, 2004. [4] K. H. Rosen. Discrete Mathematics and its applications. McGraw-Hill, 2003. [5] Alfred J. Menezes. Elliptic Curve Public Key Cryptosystems. Kluwer Academic Publishers, 1993. [6] ECC tutorial. http://www.certicom.com/index.php?action=ecc, ecc_tutorial. [7] FIPS 186-2. Padro para assinatura digital (DSS). Federal Information Processing Standards Publication 186. NIPS: Intituto Nacional de Padres e Tecnologia, 2000. [8] Martjin Maas. Pairing-Based Cryptography. Masters Thesis, Technische Universiteit Eindhoven, 2004. [9] D.R.Jr, Ecient implementation of pairing based cryptosystems over gf (3m ), 2005. [10] W.D.B. Jnior. Sistemas Criptogrcos Baseados em Identidades Pessoais. Masters thesis, Universidade de So Paulo, 2003. [11] The Pairing-Based Crypto Lounge. informatica/paulobarreto/pblounge.html. http://paginas.terra.com.br/

[12] Michael Rosing. Implementing Elliptic Curve Cryptography. Manning, 1999. [13] P.S.L.M.Barreto, S. Galbraith, C.O hEigeartaigh e M.Scott. Ecient Pairing Computation on Supersingular Abelian Varieties. Criptology ePrint Archive, Report 2004/375. [14] Institute of Eletrical and Eletronics Engineers(IEEE), Inc. P1363 - Standard Specication for Public Key Cryptography, 2000.

14

Apndice
A Cdigos

Nesta seo a apresentada a listagem das camadas que j esto prontas e testadas. Atravs dos comentrios no cdigo possvel compreender o funcionamento de cada rotina. Os comentrios tambm revelam os passos menos triviais do algoritmo implementado.

A.1

Aritmtica no Corpo Finito Arquivo d_2163.h


typedef unsigned long ELEMENT; // part of polynomial /*structure to represent big numbers*/ typedef struct BigInt{ ELEMENT pol[DOUBLESIZE];

/* ffld_2^163.h * * Large integer math header * Each big integer is represented as * a polinomial */ #include #include #include #include <stdio.h> <stdlib.h> <string.h> <time.h>

}BigInt, *BigPtr; typedef struct BigInt POLY [1]; void poly_null (POLY p); void poly_copy (POLY p1, POLY p2); void poly_add (POLY p1, POLY p2, POLY p3); BOOLEAN poly_cmp (POLY p1, POLY p2); void in_poly (POLY p); void out_poly (POLY p); ELEMENT interleave_zeros (ELEMENT halfWord); void poly_sqr (POLY p1, POLY p2); void poly_leftShift (POLY p); void poly_rightShift (POLY p); void poly_mult (POLY p1, POLY p2, POLY p3); void poly_reduction (POLY p); BOOLEAN cond_polyAux (int i, POLY p); BOOLEAN isOne (POLY p); BOOLEAN cond_poly(POLY u, POLY v); BOOLEAN compareDegree (POLY u, POLY v); void poly_inverse (POLY p, POLY inv); void poly_div (POLY p1, POLY p2, POLY p3); void poly_random (POLY p);

typedef enum {false, true} BOOLEAN; //definition of type boolean #define WORDSIZE 32 // word size #define NUMBITS 163 // number of bits of // each polynomial in the field #define NUMWORD (NUMBITS/WORDSIZE) // maximum index of machine words // to represent NUMBITS #define MAXLONG (NUMWORD+1) #define DOUBLESIZE (2*NUMWORD + 1) //number //of machine words that holds the result //of a multiplication of polynomials #define HALFSIZE (WORDSIZE/2) // half the bits in a machine word #define INTMAX (4*MAXLONG-1) //largest integer into //a large integer array

A.2

Aritmtica no Corpo Finito Arquivo d_2163.c


int i; for(i = 0; i < DOUBLESIZE; i++) p->pol[i] = 0x00; }

#include "ffld_2^163.h" POLY poly_irred = {0xC9, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}; /*irreducible polynomial: x^163 + x^7 +x^6 + x^3 + 1 */ POLY fieldSqrt = {0xDB6DB6B0, 0xB6DB6DB6, 0x2492DB6D, 0x49249249, 0x92492492, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}; /*square root in the field 2^163: sqrt(x)*/

/* poly_copy: copy p1 to p2 * INPUT: p1, p2 * OUTPUT: p2= p1 */ void poly_copy (POLY p1, POLY p2){ int i; for (i = 0; i < DOUBLESIZE; i++) p2->pol[i] = p1->pol[i]; }

/* poly_null: zeroes a polynomial * INPUT: p * OUTPUT: p identically null */ void poly_null (POLY p){

/* poly_add: add p1 and p2 and puts the * result in p3. In a binary field, * addition of two polynomials is * just a XOR operation

15

* INPUT: p1, p2, p3 * OUTPUT: p3 = p1 + p2 */ void poly_add(POLY p1,POLY p2,POLY p3){ int i; for(i=0;i<DOUBLESIZE; i++) p3->pol[i]=p1->pol[i]^p2->pol[i]; }

/* poly_cmp: compare two polynomials * INPUT: p1, p2 * OUTPUT: true, if p1 = p2 * false, otherwise */ BOOLEAN poly_cmp (POLY p1, POLY p2){ int i; for(i = 0; i < DOUBLESIZE; i++) if((p1->pol[i]) != (p2->pol[i])) return false; return true; }

int k = 0; for (i = 0; i < DOUBLESIZE; i++){ mask = 0x01; for(j = 0; j < WORDSIZE; j++){ if(p->pol[i] & mask) printf(" x^%d ", k); k++; mask = mask << 1; } } printf("\n"); //end of line }

/* in_poly: input a big int in hexa * INPUT: coeficients of p in * hexadecimal * OUTPUT: p */ void in_poly (POLY p){ int i; for(i = 0; i < DOUBLESIZE; i++) //reads in hexadecimal scanf("%x", & (p->pol[i])); }

/* interleave_zeros: interleaves zeros * among the coefficients a polynomial * INPUT: half word = * a_15, a_14,...,a_1,a_0 * OUTPUT: word = * 0,a_15,0,a_14,...,0,a_1,0,a_0 */ ELEMENT interleave_zeros (ELEMENT halfWord){ ELEMENT newWord = 0x00; unsigned long aux; unsigned long mask1, mask2; int i; mask1 = mask2 = 0x01; for(i = 0; i < (WORDSIZE/2); i++){ aux = (halfWord) & mask1; if (aux) newWord = newWord | mask2; mask1 = mask1 << 1; mask2 = mask2 << 2; } return newWord; }

/* out_poly: output a big int * Convert groups of four bits in a * character ascii-hexadecimal * INPUT: p * OUTPUT: coeficients of p in * haxadecimal */ void out_poly (POLY p){ unsigned int res; unsigned int mask; int i, j; char vet[(WORDSIZE/4)*DOUBLESIZE+1]; char binascii []= {"0123456789ABCDEF"}; int k = (WORDSIZE/4)*DOUBLESIZE -1; vet[k + 1] = \0; for (i = 0; i < DOUBLESIZE ; i++){ mask = 0x0F; for(j = 0; j < WORDSIZE/4; j++){ // filter four bits res = p->pol[i] & mask; //four bits between 0 and F res = res >> 4*j; vet [k] = binascii[res]; k--; //get the next four bits mask = mask << 4; } } printf("0x%s\n", vet); }

/* poly_sqr: squares a polynomial * Since sqaring a binary * polynomial is a linear operation, * its much faster than multipying * two polynomials * INPUT: p1 * OUTPUT: p2 = p1^2 */ void poly_sqr (POLY p1, POLY p2){ int i; for(i = 0; i < MAXLONG; i++){ p2->pol[2*i] = interleave_zeros (p1->pol[i]); //prepare to interleave with zeros //the first half of word p2->pol[2*i+1] = interleave_zeros ((p1->pol[i]) >> (WORDSIZE/2)); //prepare to interleave with zeros //the other half of word } }

/* out_poly: output a big as a * polynomial. Each nonzero bit is * assigned to a power of x * INPUT: p * OUTPUT: p in polynomial * representation */ void out_poly2 (POLY p){ unsigned int mask; int i, j;

/* poly_leftShift: shifts the * polynomial in one bit to left * INPUT: p=a_31,a_30,...,a_1,a_0 * OUTPUT: p=a_30,a_29,...,a_0, 0 */ void poly_leftShift (POLY p){ int i; BOOLEAN cond = false; for(i = MAXLONG; i >= 0; i--){ //verifies if last bit of word is 1 cond = p->pol[i] & 0x80000000; if(cond){ //if the last bit of word is 1, it goes //to the first bit of next word p->pol[i+1]=p->pol[i+1]|0x01; cond = false; }

16

p->pol[i] = (p->pol[i]) << 1; } }

(t << 4)^(t << 3)^ t ^(t >> 3); p->pol[i - 4] = (p->pol[i - 4])^ (t >> 28)^(t >>29); } t = (p->pol[5]) >> 3; p->pol[0] = (p->pol[0])^(t << 7)^ (t << 6)^(t << 3)^t; p->pol[1]=(p->pol[1])^(t>>25)^(t>>26); p->pol[5] = (p->pol[5]) & 0x07; for(i = 6; i < DOUBLESIZE; i++) p->pol[i]= 0x00; }

/* poly_rightShift: shifts the * polynomial in one bit to right * INPUT: p=a_31,a_30,...,a_1,a_0 * OUTPUT:p=0, a_31,..., a_2, a_1 */ void poly_rightShift (POLY p){ int i; BOOLEAN cond; for (i = 0; i <= MAXLONG; i++){ //verifies if first bit of word is 1 cond = p->pol[i] & 0x01; p->pol[i] = p->pol[i] >> 1; //the first bit goes to previous word if(cond && i){ p->pol[i-1] = (p->pol[i-1]) | 0x80000000; cond = false; } } }

/* poly_addEspecial: especial addition of * a polynomial and a truncated polynomial * INPUT: aux (polynomial) * OUTPUT: aux prepared to sum * with p3{j} (algorithm 2.34, * Guide to elliptic...) */ void poly_addEspecial (POLY p2, POLY p3, int j){ int i; for(i=0; i<=(MAXLONG+1); i++) p3->pol[i+j] = p3->pol[i+j]^p2->pol[i]; }

/* cond_polyAux: verifies if * polynomials are different * INPUT: u, v * OUTPUT: true if u!=1 and * false otherwise */ BOOLEAN cond_polyAux (int i, BOOLEAN condition = false; while (i && (!condition)){ if(p->pol[i]) condition = true; i--; } return condition; }

two of 1 v!=1

POLY p){

/* poly_mult: polynomial multiplication * Right-to-left comb method * INPUT: p1 and p2 * OUTPUT: p3 = p1*p2 */ void poly_mult(POLY p1,POLY p2,POLY p3){ POLY aux; poly_null(p3); unsigned long mask = 0x01; int j, k; for (k = 0; k < WORDSIZE; k++){ for(j = 0; j < MAXLONG; j++) //if the kth bit is 1 if(p1->pol[j] & mask){ poly_addEspecial(p2,p3,j); } if(k != (WORDSIZE -1)) poly_leftShift(p2); mask = mask << 1; } }

/* isOne: verify is p=1 * Used in reduction and division * INPUT: p * OUTPUT:true if p=1.False,otherwise */ BOOLEAN isOne (POLY p){ BOOLEAN cond; cond = cond_polyAux(MAXLONG, p); if(cond) return false; else if(p->pol[0] == 1) return true; else return false; }

/* cond_poly: verifies if two * polynomials are different of 1 * INPUT: u, v * OUTPUT: true if u!=1 and v!=1 * false otherwise */ BOOLEAN cond_poly(POLY u, POLY v){ BOOLEAN cond = false; cond = cond_polyAux(MAXLONG-1 u); if(!cond) cond = cond_polyAux(MAXLONG-1,v); if(!cond) cond=(u->pol[0]!=1)&&(v->pol[0]!=1); return cond; }

/* poly_reduction: fast reduction * modulo f(z)=z^163+x^7+x^6+x^3+1 * proposed by J.Lopez and R. Dahab * INPUT: p * OUTPUT: p = p mod f(z) */ void poly_reduction (POLY p){ int i; unsigned int t; for (i= 10; i >= 6; i--){ //reduce p[i]z^{32i} modulo f(z) t = p->pol[i]; p->pol[i-6]=(p->pol[i-6])^(t<<29); p->pol[i - 5] = (p->pol[i - 5])^

/* compareDegrees: compare the * degrees of two polynomials * INPUT: u, v * OUTPUT: true if deg(u) > deg (v) * false otherwise */ BOOLEAN compareDegree(POLY u,POLY v){ int i = MAXLONG; while (i >= 0){ if(u->pol[i] > v->pol[i]) return true; else

17

if(v->pol[i] > u->pol[i]) return false; i--; } //u and v are identical return false; }

poly_add(g1,poly_irred,g1); poly_rightShift(g1); } while(!(v->pol[0] & 0x01)){ //z divides v poly_rightShift(v); // z doesnt divide g2 if(g2->pol[0] & 0x01) poly_add(g2,poly_irred,g2); poly_rightShift(g2); } if(compareDegree(u, v)){ poly_add(u, v, u); poly_add(g1,g2, g1); } else{ poly_add(u, v, v); poly_add(g1,g2, g2); } } if(isOne(u)) poly_copy(g1, p3); else poly_copy(g2, p3); }

/* poly_inverse: binary algorithm * for inversion in F_{2^m} * INPUT: A nonzero binary polynomial * p of degree at most m-1 * OUTPUT: p = p^{-1} mod f(z) */ void poly_inverse (POLY p, POLY inv){ POLY u, v, g2 , g1 = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; poly_copy(p, u); poly_copy(poly_irred, v); poly_null(g2); while(cond_poly (u, v)){ //z divides u while(!((u->pol[0]) & 0x01)){ poly_rightShift(u); // z doesnt divide g1 if((g1->pol[0]) & 0x01) poly_add(g1,poly_irred,g1); poly_rightShift(g1); } while(!((v->pol[0]) & 0x01)){ //z divides v poly_rightShift(v); // z doesnt divide g2 if((g2->pol[0]) & 0x01) poly_add(g2,poly_irred,g2); poly_rightShift(g2); } if(compareDegree(u, v)){ poly_add(u, v, u); poly_add(g1,g2, g1); } else{ poly_add(u, v, v); poly_add(g1,g2, g2); } } if(isOne(u)) poly_copy(g1, inv); else poly_copy(g2, inv); }

/* poly_div: binary division of * two polynomials * INPUT: p1, p2, p3 * OUTPUT: p3 = p2/p1 */ void poly_div(POLY p1,POLY p2,POLY p3){ POLY u, v, g2 , g1; poly_copy(p1, u); poly_copy(poly_irred, v); poly_copy(p2, g1); poly_null(g2); while(cond_poly (u, v)){ while(!(u->pol[0] & 0x01)){ //z divides u poly_rightShift(u); if(g1->pol[0] & 0x01) // z doesnt divide g1

/* poly_sqrt: calculate the square * root of a polynomial * INPUT: p * OUTPUT: sqrt(p) */ void poly_sqrt (POLY p){ int i, j, k = -1; POLY even, odd, mult; poly_null(even); poly_null(odd); unsigned long mask1, mask2; for(i = 0; i < MAXLONG; i++){ mask1 = 0x01; if(i % 2 == 0){ k++; mask2 = 0x01; } for(j = 0; j < WORDSIZE/2; j++){ if((p->pol[i]) & mask1) even->pol[k] = even->pol[k] | mask2; mask1 = mask1 << 1; // goes to an odd coefficient if((p->pol[i]) & mask1) odd->pol[k] = odd->pol[k] | mask2; mask2 = mask2 << 1; mask1 = mask1 << 1; } } poly_mult(fieldSqrt, odd, mult); //sqrt(p) = even + sqrt(x)*odd poly_add(even, mult, p); poly_reduction(p); }

void poly_random (POLY p){ int i; poly_null(p); for(i = 0; i < MAXLONG -1; i++) p->pol[i] = rand(); p->pol[i]=rand()%8; //polynomial with maximum degree equal to 162 }

18

A.3

Operaes sobre a Curva Arquivo ecc_arith.h


void quadratic_eq(POLY beta,POLY H); void point_copy(EC_POINT P,EC_POINT Q); BOOLEAN point_valid(EC_POINT P); void point_out(EC_POINT P); void point_random(EC_POINT P); void point_neg (EC_POINT P); BOOLEAN isNegative(POLY yP,POLY yQ); void point_add(EC_POINT P, EC_POINT Q, EC_POINT R); void point_double(EC_POINT P,EC_POINT Q); void point_mult(EC_POINT P, EC_POINT Q, POLY k, int t);

/* ecc aritm.h*/ #include "ffld_2^163.h" #define ORDER 163 /* point in affine coordinates */ typedef struct POINT { BOOLEAN infinity; POLY x, y; // coordinates }POINT, *POINT_ptr; typedef struct POINT EC_POINT[1]; //elliptic curve point

A.4

Operaes sobre a Curva Arquivo ecc_arith.c


poly_null(firstMember); poly_sqr(P->y, firstMember); poly_reduction(firstMember); poly_add(firstMember, P->y, firstMember); poly_null(secondMember); poly_sqr(P->x, secondMember); poly_reduction(secondMember); poly_null(x_aux); poly_null(temp); poly_copy(P->x, x_aux); poly_mult(secondMember, x_aux, temp); poly_reduction(temp); poly_add(temp, P->x, secondMember); if(poly_cmp(firstMember,secondMember)) return true; else return false; }

/* ecc_arith.c * aritmetic over the curve * y^2 + y = x^3 + x */ #include "ecc_arith.h"

/* quadratic_eq: * solves x^2+x=beta->x=halfTrace * INPUT: polynomial beta * OUTPUT: polynomial H (solution of * quadratic equation) */ void quadratic_eq(POLY beta,POLY H){ POLY aux; int i; poly_copy(beta, H); poly_null(aux); for (i = 1; i<=(ORDER-1)/2; i++){ poly_sqr(H, aux); poly_reduction(aux); poly_null(H); poly_sqr(aux, H); poly_reduction(H); poly_add(H, beta, H); } }

/* point_copy: * makes copy of a point * INPUT: point P * OUTPUT: point Q, with Q = P */ void point_copy(EC_POINT P,EC_POINT Q){ Q->infinity = P->infinity; poly_copy(P->x, Q->x); poly_copy(P->y, Q->y); }

/*point_out: prints "point at infinity", * if its the case, or prints the * coordinates of point * INPUT: point P * OUTPUT: "point at infinity" or * coordinates x and y in hexadecimal */ void point_out(EC_POINT P){ if(P->infinity) printf("\nPoint at infinity\n"); else{ printf("x:\n"); out_poly(P->x); printf("y:\n"); out_poly(P->y); } }

/* point_valid: Verifies if a point * belongs to the elliptc curve * y^2 + y = x^3 + x * INPUT:point P (affine coordinates) * OUTPUT:true if the point is valid * false, otherwise */ BOOLEAN point_valid(EC_POINT P){ POLY firstMember, secondMember, x_aux, temp; if(P->infinity) return true;

/* point_random: * generates a random point that * belongs to the elliptic curve * INPUT: point P (invalid) * OUTPUT: point P (valid) */ void point_random(EC_POINT P){ POLY x_aux, secondMember, temp; P->infinity = false; do{ poly_random(P->x); poly_null(secondMember); poly_sqr(P->x, secondMember);

19

poly_reduction(secondMember); poly_null(x_aux); poly_null(temp); poly_copy(P->x, x_aux); poly_mult(secondMember, x_aux, temp); poly_reduction(temp);//x^3 mod f(x) poly_copy(temp, secondMember); poly_add(secondMember, P->x, secondMember); //x^3 + x quadratic_eq(secondMember,P->y); }while(!(point_valid(P))); //not all solutions of quadratic equation //satisfies the equation of curve }

poly_sqr(lambda, R->x); poly_reduction(R->x); poly_add(R->x, P->x, R->x); poly_add(R->x, Q->x, R->x); poly_null(aux); poly_add(R->x, P->x, aux); poly_mult(lambda, aux, R->y); poly_reduction(R->y); poly_add(R->y, P->y, R->y); R->y->pol[0]=R->y->pol[0]^0x01; } }

/* point_neg: negates a point. * If P = (x, y), -P = (x, y + 1) * INPUT: point P * OUTPUT: point -P (valid) */ void point_neg (EC_POINT P){ P->y->pol[0]=P->y->pol[0]^0x01; }

/* isNegative: Verifies if a point P is * negative of Q. Used in point_add * INPUT: points P and Q * OUTPUT:true,if Q=-P. False,otherwise */ BOOLEAN isNegative(POLY yP,POLY yQ){ int i; for(i = MAXLONG -1; i > 0; i--) if((yP->pol[i]) != (yQ->pol[i])) return false; if(((yP->pol[i])^(yQ->pol[i]))==0x01) return true; else return false; }

/* point_double: point doubling * INPUT: point P = (x1, y1) * OUTPUT: Q = 2P, Q = (x3, y3) */ void point_double(EC_POINT P, EC_POINT Q){ POLY lambda, aux; if(P->infinity) Q->infinity = true; else{ Q->infinity = false; poly_null(lambda); poly_sqr(P->x, lambda);//x^2 poly_reduction (lambda); lambda->pol[0]=lambda->pol[0]^0x01; poly_sqr(lambda, Q->x);//lambda^2 poly_reduction(Q->x); poly_null(aux); poly_add(P->x, Q->x, aux);//x1 + x3 poly_mult(lambda, aux, Q->y); poly_reduction(Q->y); poly_add(Q->y, P->y, Q->y); Q->y->pol[0]=Q->y->pol[0]^0x01; } }

/* point_add: * performs addition of points P and * Q, since P is different of +- Q * INPUT: P = (x1, y1), Q = (x2, y2) * OUTPUT: R = P + Q, R = (x3, y3) */ void point_add(EC_POINT P, EC_POINT Q, EC_POINT R){ POLY lambda,lambdaX,lambdaY,aux; if(P->infinity) point_copy(Q, R); else if(Q->infinity) point_copy(P, R); else if(isNegative(P->y, Q->y)) R->infinity = true; else if(poly_cmp(P->x, Q->x)) point_double(P, R); else{ R->infinity = false; poly_add(P->x, Q->x, lambdaX); poly_add(P->y, Q->y, lambdaY); poly_null(lambda); poly_div(lambdaX,lambdaY,lambda);

/* point_mult: point multiplication * INPUT: point P, point Q, polynomial * k, integer t, where t = length of * polynomial k * OUTPUT: Q = k*P */ void point_mult(EC_POINT P, EC_POINT Q, POLY k, int t){ EC_POINT aux; unsigned int mask; int i, j, limit; Q->infinity = true; for(i = 0; i <= t/WORDSIZE; i++){ mask = 0x01; limit = (i != t/WORDSIZE)? WORDSIZE : (t % WORDSIZE); for(j = 0; j < limit; j++){ if(k->pol[i] & mask){ point_add(Q, P, aux); point_copy(aux, Q); } point_double(P, aux); point_copy(aux, P); mask = mask << 1; } } }

20

Você também pode gostar