Giter Club home page Giter Club logo

isakruas / ecutils Goto Github PK

View Code? Open in Web Editor NEW
2.0 0.0 2.0 85 KB

Python library for Elliptic Curve Cryptography: key exchanges (Diffie-Hellman, Massey-Omura), ECDSA signatures, and Koblitz encoding. Suitable for crypto education and secure systems.

Home Page: https://ecutils.readthedocs.io/en/stable/

License: MIT License

Python 100.00%
cryptographic-algorithms digital-signatures ecdsa elliptic-curve-cryptography public-key-cryptography python-cryptography secure-communication diffie-hellman-key-exchange ecc-based-protocols elliptic-curve-operations

ecutils's Introduction

Isak Paulo de Andrade Ruas

Entusiasta das Tecnologias da Informação e Comunicação, buscando sempre se aperfeiçoar sobre as mais variadas tecnologias e métodos existentes. Apaixonado por astrofotografias, matemática e desenvolvimento de softwares. Tem interesse em frameworks como Django, FastAPI, Drogon e Starlette; e linguagens de programação com Python, C++ e C. Criador dos módulos Python: ripda - mini framework para desenvolvimento de aplicações baseadas em blockchain - e ecutils - biblioteca para operações matemáticas sobre curvas elípticas.

Identificação

Nome: Isak Paulo de Andrade Ruas

Nome em citações bibliográficas:

  • RUAS, I. P. A.;
  • PAULO DE ANDRADE RUAS, ISAK;
  • RUAS, ISAK PAULO DE ANDRADE

Formação acadêmica/titulação

  • (2016 - Atual) Graduação em andamento em Licenciatura Matemática
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil.
    Disciplinas:

    • Período 1
      • Geometria Euclidiana Plana (Carga Horária: 120h)
      • Prática Pedagógica I: Introdução à Prática Docente (Carga Horária: 40h)
      • Introdução à Informática (Carga Horária: 40h)
      • Fundamentos de Matemática Elementar I (Carga Horária: 120h)
      • Português Instrumental I (Carga Horária: 40h)
      • Métodos e Técnicas de Pesquisa (Carga Horária: 40h)
    • Período 2
      • Geometria Analítica I (Carga Horária: 80h)
      • Fundamentos de Matemática Elementar II (Carga Horária: 120h)
      • Geometria Espacial (Carga Horária: 80h)
      • Português Instrumental II (Carga Horária: 40h)
      • Fundamentos Filosóficos da Educação (Carga Horária: 40h)
      • Prática Pedagógica II: Ensino de Ciências (Carga Horária: 40h)
    • Período 3
      • Geometria Analítica II (Carga Horária: 80h)
      • Cálculo Diferencial e Integral I (Carga Horária: 120h)
      • Álgebra Linear I (Carga Horária: 80h)
      • Psicologia do Desenvolvimento e Aprendizagem (Carga Horária: 80h)
      • Prática Pedagógica III: Planejamento e Prática (Carga Horária: 40h)
    • Período 4
      • Cálculo Diferencial e Integral II (Carga Horária: 80h)
      • Álgebra Linear II (Carga Horária: 80h)
      • Física I (Carga Horária: 80h)
      • Construções Geométricas (Carga Horária: 40h)
      • Didática I (Carga Horária: 40h)
      • Educação, Sociedade e Trabalho (Carga Horária: 40h)
      • Prática Pedagógica IV: Educação Matemática (Carga Horária: 40h)
    • Período 5
      • Didática II (Carga Horária: 40h)
      • Cálculo Diferencial e Integral III (Carga Horária: 80h)
      • Introdução à Teoria Aritmética dos Números (Carga Horária: 80h)
      • Física II (Carga Horária: 40h)
      • Estatística I (Carga Horária: 40h)
      • Organização e Gestão Pedagógica (Carga Horária: 40h)
      • Prática Pedagógica V: Lem I - Laboratório de Educação Matemática I (Carga Horária: 40h)
      • Estágio Supervisionado I (Carga Horária: 120h)
    • Período 6
      • Estatística II (Carga Horária: 80h)
      • Equações Diferenciais Ordinárias (Carga Horária: 40h)
      • Educação Para a Diversidade (Carga Horária: 40h)
      • Produção e Gestão do Conhecimento (Carga Horária: 40h)
      • Produção e Gestão do Conhecimento (Carga Horária: 40h)
      • Prática Pedagógica Vi: L. E. M. II - Laboratório de Educação Matemática II (Carga Horária: 40h)
    • Período 7
      • Cálculo Numérico (Carga Horária: 80h)
      • Educação Profissional (Carga Horária: 80h)
      • Prática Pedagógica VII: LEM III - Laboratório de Educação Matemática III (Carga Horária: 40h)
      • Trabalho de Conclusão de Curso - TCC I (Carga Horária: 40h)
    • Período 8
      • Matemática Financeira (Carga Horária: 40h)
      • Funções de uma Variável Complexa (Carga Horária: 80h)
      • Prática Pedagógica VIII: LEM IV - Laboratório de Educação Matemática IV (Carga Horária: 40h)
  • (2019 - 2019)
    Aperfeiçoamento em Inglês Básico (Carga Horária: 200h).
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil.

  • (2019 - 2019)
    Aperfeiçoamento em Cálculo de Funções e Geometria Vetorial (Carga Horária: 180h).
    Faculdades Metropolitanas de São Paulo, FAMESP, Brasil.

  • (2018 - 2018)
    Aperfeiçoamento em Fundamentos Teóricos do Pensamento Matemático (Carga Horária: 180h).
    Faculdades Metropolitanas de São Paulo, FAMESP, Brasil.

  • (2018 - 2018)
    Aperfeiçoamento em Robótica para Jovens (Carga Horária: 180h).
    Faculdades Metropolitanas de São Paulo, FAMESP, Brasil.

Formação Complementar

  • (2022 - 2022)
    SQL Alckemy: Essencial (Carga Horária: 15h).
    Geek University, Brasil.

  • (2021 - 2021)
    Docker Essencial para o Desenvolvedor (Carga Horária: 8.5h).
    Geek University, Brasil.

  • (2021 - 2021)
    Programação Concorrente e Assíncrona com Python (Carga Horária: 8h).
    Geek University, Brasil.

  • (2021 - 2021)
    Padrões de Projeto (Design Patterns) com Python (Carga Horária: 11h).
    Geek University, Brasil.

  • (2020 - 2021)
    Programação em Python do básico ao avançado (Carga Horária: 64h).
    Geek University, Brasil.

  • (2020 - 2021)
    Programação Web com Python e Django Framework: Essencial (Carga Horária: 35.5h).
    Geek University, Brasil.

  • (2020 - 2020)
    Crie APIs REST com Python e Django REST Framework: Essencial (Carga Horária: 9.5h).
    Geek University, Brasil.

  • (2019 - 2019)
    Matemática aplicada a programação (Carga Horária: 13h).
    Sociedade para Promoção da Excelência do Software Brasileiro, SOFTEX, Brasil.

  • (2019 - 2019)
    Resolvendo equações diferenciais usando o Wmáxima (Carga Horária: 4h).
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil.

  • (2016 - 2016)
    Geometria Esférica por meio de materiais manipuláveis (Carga Horária: 20h).
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil.

