You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.9 KiB

  1. package nano
  2. import (
  3. "bytes"
  4. "crypto/sha512"
  5. "fmt"
  6. "github.com/pkg/errors"
  7. crypto "github.com/tendermint/go-crypto"
  8. )
  9. const (
  10. App = 0x80
  11. Init = 0x00
  12. Update = 0x01
  13. Digest = 0x02
  14. MaxChunk = 253
  15. KeyLength = 32
  16. SigLength = 64
  17. )
  18. var separator = []byte{0, 0xCA, 0xFE, 0}
  19. func generateSignRequests(payload []byte) [][]byte {
  20. // nice one-shot
  21. digest := []byte{App, Digest}
  22. if len(payload) < MaxChunk {
  23. return [][]byte{append(digest, payload...)}
  24. }
  25. // large payload is multi-chunk
  26. result := [][]byte{{App, Init}}
  27. update := []byte{App, Update}
  28. for len(payload) > MaxChunk {
  29. msg := append(update, payload[:MaxChunk]...)
  30. payload = payload[MaxChunk:]
  31. result = append(result, msg)
  32. }
  33. result = append(result, append(update, payload...))
  34. result = append(result, digest)
  35. return result
  36. }
  37. func parseDigest(resp []byte) (key, sig []byte, err error) {
  38. if resp[0] != App || resp[1] != Digest {
  39. return nil, nil, errors.New("Invalid header")
  40. }
  41. resp = resp[2:]
  42. if len(resp) != KeyLength+SigLength+len(separator) {
  43. return nil, nil, errors.Errorf("Incorrect length: %d", len(resp))
  44. }
  45. key, resp = resp[:KeyLength], resp[KeyLength:]
  46. if !bytes.Equal(separator, resp[:len(separator)]) {
  47. return nil, nil, errors.New("Cannot find 0xCAFE")
  48. }
  49. fmt.Println("successs")
  50. sig = resp[len(separator):]
  51. return key, sig, nil
  52. }
  53. func parseKey(data []byte) (key crypto.PubKey, err error) {
  54. ed := crypto.PubKeyEd25519{}
  55. if len(data) < len(ed) {
  56. return key, errors.Errorf("Key length too short: %d", len(data))
  57. }
  58. copy(ed[:], data)
  59. return ed.Wrap(), nil
  60. }
  61. func parseSig(data []byte) (key crypto.Signature, err error) {
  62. ed := crypto.SignatureEd25519{}
  63. if len(data) < len(ed) {
  64. return key, errors.Errorf("Sig length too short: %d", len(data))
  65. }
  66. copy(ed[:], data)
  67. return ed.Wrap(), nil
  68. }
  69. func hashMsg(data []byte) []byte {
  70. res := sha512.Sum512(data)
  71. return res[:]
  72. }