multiversx-crypto-verification

Cryptographic operations in MultiversX smart contracts. Use when hashing data (SHA256, Keccak256, RIPEMD160), verifying signatures (Ed25519, secp256k1, secp256r1, BLS), or encoding signatures in on-chain logic.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "multiversx-crypto-verification" with this command: npx skills add multiversx/mx-ai-skills/multiversx-mx-ai-skills-multiversx-crypto-verification

MultiversX Crypto Verification — self.crypto() API Reference

Complete reference for hashing and signature verification in MultiversX smart contracts (SDK v0.64+).

Hashing Functions

All hashing functions take &ManagedBuffer (or anything that borrows as ManagedBuffer) and return a fixed-size ManagedByteArray.

MethodReturn TypeOutput SizeUse Case
.sha256(data)ManagedByteArray<A, 32>32 bytesGeneral purpose hashing, Merkle trees
.keccak256(data)ManagedByteArray<A, 32>32 bytesEthereum compatibility, EIP-712
.ripemd160(data)ManagedByteArray<A, 20>20 bytesBitcoin address derivation (rare)
// Hash a message
let message = ManagedBuffer::from("data to hash");
let hash: ManagedByteArray<Self::Api, 32> = self.crypto().sha256(&message);

// Hash for Ethereum compatibility
let eth_hash = self.crypto().keccak256(&abi_encoded_data);

Signature Verification

Critical Distinction: Panic vs Bool

Panic-based — Transaction fails immediately on invalid signature. No error handling possible. Use when invalid signature = unauthorized action.

Bool-based — Returns true/false. Contract continues execution. Use when you need graceful error handling or multiple verification attempts.

MethodReturnsOn Invalid Signature
verify_ed25519(key, message, signature)()Panics — tx fails with "invalid signature"
verify_bls(key, message, signature)()Panics
verify_secp256r1(key, message, signature)()Panics
verify_bls_signature_share(key, message, signature)()Panics
verify_bls_aggregated_signature(keys, message, signature)()Panics
verify_secp256k1(key, message, signature)boolReturns false
verify_custom_secp256k1(key, message, signature, hash_type)boolReturns false

Method Signatures

// Panic-based (no return value)
fn verify_ed25519(
    &self,
    key: &ManagedBuffer<A>,       // 32-byte public key
    message: &ManagedBuffer<A>,   // arbitrary message
    signature: &ManagedBuffer<A>, // 64-byte signature
)

fn verify_bls(
    &self,
    key: &ManagedBuffer<A>,       // 96-byte BLS public key
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>, // 48-byte BLS signature
)

fn verify_secp256r1(
    &self,
    key: &ManagedBuffer<A>,       // 33 or 65-byte public key
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
)

fn verify_bls_signature_share(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
)

fn verify_bls_aggregated_signature(
    &self,
    keys: &ManagedVec<A, ManagedBuffer<A>>,  // list of BLS public keys
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,             // aggregated signature
)

// Bool-based
fn verify_secp256k1(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,  // DER-encoded or raw (min 2 bytes)
) -> bool

fn verify_custom_secp256k1(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
    hash_type: MessageHashType,    // how the message was hashed
) -> bool

MessageHashType Enum

Used with verify_custom_secp256k1 to specify how the message was pre-hashed:

pub enum MessageHashType {
    ECDSAPlainMsg,      // Message is not hashed (raw)
    ECDSASha256,        // Message was SHA-256 hashed
    ECDSADoubleSha256,  // Message was double SHA-256 hashed (Bitcoin)
    ECDSAKeccak256,     // Message was Keccak-256 hashed (Ethereum)
    ECDSARipemd160,     // Message was RIPEMD-160 hashed
    ECDSABlake2b,       // Message was Blake2b hashed
}

DER Signature Encoding

Convert raw (r, s) components to DER format for secp256k1:

fn encode_secp256k1_der_signature(
    &self,
    r: &ManagedBuffer<A>,  // 32-byte r component
    s: &ManagedBuffer<A>,  // 32-byte s component
) -> ManagedBuffer<A>      // DER-encoded signature

Algorithm Selection Guide