Atuação Profissional

  • (2021 - Atual)
    JobConvo: Software de Recrutamento e Seleção (Vínculo: Empregado, Enquadramento Funcional: Analista de Redes e de Comunicação de Dados: 40h).
    Outras informações:

    Responsável pelo desenvolvimento e manutenção de aplicação Python/Django.

  • (2019 - 2019)
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil (Vínculo: Bolsista, Enquadramento Funcional: Monitor, Carga horária semanal: 15h).
    Outras informações:

    Conforme o edital nº. 43, de 11 de março de 2019 do Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais (IFNMG) Campus Januária, atuei como Monitor da disciplina de Cálculo Diferencial e Integral I nos cursos de Bacharelado em Engenharia Agrícola e Ambiental, Bacharelado em Engenharia Agronômica, Bacharelado em Engenharia Civil e Bacharelado em Sistemas de Informação sob orientação da Profa. Me. Celimar Reijane Alves Damasceno Paiva.

  • (2019 - 2019)
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil (Vínculo: Bolsista, Enquadramento Funcional: Monitor, Carga horária semanal: 15h).
    Outras informações:

    Conforme o edital nº. 149, de 14 de agosto de 2019 do Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais (IFNMG) Campus Januária, atuei como Monitor da disciplina de Cálculo Diferencial e Integral II nos cursos de Bacharelado em Engenharia Agrícola e Ambiental, Bacharelado em Engenharia Agronômica, Bacharelado em Engenharia Civil e Bacharelado em Sistemas de Informação sob orientação da Profa. Me. Celimar Reijane Alves Damasceno Paiva.

  • (2018 - 2019)
    Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais, IFNMG, Brasil (Vínculo: Bolsista, Enquadramento Funcional: Monitor Voluntário, Carga horária semanal: 8h).
    Outras informações:

    Conforme o edital nº. 141, de 24 de agosto de 2018 do Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais (IFNMG) Campus Januária, atuei como Monitor da disciplina de Cálculo Diferencial e Integral I nos cursos de Bacharelado em Engenharia Agrícola e Ambiental, Bacharelado em Engenharia Agronômica, Bacharelado em Engenharia Civil e Bacharelado em Sistemas de Informação sob orientação da Profa. Me. Celimar Reijane Alves Damasceno Paiva.

  • (2016 - 2016)
    Escola Estadual Olegário Maciel, EEOM, Brasil (Vínculo: Professor Visitante, Enquadramento Funcional: Monitor,, Carga horária semanal: 6h).
    Outras informações:

    Fui professor voluntário responsável pela organização, execução, coordenação e pelo acompanhamento das atividades executadas na oficina de Comunicação, Uso de Mídias, Cultura Digital e Tecnológica do programa Escola Aberta Minas Gerais instituído pelo Ministério da Educação na forma definida na Lei número 9.608, de 1998.

Projetos de pesquisa

  • (2018 - 2019)
    Estudo investigativo sobre o ensino dos produtos notáveis de binômios através do triângulo aritmético: elaboração de um jogo didático pedagógico
    Integrantes:

    • Gustavo Pereira Gomes - Coordenador
    • Isak Paulo de Andrade Ruas - Integrante
    • Tamires Ribeiro dos Santos - Integrante

    Descrição: Os Produtos Notáveis cumprem um papel importantíssimo do desenvolvimento de expressões matemáticas, as suas características nos permitem simplificar expressões algébricas e reduzi-las de tal forma que facilite a sua resolução. Assim, conseguimos resolver certos problemas algébricos de maneira simples e prática reduzindo o tempo que seria gasto para resolvê-las. Estes produtos são estudados nos diversos níveis de ensino, desde o ensino fundamental até o ensino superior, sendo uma das primeiras generalizações matemáticas estudadas em sala de aula, podendo provocar dúvidas devido ao tipo de raciocínio trabalhado. Por este motivo, este conteúdo deve receber um tratamento especial em relação a abordagem de ensino para auxiliar o desenvolvimento do raciocínio abstrato. Introduzido frequentemente por meio da abordagem geométrica, este conteúdo é trabalhado no oitavo ano do ensino fundamental. Porém, segundo a Base Nacional Comum Curricular (BNCC), a orientação é que ele seja abordado conjuntamente com fatoração de expressões algébricas no nono ano desse mesmo ciclo de ensino, para auxiliar no desenvolvimento da capacidade de resolver e elaborar problemas que possam ser representados por equações polinomiais. Tanto por meio da abordagem geométrica como por meio da abordagem algébrica, os alunos lidam com situações abstratas de manipulação de variáveis que podem ocasionar dúvidas em relação as características dos produtos notáveis e na sua utilização. Assim, torna-se necessário o desenvolvimento de alternativas didáticas por parte dos educadores que possibilite aos alunos ferramentas para superar as dificuldades encontradas. O Triângulo Aritmético possui diversas propriedades em sua estrutura e uma delas permite relacionar as suas linhas com o desenvolvimento de um produto notável de dois termos, tanto da soma como da diferença, podendo assim, ser utilizado como uma ferramenta auxiliar no estudo deste conteúdo. Ao mesmo tempo, o Triângulo Aritmético proporciona de maneira simples o desenvolvimento de produtos notáveis superiores aos cúbicos, mostrando assim, uma alternativa didática viável para o ensino deste conteúdo. Além disso, como o lúdico possibilita uma aprendizagem mais significativa e espontânea aos alunos, a elaboração de um jogo didático sobre dos produtos notáveis através da estrutura do triângulo aritmético torna-se uma alternativa viável e pertinente para a abordagem deste conteúdo. Partindo-nos do princípio de que os alunos devem estar no centro do processo de ensino e aprendizagem, cabe ao educador elaborar formas alternativas que auxiliem a aprendizagem dos conteúdos, em particular, o ensino dos Produtos Notáveis, proposta norteadora do desenvolvimento deste projeto. Sendo assim, este projeto tem como objetivo elaborar propostas pedagógicas no ensino de produtos notáveis, aplicar o material elaborado em sala de aula e analisar os resultados obtidos.

  • (2018 - 2018)
    O uso de recursos computacionais no ensino de matemática nas escolas públicas do município de Januária (MG) (Financiador(es): Instituto Federal de Educação Ciência e Tecnologia do Norte de Minas Gerais - Bolsa)
    Integrantes:

    • Josué Antunes de Macêdo - Coordenador
    • Isak Paulo de Andrade Ruas - Integrante
    • Ednaldo Liberato de Oliveira - Integrante
    • Waldomiro Rodrigues Borba Junior - Integrante
    • Emanuel Arrudas de Macêdo - Integrante
    • Ítalo Andrew Rodrigues Santos - Integrante.

    Descrição: É notório que se vive em uma sociedade repleta de constante mudanças. Quase tudo tende a se desenvolver rapidamente, exceto o dia a dia da sala de aula, em que várias ações de ensino continuam sendo praticadas tais como as do século passado. Os recursos didáticos são na maioria das vezes desatualizados. Os professores convivem com alunos nativos digitais, que estão diariamente em contato com as tecnologias de informação e comunicação, devendo acompanhar essa evolução. O uso dos recursos computacionais é um importante elo de ligação, entre professores e alunos, podendo contribuir no processo de ensino e aprendizagem. Assim, o objetivo deste projeto de pesquisa é analisar o uso dos Recursos Computacionais no Ensino de Matemática nas escolas públicas do município de Januária (MG). Nesse sentido, buscar-se-á levantar quais são os desafios e as experiências realizadas ou a realizar como forma de contribuir no processo de ensino e aprendizagem, facilitando assim o trabalho do professor e promovendo uma aprendizagem significativa com a presença das tecnologias computacionais. Inicialmente será realizada uma pesquisa bibliográfica, contemplando a evolução histórica da informática aplicada à educação no Brasil. Posteriormente, realizar-se-á uma pesquisa de campo, por meio de visitas às escolas, buscando identificar aquelas que possuem laboratórios de informática instalados, seguido da aplicação de questionários e entrevistas aos professores que fazem uso dos laboratórios de informática dessas escolas. Espera-se assim, identificar quais os limites e possibilidades do uso dos recursos computacionais no Ensino de Matemática, contribuindo para a melhoria do processo de ensino e aprendizagem dessa área do conhecimento.

