Verify ED25519 signatures, multi-sig, and threshold keys in Solidity with the HIP-632 isAuthorizedRaw and isAuthorized functions, and keep checks valid across key updates.
Overview
Hedera-native developers can leverage Hedera’s advanced account and key management features, including ED25519
accounts, multi-sig configurations, and threshold keys. To integrate seamlessly with EVM-compatible chains and
applications, you’ll need to work with ECDSA key pairs.Hedera’s HIP-632
system contract functions—isAuthorized
and isAuthorizedRaw—bridge
this gap by enabling on-chain verification of both ED25519 and ECDSA signatures. This ensures you can extend
Hedera-native security features into EVM-compatible smart contracts without compromising trust boundaries or
functionality.
Bridging ED25519 Accounts with Solidity
Hedera’s ED25519 accounts are incompatible with Solidity’s ECRECOVER
function, which supports ECDSA. To enable seamless integration, HIP-632 introduces two key system contract
functions:
isAuthorizedRaw:
Validates a single raw ED25519 signature.
isAuthorized:
Validates multiple signatures or threshold key configurations, supporting multi-sig and advanced key
schemes.
These functions allow you to enforce the same account security models on-chain within smart contracts.Basic Example: Validating a Single ED25519 SignatureHere’s a Solidity example for validating ED25519 signatures with isAuthorizedRaw. It calls the Hedera Account Service system contract at 0x16a through a typed interface and returns the function’s result.
isAuthorizedRaw and isAuthorized report an invalid signature through their return values, not by reverting. Always check the returned values. A low-level call that only checks the call’s success flag accepts forged signatures.
// SPDX-License-Identifier: Apache-2.0pragma solidity ^0.8.24;interface IHederaAccountService { function isAuthorizedRaw(address account, bytes memory messageHash, bytes memory signature) external returns (bool authorized); function isAuthorized(address account, bytes memory message, bytes memory signature) external returns (int64 responseCode, bool authorized);}contract ED25519Verifier { IHederaAccountService internal constant HAS = IHederaAccountService(address(0x16a)); int64 internal constant SUCCESS = 22; // Returns true only if the 64-byte ED25519 signature over messageHash is valid for the account's key function verifyED25519Signature(address account, bytes32 messageHash, bytes calldata signature) public returns (bool) { return HAS.isAuthorizedRaw(account, abi.encodePacked(messageHash), signature); }}
Use Case: Validate ED25519 signatures on-chain to ensure that only authorized
accounts execute sensitive operations.
Integrating Multi-Sig and Threshold Keys On-Chain
Hedera’s account model supports multi-sig and threshold key configurations. You can replicate these models
on-chain with isAuthorized
for robust access control.Example: On-Chain Multi-Sig VerificationThis example demonstrates requiring multiple valid signatures for critical contract actions:
// Add to the ED25519Verifier contract above.// signatureMap is a serialized protobuf SignatureMap with one signature per key.function validateMultiSig(address account, bytes memory proposalData, bytes memory signatureMap) public returns (bool){ (int64 responseCode, bool authorized) = HAS.isAuthorized(account, proposalData, signatureMap); return responseCode == SUCCESS && authorized;}
Use Case: Ideal for governance scenarios like DAOs where multiple stakeholders
must approve actions.Advanced Example: Executing a DAO Proposal with Threshold KeysIn more complex scenarios, like DAOs, you can combine multi-sig verification with actionable contract logic to
enforce threshold-based governance processes:
function executeProposal(address daoAccount, bytes memory proposalData, bytes memory signatures) public { require(validateMultiSig(daoAccount, proposalData, signatures), "Invalid signatures"); // Execute the proposal logic here}
This ensures that even on-chain actions that modify state or issue tokens adhere to your established
threshold-based governance processes.
Key Updates and isAuthorized
isAuthorized checks the account’s key at the time of the call. If an ED25519 account’s keys are updated with CryptoUpdateTransaction, contracts that verify the account through isAuthorized accept signatures from the new keys without being redeployed.ECDSA accounts are different. A key update does not change an ECDSA account’s EVM Address from Public Key: that address is immutable and stays bound to the original ECDSA public key. After the update, the account cannot send JSON-RPC transactions with either key, and ecrecover checks against the address still accept the old key. To replace a compromised ECDSA key, create a new ECDSA account and migrate assets and state. See Accounts, Signature Verification & Keys.