# Desafio Golang ## Como você será avaliado O objetivo deste desafio é verificar o seu conhecimento, resolvendo um cenário de desenvolvimento com escopo reduzido, porém baseado em necessidades reais. Tendo isso em mente, é importante ficar atento a alguns detalhes: 1. Você **não deve** utilizar geradores de código ao desenvolver seu desafio. Geradores como `mockgen` e similares serão aceitos ++se usados apenas para testes++. 2. Caso utilize algum banco de dados, documente e automatize a infraestrutura necessária. Lembre-se que seu código não será avaliado na sua máquina! 3. Não se esqueça da documentação do projeto. É praxe que exista, no mínimo, um `README` com as instruções e considerações mais importantes (por exemplo, documentação dos endpoints de uma API, opções válidas para um aplicativo linha de comando, etc.). 4. Por favor, utilize `git` como seu VCS. Lembre-se também de usar um repositório público, para que possamos acessar seu código. 5. Por favor, não entregue seu projeto todo com um único commit. Parte **essencial** da avaliação é observar como você desenvolve seu raciocínio e lida com os problemas que vão aparecendo. 6. Testes unitários não são obrigatórios, mas serão muito bem vindos. 7. Caso utilize dependências, lembre-se de gerenciá-las da maneira correta (`go mod`, `dep`, `govendor`, etc.) ### Conhecimento Levando em consideração que nas **blockchains** temos um parte da cripitográfica bastante evidente, alguns exemplos, o **ECDSA**, **Keccak256**, **SHA3**. Com esses mecanismos, conseguimos criptografar e descriptografar e gerar hash's, utilizando **ECDSA**, **Secp256k1** e **SHA3**, alguns desses algoritimos estão presente no "Bitcoin" ou no "Ethereum". ### Desafio O desafio será construir um **aplicativo em linha de comando** para **assinar** arquivos e **validar a assinatura** gerada. A "entrada" do aplicativo será um nome de um arquivo (que será passado pela interface em linhade comando) e sua saída será um arquivo de mesmo nome, acrescido da extensão `.sig`. O arquivo `.sig`, como o nome sugere, irá conter a assinatura. Note que para gerar uma assinatura, é necessário antes criar um par de chaves pública/privada. Seu aplicativo deverá gerar este par^[**Dica:** Não utilize senhas para gerar a chave. Se realmente for necessário, use um valor fixo, para testes.], com os nomes `private.key` e `public.key`, para as chaves pública e privada, respectivamente. Uma vez terminado o projeto, seu funcionamento deverá ser semelhante ao exemplo abaixo^[Usamos o nome `sign` apenas como exemplo. Você pode usar o nome que quiser para o seu projeto.]: ```shell # primeiro, criamos um arquivo com um determinado conteúdo: $ echo "meu arquivo" > file.txt # criamos um par de chaves pública/privada $ sig -generate Key files generated. # está tudo certo? $ ls private.key public.key file.txt # geramos uma assinatura para o arquivo $ sign file.txt Signature file 'file.txt.sig' generated. # Essa assinatura é válida? $ sign -v file.txt Comparing 'file.txt' with signature 'file.txt.sig'... Congratulations! This signature is valid! # Se mudarmos o arquivo (ou a assinatura), # o resultado é bem diferente... $ echo "outro conteudo" > file.txt $ sign -v file.txt Comparing 'file.txt' with signature 'file.txt.sig'... Ooops! The signature is NOT valid. ``` Algumas dicas que podem ajudar seu desenvolvimento: - Há uma package nativa do Go, chamada [`flag`](https://godoc.org/flag) que faz o parse de argumentos na linha de comando. - Lembre-se de validar os parâmetros de execução (o arquivo existe? as chaves foram criadas? etc.) - Antes mesmo de começar a programar, certifique-se de que entendeu o conceito de [Criptografia de chave pública](https://en.wikipedia.org/wiki/Public-key_cryptography), bem como a [diferença](https://stackoverflow.com/questions/454048/what-is-the-difference-between-encrypting-and-signing-in-asymmetric-encryption) entre este modelo e o modelo de criptografia simétrica. - Existem vários algoritmos para criptografia de chave pública ([RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)), [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm), entre outros), e várias bibliotecas (algumas padrão) que fornecem uma implementação para eles. Qualquer um deles será aceito para esse desafio^[Geralmente as blockchains utilizam `ECDSA`, `Keccak256`, `Secp256k1` e `SHA3` para criptografia/hashes.].