Projetos de extensão

  • (2020 - 2020)
    Videoaulas de Matemática: Análise Real e Teoria dos Números
    Integrantes:
    • Gustavo Pereira Gomes - Coordenador
    • Isak Paulo de Andrade Ruas - Integrante
    • João Paulo Antunes Carvalho - Integrante
    • Gabriel Márcio Gonçalves - Integrante
    • Gentil José de Oliveira Neto - Integrante
    • Iago Marcelino de oliveira - Integrante.

    Descrição: A inclusão dos recursos tecnológicos está cada vez mais presente no ambiente escolar das diversas modalidades de ensino. Dentre estes, um recurso bastante utilizado pelos estudantes é a vídeoaula, encontradas em sua maioria no site de compartilhamento de vídeos YouTube. Nesta plataforma, qualquer pessoa pode postar conteúdo e os professores estão utilizando-o cada vez mais com a finalidade de renovar a prática pedagógica para aproximar o ensino do aluno moderno. Deste modo, o presente projeto tem como objetivo principal alimentar o site https://vid.mat.br/ e o canal do YouTube Vid.Mat com resoluções de exercícios das disciplinas de Análise Real e Teoria dos Números no formato de vídeoaulas elaboradas pelos participantes. Além disso, serão disponibilizados materiais de apoio voltados ao ensino da matemática e a duração do projeto será de um ano, sendo que todo o orçamento necessário para a execução deste será por conta da equipe técnica. Portanto, espera-se que o material disponibilizado contribua para a formação dos alunos além de dar suporte ao professor que pretende utilizar este novo recurso tecnológico bastante popular entre os alunos da atualidade.

Projetos de desenvolvimento e/ou inovação

  • (2020 - 2020)
    Desenvolvimento de um sistema hipermídia para elaboração de avaliações de matemática (Financiador(es): Conselho Nacional de Desenvolvimento Científico e Tecnológico - Bolsa)
    Integrantes:

    • Josué Antunes de Macêdo - Coordenador
    • Isak Paulo de Andrade Ruas - Integrante

    Descrição: A internet revolucionou a maneira como se transmite informações e comunicações, possibilita uma maior interatividade entre as pessoas e este aspecto pode ser explorado em processos educacionais. Umas das possíveis maneiras de se utilizar a internet como ferramenta facilitadora em processos educacionais é através da elaboração de sites especializados. Existe uma variedade deles destinados a facilitarem a aprendizagem do aluno, seja com conteúdos em vídeo, texto ou animações. Nota-se porém, que é pouco explorado a existência de sites especializados com o objetivo de auxiliar professores de matemática a elaborarem seus conteúdos didáticos. Não se percebe na rede mundial de computadores uma ferramenta gratuita com esta finalidade. Neste sentido, torna-se necessário desenvolver um sistema gratuito, com critérios ergonômicos, através da metodologia da pesquisa designer educacional, que possibilite ao professor de matemática dos anos finais do ensino fundamental e ensino médio a elaborar atividades avaliativas, que seja acessível on-line pela internet. Espera-se assim fornecer aos professores e professoras de matemática dos anos finais do ensino fundamental e ensino médio um sistema gratuito e acessível pela internet, que facilite a elaboração de atividades avaliativas de matemática.

  • (2020 - 2021)
    Desenvolvimento de um aplicativo mobile para elaboração de avaliações de matemática (Financiador(es): Conselho Nacional de Desenvolvimento Científico e Tecnológico - Bolsa)
    Integrantes:

    • Josué Antunes de Macêdo - Coordenador
    • Isak Paulo de Andrade Ruas - Integrante

    Descrição: A internet revolucionou a maneira como se transmite informações e comunicações, possibilita uma maior interatividade entre as pessoas e este aspecto pode ser explorado em processos educacionais. Umas das possíveis maneiras de se utilizar a internet como ferramenta facilitadora em processos educacionais é através da elaboração de sites ou aplicativos web progressivos especializados. Existe uma variedade deles destinados a facilitarem a aprendizagem do aluno, seja com conteúdos em vídeo, texto ou animações. Nota-se, porém, que é pouco explorado a existência de sites ou aplicativos mobiles especializados com o objetivo de auxiliar professores de matemática a elaborarem seus conteúdos didáticos. Não se percebe na rede mundial de computadores uma ferramenta gratuita com esta finalidade. Neste sentido, torna-se necessário desenvolver um aplicativo gratuito, com critérios ergonômicos, através da metodologia da pesquisa designer educacional, que possibilite ao professor de matemática dos anos finais do ensino fundamental e ensino médio a elaborar atividades avaliativas, que seja acessível on-line pela internet através de um aplicativo mobile. Espera-se assim fornecer aos professores de matemática dos anos finais do ensino fundamental e ensino médio um aplicativo gratuito e acessível pela internet, que facilite a elaboração de atividades avaliativas de matemática.

Áreas de atuação

  • Grande área: Ciências Exatas e da Terra / Área: Matemática
  • Grande área: Ciências Exatas e da Terra / Área: Matemática / Subárea: Ensino de Matemática

Prêmios e títulos

Produções

Produção bibliográfica

Artigos completos publicados em periódicos

Capítulos de livros publicados

Resumos expandidos publicados em anais de congressos

Resumos publicados em anais de congressos

Demais tipos de produção técnica

  • MACEDO, E. A. ; RUAS, I. P. A. ; MACEDO, J. A. . CONSTRUINDO UM JOGO PARA O ENSINO DE MATEMÁTICA UTILIZANDO O SCRATCH. 2018. (Curso de curta duração ministrado/Outra).
  • RUAS, I. P. A.; SANTOS, T. R. ; GOMES, G. P. . JOGO TABULEIRO TRIANGULAR E PRODUTOS NOTÁVEIS. 2018. (Curso de curta duração ministrado/Outra).

Eventos

