|
|
package common
import ( "encoding/binary" "time"
ethCommon "github.com/ethereum/go-ethereum/common" ethCrypto "github.com/ethereum/go-ethereum/crypto" "github.com/iden3/go-iden3-crypto/babyjub" )
// AccountCreationAuthMsg is the message that is signed to authorize an account
// creation
const AccountCreationAuthMsg = "I authorize this babyjubjub key for hermez rollup account creation"
// AccountCreationAuth authorizations sent by users to the L2DB, to be used for
// account creations when necessary
type AccountCreationAuth struct { EthAddr ethCommon.Address `meddler:"eth_addr"` BJJ babyjub.PublicKeyComp `meddler:"bjj"` Signature []byte `meddler:"signature"` Timestamp time.Time `meddler:"timestamp,utctime"` }
// HashToSign builds the hash to be signed using BJJ pub key and the constant message
func (a *AccountCreationAuth) HashToSign(chainID uint16, hermezContractAddr ethCommon.Address) ([]byte, error) { // Calculate message to be signed
var chainIDBytes [2]byte binary.BigEndian.PutUint16(chainIDBytes[:], chainID) // to hash: [AccountCreationAuthMsg | compressedBJJ | chainID | hermezContractAddr]
return ethCrypto.Keccak256Hash([]byte(AccountCreationAuthMsg), a.BJJ[:], chainIDBytes[:], hermezContractAddr[:]).Bytes(), nil }
// VerifySignature ensures that the Signature is done with the specified EthAddr
func (a *AccountCreationAuth) VerifySignature(chainID uint16, hermezContractAddr ethCommon.Address) bool { // Calculate hash to be signed
msg, err := a.HashToSign(chainID, hermezContractAddr) if err != nil { return false } // Get public key from Signature
pubKBytes, err := ethCrypto.Ecrecover(msg, a.Signature) if err != nil { return false } pubK, err := ethCrypto.UnmarshalPubkey(pubKBytes) if err != nil { return false } // Get addr from pubK
addr := ethCrypto.PubkeyToAddress(*pubK) return addr == a.EthAddr }
|