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.

150 lines
3.8 KiB

  1. package nano
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. crypto "github.com/tendermint/go-crypto"
  6. )
  7. // // Implements PrivKey, calling the ledger nano
  8. // type PrivKeyLedger struct{}
  9. // var _ PrivKeyInner = PrivKeyLedger{}
  10. // func (privKey PrivKeyLedger) AssertIsPrivKeyInner() {}
  11. // func (privKey PrivKeyLedger) Bytes() []byte {
  12. // return wire.BinaryBytes(PrivKey{privKey})
  13. // }
  14. // func (privKey PrivKeyLedger) Sign(msg []byte) Signature {
  15. // privKeyBytes := [64]byte(privKey)
  16. // signatureBytes := ed25519.Sign(&privKeyBytes, msg)
  17. // return SignatureEd25519(*signatureBytes).Wrap()
  18. // }
  19. // func (privKey PrivKeyLedger) PubKey() PubKey {
  20. // privKeyBytes := [64]byte(privKey)
  21. // pubBytes := *ed25519.MakePublicKey(&privKeyBytes)
  22. // return PubKeyEd25519(pubBytes).Wrap()
  23. // }
  24. // func (privKey PrivKeyLedger) Equals(other PrivKey) bool {
  25. // if otherEd, ok := other.Unwrap().(PrivKeyLedger); ok {
  26. // return bytes.Equal(privKey[:], otherEd[:])
  27. // } else {
  28. // return false
  29. // }
  30. // }
  31. // MockPrivKeyLedger behaves as the ledger, but stores a pre-packaged call-response
  32. // for use in test cases
  33. type MockPrivKeyLedger struct {
  34. Msg []byte
  35. Pub [KeyLength]byte
  36. Sig [SigLength]byte
  37. }
  38. // NewMockKey returns
  39. func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedger) {
  40. var err error
  41. pk.Msg, err = hex.DecodeString(msg)
  42. if err != nil {
  43. panic(err)
  44. }
  45. bpk, err := hex.DecodeString(pubkey)
  46. if err != nil {
  47. panic(err)
  48. }
  49. bsig, err := hex.DecodeString(sig)
  50. if err != nil {
  51. panic(err)
  52. }
  53. copy(pk.Pub[:], bpk)
  54. copy(pk.Sig[:], bsig)
  55. return pk
  56. }
  57. var _ crypto.PrivKeyInner = MockPrivKeyLedger{}
  58. // AssertIsPrivKeyInner fulfils PrivKey Interface
  59. func (pk MockPrivKeyLedger) AssertIsPrivKeyInner() {}
  60. // Bytes fulfils PrivKey Interface - not supported
  61. func (pk MockPrivKeyLedger) Bytes() []byte {
  62. return nil
  63. }
  64. // Sign returns a real SignatureLedger, if the msg matches what we expect
  65. func (pk MockPrivKeyLedger) Sign(msg []byte) crypto.Signature {
  66. if !bytes.Equal(pk.Msg, msg) {
  67. panic("Mock key is for different msg")
  68. }
  69. return crypto.SignatureEd25519(pk.Sig).Wrap()
  70. }
  71. // PubKey returns a real PubKeyLedger, that will verify this signature
  72. func (pk MockPrivKeyLedger) PubKey() crypto.PubKey {
  73. return PubKeyLedger{crypto.PubKeyEd25519(pk.Pub)}.Wrap()
  74. }
  75. // Equals compares that two Mocks have the same data
  76. func (pk MockPrivKeyLedger) Equals(other crypto.PrivKey) bool {
  77. if mock, ok := other.Unwrap().(MockPrivKeyLedger); ok {
  78. return bytes.Equal(mock.Pub[:], pk.Pub[:]) &&
  79. bytes.Equal(mock.Sig[:], pk.Sig[:]) &&
  80. bytes.Equal(mock.Msg, pk.Msg)
  81. }
  82. return false
  83. }
  84. ////////////////////////////////////////////
  85. // pubkey
  86. // PubKeyLedger works like a normal Ed25519 except a hash before the verify bytes
  87. type PubKeyLedger struct {
  88. crypto.PubKeyEd25519
  89. }
  90. // VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand
  91. func (pk PubKeyLedger) VerifyBytes(msg []byte, sig crypto.Signature) bool {
  92. hmsg := hashMsg(msg)
  93. return pk.PubKeyEd25519.VerifyBytes(hmsg, sig)
  94. }
  95. // Equals implements PubKey interface
  96. func (pk PubKeyLedger) Equals(other crypto.PubKey) bool {
  97. if ledger, ok := other.Unwrap().(PubKeyLedger); ok {
  98. return bytes.Equal(pk.PubKeyEd25519[:], ledger.PubKeyEd25519[:])
  99. }
  100. return false
  101. }
  102. /*** registration with go-data ***/
  103. func init() {
  104. crypto.PrivKeyMapper.
  105. // RegisterImplementation(PrivKeyLedger{}, "ledger", 0x10).
  106. RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11)
  107. crypto.PubKeyMapper.
  108. RegisterImplementation(PubKeyLedger{}, "ledger", 0x10)
  109. }
  110. // // Wrap fulfils interface for PrivKey struct
  111. // func (hi PrivKeyLedger) Wrap() crypto.PrivKey {
  112. // return PrivKey{hi}
  113. // }
  114. // Wrap fulfils interface for PrivKey struct
  115. func (pk MockPrivKeyLedger) Wrap() crypto.PrivKey {
  116. return crypto.PrivKey{pk}
  117. }
  118. // Wrap fulfils interface for PubKey struct
  119. func (pk PubKeyLedger) Wrap() crypto.PubKey {
  120. return crypto.PubKey{pk}
  121. }