# 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.].