Skip to main content
OpenGDP uses battle-tested primitives that match EVM execution, while keeping native chain commitments verifiable and compact. This section describes the hashing functions, keys and signatures, how addresses are derived, and how messages and transactions are signed.

Hashing Algorithms

Keccak-256 (legacy SHA-3 variant)

  • Where it is used: EVM state (Merkle-Patricia tries), log topics, transaction and message hashing for signatures, address derivation, and EIP-55 address checksums.
  • Why: Exact parity with Ethereum behavior and tooling.

SHA-256

  • Where it is used: Native chain commitments such as IAVL sub-trees and the top-level Merkle commitments described in the State Model.
  • Why: Efficient, widely audited, and standard for Merkleized structures outside the EVM.
  • Note: Keccak-256 and NIST SHA3-256 are not bit-for-bit identical. OpenGDP uses Keccak-256 for all EVM-compatible paths to preserve compatibility.

The secp256k1 Elliptic Curve

OpenGDP uses ECDSA over the secp256k1 curve for account keys and signatures.
  • Private key: 32-byte integer d[1,n1]d \in [1, n-1], where nn is the curve order.
  • Public key: Point Q=dGQ = d \cdot G on the curve. For EVM operations, we use the uncompressed 65-byte form 0x04 || X || Y.
  • Signatures: Tuple (r,s)(r, s) plus a 1-byte recovery id vv that enables public-key recovery (ecrecover). OpenGDP enforces low-S normalization sn/2s \leq n/2 to prevent malleability.

Address Generation from Public Keys

OpenGDP follows Ethereum’s 20-byte address format for EVM accounts.

Externally Owned Account (EOA) address

  • Take the uncompressed public key bytes without the 0x04 prefix: pubkey[1:] (64 bytes).
  • Compute keccak256(pubkey[1:]).
  • The address is the last 20 bytes of that hash.
  • Display as hex with 0x prefix and optional EIP-55 mixed-case checksum.
address = last20( keccak256( uncompressed_pubkey[1:] ) )

Contract address

  • CREATE: address = last20( keccak256( RLP(sender_address, sender_nonce) ) )
  • CREATE2: address = last20( keccak256( 0xff || sender_address || salt || keccak256(init_code) ) )
In both cases, the address is deterministic given the inputs; no private key “owns” a contract address.

The Two Types of Address

  • Externally Owned Accounts (EOA)
    • Controlled by a private key on secp256k1.
    • Can send transactions, pay gas, and initiate contract calls.
    • Nonce increases with each successful transaction.
  • Contract Accounts
    • Code lives at the address and is executed when called.
    • Have persistent storage and can hold balances.
    • Cannot initiate transactions by themselves; they react to calls from EOAs or other contracts.
Both are 20-byte addresses and use the same display format and checksum rules.

Signing Methods

All signing uses ECDSA over secp256k1 with Keccak-256 as the message hash. OpenGDP preserves JSON-RPC semantics from Geth, so existing wallets and libraries work out of the box.

Transaction Signing (with replay protection)

OpenGDP supports legacy and typed Ethereum transactions. The signable payload is the canonical, chain-id-aware encoding of the transaction fields.
  • Hash to sign: keccak256( tx_signing_payload )
  • Signature: (r,s,v)(r,s,v) where:
    • r,sr,s are ECDSA scalars with low-S normalization.
    • vv encodes parity and the chain id. Wallets may present vv as 0/10/1, 27/2827/28, or 35+2×chainId+parity35 + 2 \times chainId + parity depending on type; OpenGDP accepts standard encodings.
  • Submission: The signed blob is sent via eth_sendRawTransaction.
  • Recovery): Nodes use ecrecover(hash, v, r, s) to recover the public key and verify the sender address.

Security properties

  • Replay protection: Chain-id binding prevents cross-chain replays.
  • Non-malleability: Low-S rule plus consensus validation rejects malleated signatures.

Personal Message Signing (EIP-191)

Used for human-readable messages, off-chain attestations, and wallet prompts such as personal_sign.
  • Prefixing (domain separation): "\x19Ethereum Signed Message:\n" || len(msg) || msg
  • Hash to sign: keccak256( prefixed_message )
  • Verify/recover: Same ecrecover flow as transactions.