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.

71 lines
1.7 KiB

  1. package sr25519
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/tendermint/tendermint/crypto"
  6. "github.com/tendermint/tendermint/crypto/tmhash"
  7. schnorrkel "github.com/ChainSafe/go-schnorrkel"
  8. )
  9. var _ crypto.PubKey = PubKeySr25519{}
  10. // PubKeySr25519Size is the number of bytes in an Sr25519 public key.
  11. const PubKeySr25519Size = 32
  12. // PubKeySr25519 implements crypto.PubKey for the Sr25519 signature scheme.
  13. type PubKeySr25519 [PubKeySr25519Size]byte
  14. // Address is the SHA256-20 of the raw pubkey bytes.
  15. func (pubKey PubKeySr25519) Address() crypto.Address {
  16. return crypto.Address(tmhash.SumTruncated(pubKey[:]))
  17. }
  18. // Bytes marshals the PubKey using amino encoding.
  19. func (pubKey PubKeySr25519) Bytes() []byte {
  20. bz, err := cdc.MarshalBinaryBare(pubKey)
  21. if err != nil {
  22. panic(err)
  23. }
  24. return bz
  25. }
  26. func (pubKey PubKeySr25519) VerifyBytes(msg []byte, sig []byte) bool {
  27. // make sure we use the same algorithm to sign
  28. if len(sig) != SignatureSize {
  29. return false
  30. }
  31. var sig64 [SignatureSize]byte
  32. copy(sig64[:], sig)
  33. publicKey := &(schnorrkel.PublicKey{})
  34. err := publicKey.Decode(pubKey)
  35. if err != nil {
  36. return false
  37. }
  38. signingContext := schnorrkel.NewSigningContext([]byte{}, msg)
  39. signature := &(schnorrkel.Signature{})
  40. err = signature.Decode(sig64)
  41. if err != nil {
  42. return false
  43. }
  44. return publicKey.Verify(signature, signingContext)
  45. }
  46. func (pubKey PubKeySr25519) String() string {
  47. return fmt.Sprintf("PubKeySr25519{%X}", pubKey[:])
  48. }
  49. // Equals - checks that two public keys are the same time
  50. // Runs in constant time based on length of the keys.
  51. func (pubKey PubKeySr25519) Equals(other crypto.PubKey) bool {
  52. if otherEd, ok := other.(PubKeySr25519); ok {
  53. return bytes.Equal(pubKey[:], otherEd[:])
  54. }
  55. return false
  56. }