AlgorithmWhen to Use
Ed25519MultiversX native signatures. Verify user/SC signatures from the chain. Default choice.
secp256k1Ethereum/Bitcoin compatibility. Bridge contracts, cross-chain verification.
secp256r1NIST P-256 / WebAuthn / Apple Secure Enclave. Passkey-based auth.
BLSValidator signatures, multi-sig aggregation, threshold schemes.
BLS aggregatedVerify a single aggregated signature from multiple validators.

Common Patterns

Ed25519 Signature Gate (MultiversX Native)

#[endpoint(executeWithSignature)]
fn execute_with_signature(
    &self,
    data: ManagedBuffer,
    signature: ManagedBuffer,
) {
    let signer = self.trusted_signer().get();
    // Panics if invalid — tx reverts automatically
    self.crypto().verify_ed25519(
        &signer,
        &data,
        &signature,
    );
    // Only reached if signature is valid
    self.process_data(&data);
}

Ethereum Signature Verification (Graceful)

#[endpoint(verifyEthSignature)]
fn verify_eth_signature(
    &self,
    key: ManagedBuffer,
    message: ManagedBuffer,
    signature: ManagedBuffer,
) -> bool {
    // Returns bool — handle failure gracefully
    let valid = self.crypto().verify_custom_secp256k1(
        &key,
        &message,
        &signature,
        MessageHashType::ECDSAKeccak256,
    );
    require!(valid, "Invalid Ethereum signature");
    valid
}

Multi-Validator BLS Aggregated Check

#[endpoint(verifyValidators)]
fn verify_validators(
    &self,
    validator_keys: ManagedVec<ManagedBuffer>,
    message: ManagedBuffer,
    aggregated_sig: ManagedBuffer,
) {
    // Panics if aggregated signature is invalid
    self.crypto().verify_bls_aggregated_signature(
        &validator_keys,
        &message,
        &aggregated_sig,
    );
}

Hash-Based Commit-Reveal

#[endpoint(commit)]
fn commit(&self, hash: ManagedByteArray<Self::Api, 32>) {
    let caller = self.blockchain().get_caller();
    self.commitments(&caller).set(hash);
}

#[endpoint(reveal)]
fn reveal(&self, value: ManagedBuffer) {
    let caller = self.blockchain().get_caller();
    let stored_hash = self.commitments(&caller).get();
    let computed_hash = self.crypto().sha256(&value);
    require!(stored_hash == computed_hash, "Hash mismatch");
    self.commitments(&caller).clear();
    self.process_reveal(&caller, &value);
}

DER Encoding for secp256k1

// When you have raw r,s components (e.g., from an oracle)
let r = ManagedBuffer::from(&r_bytes[..]);
let s = ManagedBuffer::from(&s_bytes[..]);
let der_sig = self.crypto().encode_secp256k1_der_signature(&r, &s);

let valid = self.crypto().verify_secp256k1(&pubkey, &message, &der_sig);

Anti-Patterns

// BAD: Trying to catch Ed25519 failure — it panics, there's nothing to catch
let result = self.crypto().verify_ed25519(&key, &msg, &sig);
// ← verify_ed25519 returns (), not Result. If invalid, tx is already dead.

// GOOD: Use Ed25519 as a gate (panic is the intended behavior)
self.crypto().verify_ed25519(&key, &msg, &sig);
// Execution continues only if valid

// BAD: Using verify_secp256k1 without checking the bool
self.crypto().verify_secp256k1(&key, &msg, &sig);
// ← Compiles fine but ignores the result! Signature not actually checked.

// GOOD: Always check the bool return
let valid = self.crypto().verify_secp256k1(&key, &msg, &sig);
require!(valid, "Invalid signature");

// BAD: Using wrong hash type for Ethereum signatures
self.crypto().verify_custom_secp256k1(&key, &msg, &sig, MessageHashType::ECDSASha256);
// ← Ethereum uses Keccak256, not SHA256

// GOOD: Match the hash type to the chain
self.crypto().verify_custom_secp256k1(&key, &msg, &sig, MessageHashType::ECDSAKeccak256);

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

multiversx-blockchain-data

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

multiversx-defi-math

No summary provided by upstream source.

Repository SourceNeeds Review
General

multiversx-clarification-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

multiversx-protocol-experts

No summary provided by upstream source.

Repository SourceNeeds Review