Participação em eventos, congressos, exposições e feiras

  • XI Congresso Nacional de Pesquisa em Educação. DESENVOLVIMENTO DE UM BANCO DE QUESTÕES DE MATEMÁTICA ONLINE. 2020. (Congresso)
  • 32º Colóquio Brasileiro de Matemática. 2019. (Encontro)
  • III Semana da Matemática do IFNMG. PROPOSTA DO USO DA TEORIA ERGONÔMICA NA ELABORAÇÃO DE UM BANCO DE QUESTÕES DE MATEMÁTICA. 2019. (Encontro)
  • VIII Seminário de Iniciação Científica, I Seminário do ProfEPT e VI Prospectar do IFNMG. QUAL A MELHOR POSIÇÃO PARA SE SENTAR NO CINEMA?. 2019. (Seminário)
  • VIII Seminário de Iniciação Científica, I Seminário do ProfEPT e VI Prospectar do IFNMG. UTILIZAÇÃO DO LABORATÓRIO DE INFORMÁTICA NO ENSINO DE MATEMÁTICA NO MUNICÍPIO DE JANUÁRIA (MG). 2019. (Seminário)
  • I Congresso Internacional de Educação: Diversidade, Formação e Saberes Docentes. OS LABORATÓRIOS DE INFORMÁTICA NAS ESCOLAS PÚBLICAS DO MUNICÍPIO DE JANUÁRIA (MG). 2018. (Congresso)
  • II Semana da Matemática do IFNMG. OPERACIONALIDADE DOS LABORATÓRIOS DE INFORMÁTICAS DAS ESCOLAS PÚBLICAS DO MUNICÍPIO DE JANUÁRIA (MG). 2018. (Encontro)
  • II Semana da Matemática do IFNMG. INDISCIPLINA NO AMBIENTE ESCOLAR: PERCEPÇÕES DOS EDUCADORES E EDUCADORAS DE DUAS ESCOLAS PÚBLICAS DO MUNICÍPIO DE JANUÁRIA (MG). 2018. (Encontro)
  • II Semana da Matemática do IFNMG. RELACIONANDO CONCEITOS MATEMÁTICOS AO DESENVOLVIMENTO DE UM JOGO UTILIZANDO A LINGUAGEM DE PROGRAMAÇÃO SCRATCH. 2018. (Encontro)
  • II Semana Integrada de Ensino, Pesquisa e Extensão. UTILIZAÇÃO DO LABORATÓRIO DE INFORMÁTICA, SOFTWARES E/OU APLICATIVOS EDUCACIONAIS NA PRÁTICA DOCENTE DOS PROFESSORES E PROFESSORAS DE MATEMÁTICA DE ONZE ESCOLAS PÚBLICAS DO MUNICÍPIO DE JANUÁRIA (MG). 2018. (Simpósio)
  • VII Seminário de Iniciação Científica do IFNMG, I Seminário da PPGVet e V Prospectar. ANÁLISE DA ABORDAGEM UTILIZADA NOS LIVROS DIDÁTICOS DA REDE PUBLICA PARA O ENSINO DOS PRODUTOS NOTÁVEIS DE BINÔMIOS NO OITAVO ANO DO ENSINO FUNDAMENTAL NA CIDADE DE JANUÁRIA (MG). 2018. (Seminário)
  • XII Fórum de Ensino, Pesquisa, Extensão e Gestão. 2018. (Encontro)

Organização de eventos, congressos, exposições e feiras

  • II Semana da Matemática do IFNMG. 2018. (Outro)

ecutils's People

Contributors

isakruas avatar snyk-bot avatar

Stargazers

 avatar  avatar

ecutils's Issues

Coordenadas Jacobianas ...

Você já considerou usar a Aritmética da Curva Elíptica com as Coordenadas Jacobianas ?

Dê uma olhada:

https://github.com/gtmadureira/cryptography/blob/main/ecc/secp256k1/secp256k1_jacobian.py

Para testar o código, considere executa-lo em modo otimizado, por exemplo:

user@linux:~$ python3 -OO your_python_code.py
"""
§  [ LICENSE ]  ( GNU GPLv3 )  :

SECP256K1 at Jacobian Coordinates  -  Elliptic Curve Cryptography (ECC).
Copyright (C)  2021 - 2023  Gustavo Madureira

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along
with this program. If not, see https://www.gnu.org/licenses/.


§  [ ABOUT ]  :

Elliptic Curve Cryptography (ECC).
Module for asymmetric cryptography with elliptic curve SECP256K1, using
the Jacobian coordinates.

- Used to perform public key generation;
- Used to perform digital signature generation and verification with
  ECDSA and Schnorr;
- Used to perform data encryption and decryption.

(Curve used in cryptocurrencies such as Bitcoin, Ethereum, etc...)

For educational purposes only.

Works on Python 3.8 or higher.


    Source code:

            https://github.com/gtmadureira/cryptography/blob/main/ecc/secp256k1/secp256k1_jacobian.py


    Author information:

            Name:
            • Gustavo Madureira ([email protected])

            Nickname:
            • Hattoshi Hanzōmoto ([email protected])

            Webpage:
            • https://gtmadureira.github.io/
"""


from types import NoneType
from typing import Final, Tuple

# Type hints.
Point = Tuple[int, int]
JacobianCoordinate = Tuple[int, int, int]
ScalarBinary = Tuple[str, ...]


# *****************************************************************************
# *                                                                           *
# *        The manipulation of binary, hexadecimal and integer values.        *
# *                                                                           *
# *****************************************************************************
# *                                                                           *
# *****************************************************************************
# ********************************* [ BEGIN ] *********************************
# *****************************************************************************


def is_bin_encoded(_bin: str) -> bool:
    """Check if the input string is an encoded binary value."""
    assert isinstance(_bin, str)
    try:
        result = bool(((int(_bin, 2) == 0) or int(_bin, 2)) and
                      ((len(_bin) % 2) == 0))
    except ValueError:
        result = False
    assert isinstance(result, bool)
    return result


def is_hex_encoded(_hex: str) -> bool:
    """Check if the input string is an encoded hexadecimal value."""
    assert isinstance(_hex, str)
    try:
        result = bool(((int(_hex, 16) == 0) or int(_hex, 16)) and
                      ((len(_hex) % 2) == 0))
    except ValueError:
        result = False
    assert isinstance(result, bool)
    return result


def hex_from_int(_x: int, output_length_bytes: int) -> str:
    """Converts an integer to an encoded hexadecimal string."""
    assert isinstance(_x and output_length_bytes, int)
    result = hex(_x)[2:].zfill(output_length_bytes * 2)
    assert (isinstance(result, str) and
            is_hex_encoded(result))
    return result


# *****************************************************************************
# ********************************** [ END ] **********************************
# *****************************************************************************


# *****************************************************************************
# *                                                                           *
# *    The mathematical domain parameters of the elliptic curve SECP256K1,    *
# *    over a finite field (Fp).                                              *
# *                                                                           *
# *    Source:   https://www.secg.org/sec2-v2.pdf                             *
# *                                                                           *
# *****************************************************************************
# *                                                                           *
# *****************************************************************************
# ********************************* [ BEGIN ] *********************************
# *****************************************************************************


# The finite field (Fp) is defined by:
FP_CURVE: Final[int] = \
    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F

assert (isinstance(FP_CURVE, int) and
        is_hex_encoded(hex_from_int(FP_CURVE, 32)))


# The elliptic curve in short Weierstrass form over a finite field (Fp)
# ( y² ≡ x³ + a⋅x + b  mod Fp ) is defined by the coefficients {a,b}:
A_CURVE: Final[int] = \
    0x0000000000000000000000000000000000000000000000000000000000000000

B_CURVE: Final[int] = \
    0x0000000000000000000000000000000000000000000000000000000000000007

assert (isinstance(A_CURVE and B_CURVE, int) and
        is_hex_encoded(hex_from_int(A_CURVE, 32)) and
        is_hex_encoded(hex_from_int(B_CURVE, 32)))


# The generator point (G), over the affine coordinate ( x , y ), is
# defined by:
X_COORD_GENERATOR_POINT_CURVE: Final[int] = \
    0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798

Y_COORD_GENERATOR_POINT_CURVE: Final[int] = \
    0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

