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.

56 lines
1.9 KiB

  1. package common
  2. import (
  3. "encoding/binary"
  4. "time"
  5. ethCommon "github.com/ethereum/go-ethereum/common"
  6. ethCrypto "github.com/ethereum/go-ethereum/crypto"
  7. "github.com/iden3/go-iden3-crypto/babyjub"
  8. )
  9. // AccountCreationAuthMsg is the message that is signed to authorize an account
  10. // creation
  11. const AccountCreationAuthMsg = "I authorize this babyjubjub key for hermez rollup account creation"
  12. // AccountCreationAuth authorizations sent by users to the L2DB, to be used for
  13. // account creations when necessary
  14. type AccountCreationAuth struct {
  15. EthAddr ethCommon.Address `meddler:"eth_addr"`
  16. BJJ babyjub.PublicKeyComp `meddler:"bjj"`
  17. Signature []byte `meddler:"signature"`
  18. Timestamp time.Time `meddler:"timestamp,utctime"`
  19. }
  20. // HashToSign builds the hash to be signed using BJJ pub key and the constant message
  21. func (a *AccountCreationAuth) HashToSign(chainID uint16,
  22. hermezContractAddr ethCommon.Address) ([]byte, error) {
  23. // Calculate message to be signed
  24. var chainIDBytes [2]byte
  25. binary.BigEndian.PutUint16(chainIDBytes[:], chainID)
  26. // to hash: [AccountCreationAuthMsg | compressedBJJ | chainID | hermezContractAddr]
  27. return ethCrypto.Keccak256Hash([]byte(AccountCreationAuthMsg), a.BJJ[:], chainIDBytes[:],
  28. hermezContractAddr[:]).Bytes(), nil
  29. }
  30. // VerifySignature ensures that the Signature is done with the specified EthAddr
  31. func (a *AccountCreationAuth) VerifySignature(chainID uint16,
  32. hermezContractAddr ethCommon.Address) bool {
  33. // Calculate hash to be signed
  34. msg, err := a.HashToSign(chainID, hermezContractAddr)
  35. if err != nil {
  36. return false
  37. }
  38. // Get public key from Signature
  39. pubKBytes, err := ethCrypto.Ecrecover(msg, a.Signature)
  40. if err != nil {
  41. return false
  42. }
  43. pubK, err := ethCrypto.UnmarshalPubkey(pubKBytes)
  44. if err != nil {
  45. return false
  46. }
  47. // Get addr from pubK
  48. addr := ethCrypto.PubkeyToAddress(*pubK)
  49. return addr == a.EthAddr
  50. }