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