assert (isinstance(X_COORD_GENERATOR_POINT_CURVE and
                   Y_COORD_GENERATOR_POINT_CURVE, int) and
        is_hex_encoded(hex_from_int(X_COORD_GENERATOR_POINT_CURVE, 32)) and
        is_hex_encoded(hex_from_int(Y_COORD_GENERATOR_POINT_CURVE, 32)))

GENERATOR_POINT_CURVE: Final[Point] = (X_COORD_GENERATOR_POINT_CURVE,
                                       Y_COORD_GENERATOR_POINT_CURVE)

assert (isinstance(GENERATOR_POINT_CURVE, tuple) and
        is_hex_encoded(hex_from_int(GENERATOR_POINT_CURVE[0], 32)) and
        is_hex_encoded(hex_from_int(GENERATOR_POINT_CURVE[1], 32)))


# The order (n) of the generator point and the cofactor (h) are defined
# by:
N_CURVE: Final[int] = \
    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

H_CURVE: Final[int] = \
    0x0000000000000000000000000000000000000000000000000000000000000001

assert (isinstance(N_CURVE and H_CURVE, int) and
        is_hex_encoded(hex_from_int(N_CURVE, 32)) and
        is_hex_encoded(hex_from_int(H_CURVE, 32)))


# The point that points to infinity on the elliptic curve, over the
# affine coordinate ( x , y ), is defined by:
X_COORD_POINT_INFINITY_CURVE: Final[int] = 0

Y_COORD_POINT_INFINITY_CURVE: Final[int] = 0 if (B_CURVE != 0) else 1

assert isinstance(X_COORD_POINT_INFINITY_CURVE and
                  Y_COORD_POINT_INFINITY_CURVE, int)

POINT_INFINITY_CURVE: Final[Point] = (X_COORD_POINT_INFINITY_CURVE,
                                      Y_COORD_POINT_INFINITY_CURVE)

assert isinstance(POINT_INFINITY_CURVE, tuple)


# The point that points to infinity on the elliptic curve, over the
# Jacobian coordinate ( x : y : z ), is defined by:
X_COORD_POINT_INFINITY_JACOBIAN: Final[int] = 1

Y_COORD_POINT_INFINITY_JACOBIAN: Final[int] = 1

Z_COORD_POINT_INFINITY_JACOBIAN: Final[int] = 0

assert isinstance(X_COORD_POINT_INFINITY_JACOBIAN and
                  Y_COORD_POINT_INFINITY_JACOBIAN and
                  Z_COORD_POINT_INFINITY_JACOBIAN, int)

POINT_INFINITY_JACOBIAN: Final[JacobianCoordinate] = \
    (X_COORD_POINT_INFINITY_JACOBIAN,
     Y_COORD_POINT_INFINITY_JACOBIAN,
     Z_COORD_POINT_INFINITY_JACOBIAN)

assert isinstance(POINT_INFINITY_JACOBIAN, tuple)


# *****************************************************************************
# ********************************** [ END ] **********************************
# *****************************************************************************


# *****************************************************************************
# *                                                                           *
# *       The elliptic curve arithmetic, using the Jacobian coordinate,       *
# *       over a finite field (Fp).                                           *
# *                                                                           *
# *       Source:   https://www.hyperelliptic.org/EFD/                        *
# *                                                                           *
# *                 https://www.hyperelliptic.org/EFD/precomp.pdf             *
# *                                                                           *
# *                 https://www.hyperelliptic.org/HEHCC/                      *
# *                                                                           *
# *                 https://www.math.umd.edu/~lcw/ellipticcurves.html         *
# *                                                                           *
# *****************************************************************************
# *                                                                           *
# *****************************************************************************
# ********************************* [ BEGIN ] *********************************
# *****************************************************************************


def modular_inverse(_k: int, _p: int) -> int:
    """
    Fermat's little theorem on the elliptic curve to find the modular
    multiplicative inverse.

    Returns the modular multiplicative inverse of {_k mod _p}. Where the
    only integer {_x} is defined such that {(_k ⋅ _x) mod _p = 1}.

    {_p} must be a prime number.
    """
    assert isinstance(_k and _p, int)
    if (_k % _p) == 0:
        result = None
        assert isinstance(result, NoneType)
        return result  # type: ignore
    _x = pow(_k, - 1, _p)
    assert bool(((_k * _x) % _p) == 1)
    result = _x
    assert isinstance(result, int)
    return result


def is_infinite(point: Point) -> bool:
    """
    Returns True if the point is at infinity on the elliptic curve;
    otherwise, it returns False.
    """
    assert isinstance(point, tuple)
    _xp, _yp = point
    result = bool((point == POINT_INFINITY_CURVE) or
                  ((_xp == 0) and (_yp != 0)))
    assert isinstance(result, bool)
    return result


def is_on_curve(point: Point) -> bool:
    """
    Returns True if the point lies on the elliptic curve; otherwise, it
    returns False.
    """
    assert isinstance(point, tuple)
    if is_infinite(point):
        result = True
        assert isinstance(result, bool)
        return result
    _xp, _yp = point
    result = bool(((pow(_yp, 2, FP_CURVE) - pow(_xp, 3, FP_CURVE) - A_CURVE *
                    _xp - B_CURVE) % FP_CURVE) == 0)
    assert isinstance(result, bool)
    return result


def x_coordinate(point: Point) -> int:
    """
    Refers to {x} coordinate of a point, over the affine coordinate
    ( x , y ), assuming it is not at infinity, then returns {x}.
    """
    assert (isinstance(point, tuple) and
            is_on_curve(point) and not
            is_infinite(point))
    _xp, _ = point
    result = _xp
    assert isinstance(result, int)
    return result


def y_coordinate(point: Point) -> int:
    """
    Refers to {y} coordinate of a point, over the affine coordinate
    ( x , y ) assuming it is not at infinity, then returns {y}.
    """
    assert (isinstance(point, tuple) and
            is_on_curve(point) and not
            is_infinite(point))
    _, _yp = point
    result = _yp
    assert isinstance(result, int)
    return result


def has_even_y(point: Point) -> bool:
    """
    Where the point is not at infinity, the same being represented as
    the affine coordinate ( x , y ), it returns True so that the
    y-coordinate is an even value if {_yp mod 2 = 0}; otherwise, it
    returns False.
    """
    assert (isinstance(point, tuple) and
            is_on_curve(point) and not
            is_infinite(point))
    _yp = y_coordinate(point)
    result = bool((_yp % 2) == 0)
    assert isinstance(result, bool)
    return result


def lift_x(_xp: int) -> Point:
    """
    Given an x-coordinate on the curve, return a corresponding affine
    point, the same being represented as the affine coordinate
    ( x , y ), for which the y-coordinate is even:


    {x(point) = x}

    and

    {y(point) = y} if {y mod 2 = 0} else
    {y(point) = (Fp) - y} otherwise.
    """
    assert isinstance(_xp, int)
    if not 0 < _xp < FP_CURVE:
        result = POINT_INFINITY_CURVE
        assert isinstance(result, tuple)
        return result
    yp_2 = (pow(_xp, 3, FP_CURVE) + A_CURVE * _xp + B_CURVE) % FP_CURVE
    _yp = pow(yp_2, (FP_CURVE + 1) // 4, FP_CURVE)
    if pow(_yp, 2, FP_CURVE) != yp_2:
        result = POINT_INFINITY_CURVE
        assert isinstance(result, tuple)
        return result
    point = (_xp, _yp)
    result = (x_coordinate(point),
              y_coordinate(point) if has_even_y(point) else
              (FP_CURVE - y_coordinate(point)))
    assert isinstance(result, tuple)
    return result


def is_infinite_jacobian(jacobian: JacobianCoordinate) -> bool:
    """
    Returns True if the point is at infinity on the elliptic curve over
    the Jacobian coordinate ( x : y : z ); otherwise, it returns False.
    """
    assert isinstance(jacobian, tuple)
    _xp, _yp, _zp = jacobian
    result = bool((jacobian == POINT_INFINITY_JACOBIAN) or
                  ((_zp == 0) and (0 not in (_xp, _yp))))
    assert isinstance(result, bool)
    return result


def is_on_curve_jacobian(jacobian: JacobianCoordinate) -> bool:
    """
    Returns True if the point lies on the elliptic curve over the
    Jacobian coordinate ( x : y : z ); otherwise, it returns False.
    """
    assert isinstance(jacobian, tuple)
    if is_infinite_jacobian(jacobian):
        result = True
        assert isinstance(result, bool)
        return result
    _xp, _yp, _zp = jacobian
    zp_2 = pow(_zp, 2, FP_CURVE)
    zp_4 = pow(_zp, 4, FP_CURVE)
    result = bool(((pow(_yp, 2, FP_CURVE) - pow(_xp, 3, FP_CURVE) - A_CURVE *
                    _xp * zp_4 - B_CURVE * zp_2 * zp_4) % FP_CURVE) == 0)
    assert isinstance(result, bool)
    return result


def is_affine_jacobian(jacobian: JacobianCoordinate) -> bool:
    """
    Returns True if the point is the affine form in the Jacobian
    coordinate ( x : y : 1 ).
    """
    assert (isinstance(jacobian, tuple) and
            is_on_curve_jacobian(jacobian) and not
            is_infinite_jacobian(jacobian))
    _, _, _zp = jacobian
    result = bool(_zp == 1)
    assert isinstance(result, bool)
    return result


def to_jacobian(point: Point) -> JacobianCoordinate:
    """
    Convert an affine point ( x , y ) to a Jacobian coordinate
    ( x : y : z ), or return a point at infinity.
    """
    assert (isinstance(point, tuple) and
            is_on_curve(point))
    if is_infinite(point):
        jacobian = POINT_INFINITY_JACOBIAN
        result = jacobian
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _xp, _yp = point
    _xp, _yp, _zp = (_xp, _yp, 1)  # pylint: disable=W0127
    jacobian = (_xp, _yp, _zp)
    result = jacobian
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def from_jacobian(jacobian: JacobianCoordinate) -> Point:
    """
    Convert a Jacobian coordinate ( x : y : z ) to an affine point
    ( x , y ), or return a point at infinity.
    """
    assert (isinstance(jacobian, tuple) and
            is_on_curve_jacobian(jacobian))
    if is_infinite_jacobian(jacobian):
        point = POINT_INFINITY_CURVE
        result = point
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    _xp, _yp, _zp = jacobian
    if is_affine_jacobian(jacobian):
        point = (_xp, _yp)
        result = point
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    zp_inv = modular_inverse(_zp, FP_CURVE)
    zp_inv_2 = pow(zp_inv, 2, FP_CURVE)
    zp_inv_3 = pow(zp_inv, 3, FP_CURVE)
    point = ((zp_inv_2 * _xp) % FP_CURVE, (zp_inv_3 * _yp) % FP_CURVE)
    result = point
    assert (isinstance(result, tuple) and
            is_on_curve(result))
    return result


def jacobian_point_doubling(  # pylint: disable=R0914
        jacobian_p: JacobianCoordinate) -> JacobianCoordinate:
    """
    Point doubling on the elliptic curve over the Jacobian coordinate
    ( x : y : z ).

    It doubles Point-P.

    - Point-P is defined as Jacobian-P.
    """
    assert (isinstance(jacobian_p, tuple) and
            is_on_curve_jacobian(jacobian_p))
    if is_infinite_jacobian(jacobian_p):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _xp, _yp, _zp = jacobian_p
    xp_2 = pow(_xp, 2, FP_CURVE)
    yp_2 = pow(_yp, 2, FP_CURVE)
    yp_4 = pow(yp_2, 2, FP_CURVE)
    zp_2 = pow(_zp, 2, FP_CURVE)
    _s = (2 * (pow(_xp + yp_2, 2, FP_CURVE) - xp_2 - yp_4)) % FP_CURVE
    if not A_CURVE:
        _m = (3 * xp_2) % FP_CURVE
        _t = pow(_m, 2, FP_CURVE)
        _xr = (_t - 2 * _s) % FP_CURVE
        _yr = (_m * (_s - _xr) - 8 * yp_4) % FP_CURVE
        _zr = (2 * _yp * _zp) % FP_CURVE
        jacobian_r = (_xr, _yr, _zr)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if (A_CURVE % FP_CURVE) == (FP_CURVE - 3):
        alpha = (_xp * yp_2) % FP_CURVE
        beta = (3 * (_xp - zp_2) * (_xp + zp_2)) % FP_CURVE
        _xr = (pow(beta, 2, FP_CURVE) - 8 * alpha) % FP_CURVE
        _yr = ((beta * (4 * alpha - _xr) - 8 *
               pow(yp_2, 2, FP_CURVE)) % FP_CURVE)
        _zr = (pow(_yp + _zp, 2, FP_CURVE) - yp_2 - zp_2) % FP_CURVE
        jacobian_r = (_xr, _yr, _zr)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if _zp == 1:
        _m = (3 * xp_2 + A_CURVE) % FP_CURVE
        _zr = (2 * _yp) % FP_CURVE
    else:
        _m = (3 * xp_2 + A_CURVE * pow(zp_2, 2, FP_CURVE)) % FP_CURVE
        _zr = (pow(_yp + _zp, 2, FP_CURVE) - yp_2 - zp_2) % FP_CURVE
    _t = (pow(_m, 2, FP_CURVE) - 2 * _s) % FP_CURVE
    _xr = _t
    _yr = (_m * (_s - _t) - 8 * yp_4) % FP_CURVE
    jacobian_r = (_xr, _yr, _zr)
    result = jacobian_r
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def jacobian_point_addition_affined_only(  # pylint: disable=R0914
        jacobian_p: JacobianCoordinate,
        jacobian_q: JacobianCoordinate) -> JacobianCoordinate:
    """
    Point addition on the elliptic curve over the Jacobian coordinate
    ( x : y : z ), with both points with z = 1, that is, only with
    points in affine space ( x : y : 1 ).

    It adds Point-P with Point-Q.

    - Point-P is defined as Jacobian-P, and Point-Q is defined as
      Jacobian-Q.
    """
    assert (isinstance(jacobian_p and jacobian_q, tuple) and
            is_on_curve_jacobian(jacobian_p) and
            is_on_curve_jacobian(jacobian_q) and
            is_affine_jacobian(jacobian_p) and
            is_affine_jacobian(jacobian_q))
    _xp, _yp, _ = jacobian_p
    _xq, _yq, _ = jacobian_q
    if (_xp == _xq) and (_yp != _yq):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if (_xp == _xq) and (_yp == _yq):
        jacobian_r = jacobian_point_doubling(jacobian_p)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _h = (_xq - _xp) % FP_CURVE
    h_2 = pow(_h, 2, FP_CURVE)
    _i = (4 * h_2) % FP_CURVE
    _j = (_h * _i) % FP_CURVE
    _r = (2 * (_yq - _yp)) % FP_CURVE
    _v = (_xp * _i) % FP_CURVE
    _xr = (pow(_r, 2, FP_CURVE) - _j - 2 * _v) % FP_CURVE
    _yr = (_r * (_v - _xr) - 2 * _yp * _j) % FP_CURVE
    _zr = (2 * _h) % FP_CURVE
    jacobian_r = (_xr, _yr, _zr)
    result = jacobian_r
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def jacobian_point_addition_z_equals(  # pylint: disable=R0914
        jacobian_p: JacobianCoordinate,
        jacobian_q: JacobianCoordinate) -> JacobianCoordinate:
    """
    Point addition on the elliptic curve over the Jacobian coordinate
    ( x : y : z ), with both points having z equal (Co-Z), but
    being != 1, that is, both are not in affine space but share the same
    z-coordinate ( x : y : z != 1 ).

    It adds Point-P with Point-Q.

    - Point-P is defined as Jacobian-P, and Point-Q is defined as
      Jacobian-Q.
    """
    assert (isinstance(jacobian_p and jacobian_q, tuple) and
            is_on_curve_jacobian(jacobian_p) and
            is_on_curve_jacobian(jacobian_q) and not
            is_affine_jacobian(jacobian_p) and not
            is_affine_jacobian(jacobian_q))
    _xp, _yp, _zp = jacobian_p
    _xq, _yq, _ = jacobian_q
    if (_xp == _xq) and (_yp != _yq):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if (_xp == _xq) and (_yp == _yq):
        jacobian_r = jacobian_point_doubling(jacobian_p)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _a = pow(_xq - _xp, 2, FP_CURVE)
    _b = (_xp * _a) % FP_CURVE
    _c = (_xq * _a) % FP_CURVE
    _d = pow(_yq - _yp, 2, FP_CURVE)
    _xr = (_d - _b - _c) % FP_CURVE
    _yr = ((_yq - _yp) * (_b - _xr) - _yp * (_c - _b)) % FP_CURVE
    _zr = (_zp * (_xq - _xp)) % FP_CURVE
    jacobian_r = (_xr, _yr, _zr)
    result = jacobian_r
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def jacobian_point_addition_mixed(  # pylint: disable=R0914
        jacobian_p: JacobianCoordinate,
        jacobian_q: JacobianCoordinate) -> JacobianCoordinate:
    """
    Point addition (mixed) on the elliptic curve over the Jacobian
    coordinate ( x : y : z ), and the affine form in the Jacobian
    coordinate ( x : y : 1 ).

    It adds Point-P with Point-Q.

    - Point-P is defined as Jacobian-P, and Point-Q is defined as
      Jacobian-Q.
    """
    assert (isinstance(jacobian_p and jacobian_q, tuple) and
            is_on_curve_jacobian(jacobian_p) and
            is_on_curve_jacobian(jacobian_q) and not
            is_affine_jacobian(jacobian_p) and
            is_affine_jacobian(jacobian_q))
    _xp, _yp, _zp = jacobian_p
    _xq, _yq, _ = jacobian_q
    zp_2 = pow(_zp, 2, FP_CURVE)
    _uq = (_xq * zp_2) % FP_CURVE
    _sq = (_yq * _zp * zp_2) % FP_CURVE
    if (_xp == _uq) and (_yp != _sq):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if (_xp == _uq) and (_yp == _sq):
        jacobian_r = jacobian_point_doubling(jacobian_p)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _h = (_uq - _xp) % FP_CURVE
    h_2 = pow(_h, 2, FP_CURVE)
    _i = (4 * h_2) % FP_CURVE
    _j = (_h * _i) % FP_CURVE
    _r = (2 * (_sq - _yp)) % FP_CURVE
    _v = (_xp * _i) % FP_CURVE
    _xr = (pow(_r, 2, FP_CURVE) - _j - 2 * _v) % FP_CURVE
    _yr = (_r * (_v - _xr) - 2 * _yp * _j) % FP_CURVE
    _zr = (pow(_zp + _h, 2, FP_CURVE) - zp_2 - h_2) % FP_CURVE
    jacobian_r = (_xr, _yr, _zr)
    result = jacobian_r
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def jacobian_point_addition(  # pylint: disable=R0911, R0914, R0915
        jacobian_p: JacobianCoordinate,
        jacobian_q: JacobianCoordinate) -> JacobianCoordinate:
    """
    Point addition on the elliptic curve over the Jacobian coordinate
    ( x : y : z ).

    It adds Point-P with Point-Q.

    - Point-P is defined as Jacobian-P, and Point-Q is defined as
      Jacobian-Q.
    """
    assert (isinstance(jacobian_p and jacobian_q, tuple) and
            is_on_curve_jacobian(jacobian_p) and
            is_on_curve_jacobian(jacobian_q))
    if is_infinite_jacobian(jacobian_p) and is_infinite_jacobian(jacobian_q):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if is_infinite_jacobian(jacobian_p):
        jacobian_r = jacobian_q
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if is_infinite_jacobian(jacobian_q):
        jacobian_r = jacobian_p
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if is_affine_jacobian(jacobian_p) and is_affine_jacobian(jacobian_q):
        jacobian_r = jacobian_point_addition_affined_only(jacobian_p,
                                                          jacobian_q)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if is_affine_jacobian(jacobian_p):
        jacobian_r = jacobian_point_addition_mixed(  # pylint: disable=W1114
            jacobian_q, jacobian_p)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if is_affine_jacobian(jacobian_q):
        jacobian_r = jacobian_point_addition_mixed(jacobian_p, jacobian_q)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _xp, _yp, _zp = jacobian_p
    _xq, _yq, _zq = jacobian_q
    if _zp == _zq:
        jacobian_r = jacobian_point_addition_z_equals(jacobian_p, jacobian_q)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    zp_2 = pow(_zp, 2, FP_CURVE)
    zq_2 = pow(_zq, 2, FP_CURVE)
    _up = (_xp * zq_2) % FP_CURVE
    _uq = (_xq * zp_2) % FP_CURVE
    _sp = (_yp * _zq * zq_2) % FP_CURVE
    _sq = (_yq * _zp * zp_2) % FP_CURVE
    if (_up == _uq) and (_sp != _sq):
        jacobian_r = POINT_INFINITY_JACOBIAN
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    if (_up == _uq) and (_sp == _sq):
        jacobian_r = jacobian_point_doubling(jacobian_p)
        result = jacobian_r
        assert (isinstance(result, tuple) and
                is_on_curve_jacobian(result))
        return result
    _h = (_uq - _up) % FP_CURVE
    _i = pow(2 * _h, 2, FP_CURVE)
    _j = (_h * _i) % FP_CURVE
    _r = (2 * (_sq - _sp)) % FP_CURVE
    _v = (_up * _i) % FP_CURVE
    _xr = (pow(_r, 2, FP_CURVE) - _j - 2 * _v) & FP_CURVE
    _yr = (_r * (_v - _xr) - 2 * _sp * _j) % FP_CURVE
    _zr = ((pow(_zp + _zq, 2, FP_CURVE) - zp_2 - zq_2) * _h) % FP_CURVE
    jacobian_r = (_xr, _yr, _zr)
    result = jacobian_r
    assert (isinstance(result, tuple) and
            is_on_curve_jacobian(result))
    return result


def fast_point_addition(point_p: Point, point_q: Point) -> Point:
    """
    Fast point addition on the elliptic curve over the affine form
    ( x , y ) to the Jacobian coordinate ( x : y : z ).

    It adds Point-P with Point-Q.

    - Point-P is defined as Jacobian-P, and Point-Q is defined as
      Jacobian-Q.
    """
    assert (isinstance(point_p and point_q, tuple) and
            is_on_curve(point_p) and
            is_on_curve(point_q))
    if is_infinite(point_p) and is_infinite(point_q):
        point_r = POINT_INFINITY_CURVE
        result = point_r
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    if is_infinite(point_p):
        point_r = point_q
        result = point_r
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    if is_infinite(point_q):
        point_r = point_p
        result = point_r
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    jacobian_p = to_jacobian(point_p)
    jacobian_q = to_jacobian(point_q)
    assert (isinstance(jacobian_p and jacobian_q, tuple) and
            is_on_curve_jacobian(jacobian_p) and
            is_on_curve_jacobian(jacobian_q))
    jacobian_r = jacobian_point_addition_affined_only(jacobian_p, jacobian_q)
    assert (isinstance(jacobian_r, tuple) and
            is_on_curve_jacobian(jacobian_r))
    point_r = from_jacobian(jacobian_r)
    result = point_r
    assert (isinstance(result, tuple) and
            is_on_curve(result))
    return result


def fast_scalar_multiplication(scalar: int, point: Point) -> Point:
    """
    Fast scalar multiplication of point on the elliptic curve over the
    affine ( x , y ) to the Jacobian coordinate ( x : y : z ).

    It doubles Point-P and adds Point-P with Point-Q.

    - Point is defined as Jacobian and Current is defined as
      New-Point.
    """
    # §     [ SCALAR AND POINT VERIFICATION ]

    # *  -> Initial verification of arguments received by function
    # *     parameters.
    # *  -> The {scalar} must be valid, and the {point} must lie on the
    # *     elliptic curve.
    assert (isinstance(scalar, int) and
            isinstance(point, tuple) and
            is_on_curve(point))
    if (scalar in (0, N_CURVE)) or is_infinite(point):
        new_point = POINT_INFINITY_CURVE
        result = new_point
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    if scalar == 1:
        result = point
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result
    if (scalar < 0) or (scalar > N_CURVE):
        new_point = fast_scalar_multiplication(scalar % N_CURVE, point)
        result = new_point
        assert (isinstance(result, tuple) and
                is_on_curve(result))
        return result

    # §     [ SCALAR PREPARATION ]

    # *  -> The next variable below will be assigned after converting
    # *     the scalar (represented as an integer) to string objects as
    # *     bits ("0" or "1"), and storing them inside a tuple.
    # *     e.g: Tuple["1", "0", "0", "1", ...].
    # *  -> We guarantee, as a warning in the code, that it will be
    # *     declared as Final and cannot be reassigned.
    scalar_bits: Final[ScalarBinary] = tuple(bin(scalar)[2:])
    assert is_bin_encoded("".join(scalar_bits).zfill(256))

    # §     [ SCALAR-POINT MULTIPLICATION ]

    # *  -> For-Loop below, working from left-to-right.
    # *  -> "AND IGNORING" the Most Significant Bit (MSB) from the
    # *     incoming scalar binary, that will be iterated over. This is
    # *     usually the bit farthest to the left, or the bit transmitted
    # *     first in a sequence.
    jacobian = to_jacobian(point)
    current = jacobian
    assert (isinstance(jacobian and current, tuple) and
            is_on_curve_jacobian(jacobian) and
            is_on_curve_jacobian(current))
    for bit in scalar_bits[1:]:
        current = jacobian_point_doubling(current)
        if bit == "1":
            current = jacobian_point_addition(current, jacobian)
    new_point = from_jacobian(current)
    result = new_point
    assert (isinstance(result, tuple) and
            is_on_curve(result))
    return result


# *****************************************************************************
# ********************************** [ END ] **********************************
# *****************************************************************************


# *****************************************************************************
# *                                                                           *
# *              The elliptic curve scalar multiplication test.               *
# *                                                                           *
# *****************************************************************************
# *                                                                           *
# *****************************************************************************
# ********************************* [ BEGIN ] *********************************
# *****************************************************************************


if __name__ == "__main__":

    try:
        # *  -> Non-Singularity test ( 4⋅a³ + 27⋅b² mod p != 0 mod p )
        # *     for the elliptic curve, and also tests if the generator
        # *     point lies on the elliptic curve.
        # *  -> The program will only start if it passes the tests.
        assert ((((- 16 * (4 * pow(A_CURVE, 3, FP_CURVE) + 27 *
                           pow(B_CURVE, 2, FP_CURVE))) % FP_CURVE) !=
                 (0 % FP_CURVE)) and is_on_curve(GENERATOR_POINT_CURVE))

        from os import name as system_type
        from os import system as run_command
        from random import randrange
        from time import perf_counter

        from colorama import just_fix_windows_console

        # Get ANSI escapes from the color scheme to work on the Windows
        # operating system.
        just_fix_windows_console()

        # Define clear_screen function.
        def clear_screen() -> None:
            """
            Tests the operating system type and sets the screen clear
            command.
            """
            # Screen clear command for Windows operating system.
            if system_type == "nt":
                run_command("cls")
            # Screen clear command for Linux/UNIX and macOS operating
            # systems.
            elif system_type == "posix":
                run_command("clear")

        start = perf_counter()
        ELAPSED = 0.0
        COUNTER = 1
        while ELAPSED < 15.0:
            private_key = randrange(1, N_CURVE)
            public_key = fast_scalar_multiplication(
                private_key, GENERATOR_POINT_CURVE)
            if has_even_y(public_key):
                PREFIX = "02"
            else:
                PREFIX = "03"
            data = (str(private_key),
                    hex(private_key)[2:].zfill(64).upper(),
                    hex(x_coordinate(public_key))[2:].zfill(64).upper(),
                    hex(y_coordinate(public_key))[2:].zfill(64).upper(),
                    PREFIX)
            clear_screen()
            ELAPSED = perf_counter() - start
            print(f"""\033[92m
            SECP256K1 at Jacobian Coordinate
            Copyright (C) 2021 - 2023  Gustavo Madureira
            License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
            This program comes with ABSOLUTELY NO WARRANTY.
            This is free software, and you are welcome to redistribute it
            under certain conditions.

            \33[1;7m[ *** FOR EDUCATIONAL PURPOSES ONLY *** ]\033[0m


               \033[92mPoint Number: {data[0]}
                Private Key: {data[1]}
    Uncompressed Public Key: 04{data[2]}
                               {data[3]}
      Compressed Public Key: {data[4]}{data[2]}

               Elapsed Time: {ELAPSED:.02f} seconds.
   Number of Points Created: {COUNTER} points.
\033[0m""")
            COUNTER += 1
    except Exception:  # pylint: disable=W0703
        print("""\033[91m\33[1;7m
[-----------------------------------------------------------------------------]
[                                                                             ]
[     *** Something bad happened and the program had to be shut down ***      ]
[                                                                             ]
[  Possible Error :                                                           ]
[                                                                             ]
[ [X] Mathematical domain parameters of the elliptic curve may be incorrect ! ]
[                                                                             ]
[-----------------------------------------------------------------------------]
\033[0m""")


# *****************************************************************************
# ********************************** [ END ] **********************************
# *****************************************************************************

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.