# Signature Verification in Move

*[Documentation index](/llms.txt) · [Full index](/llms-full.txt)*

Move contracts in Sui support verifications for several signature schemes onchain. Not all signatures supported in onchain verification are supported as user signature verification. See [Sui Signatures](/develop/transactions/transaction-auth/auth-overview) for valid signature schemes for transaction authorization.

:::caution

This guide uses the [`fastcrypto`](https://github.com/MystenLabs/fastcrypto) CLI tool (`sigs-cli`) to create signatures of a given scheme. The CLI is for testing and debugging only and **must not** be used in production: it generates keys from fixed seeds, exposes secret keys on the command line and in shell history, and applies no domain separation. For production signing, sign with a vetted wallet, SDK, or HSM/TEE-backed signer, keep private keys outside of CLIs and logs, and bind every signed message to a domain separator and a nonce (or request ID) to prevent cross-context reuse and replay. See [Frontend and transaction signing](/develop/security/best-practices#frontend-and-transaction-signing) and [User and operator key management](/develop/security/best-practices#user-and-operator-key-management) for details.

:::

## Setup `fastcrypto` CLI binary

```sh
git@github.com:MystenLabs/fastcrypto.git
cd fastcrypto/
cargo build --bin sigs-cli
```

## Sign with CLI and submit to onchain Move method

### Ed25519 signature (64 bytes)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme ed25519 --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme ed25519 --msg $MSG --secret-key  $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the verify method in Move. All inputs are represented in bytes in hex format:

```move
    use sui::ed25519;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    let verify = ed25519::ed25519_verify(&sig, &pk, &msg);
    assert!(verify == true, 0);
```

### Secp256k1 non-recoverable signature (64 bytes)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme secp256k1 --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme secp256k1 --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the verify method in Move.

```move
    use sui::ecdsa_k1;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    // The last param 1 represents the hash function used is SHA256, the default hash function used when signing in CLI.
    let verify = ecdsa_k1::secp256k1_verify(&sig, &pk, &msg, 1);
    assert!(verify == true, 0);
```

### Secp256k1 recoverable signature (65 bytes)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme secp256k1-rec --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme secp256k1-rec --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the ecrecover method in Move and check equality.
```move
    use sui::ecdsa_k1;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    // The last param 1 represents the hash function used is SHA256, the default hash function used when signing in CLI.
    let recovered = ecdsa_k1::secp256k1_ecrecover(&sig, &msg, 1);
    assert!(pk == recovered, 0);
```

### Secp256r1 non-recoverable signature (64 bytes)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme secp256r1 --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme secp256r1 --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the verify method in Move.

```move
    use sui::ecdsa_r1;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    // The last param 1 represents the hash function used is SHA256, the default hash function used when signing in CLI.
    let verify = ecdsa_r1::secp256r1_verify(&sig, &pk, &msg, 1);
    assert!(verify == true, 0);
```

### Secp256r1 recoverable signature (65 bytes)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme secp256r1-rec --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme secp256r1-rec --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the ecrecover method in Move and check equality.

```move
    use sui::ecdsa_r1;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    // The last param 1 represents the hash function used is SHA256, the default hash function used when signing in CLI.
    let recovered = ecdsa_r1::secp256r1_ecrecover(&sig, &msg, 1);
    assert!(pk == recovered, 0);
```

### BLS G1 signature (48 bytes, minSig setting)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme bls12381-minsig --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme bls12381-minsig --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the verify method in Move.

```move
    use sui::bls12381;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    let verified = bls12381::bls12381_min_sig_verify(&sig, &pk, &msg);
    assert!(verified == true, 0);
```

### BLS G1 signature (96 bytes, minPk setting)

#### Step 1: Generate a key and sign a message.

```sh
target/debug/sigs-cli keygen --scheme bls12381-minpk --seed 0000000000000000000000000000000000000000000000000000000000000000
Private key in hex: $SK
Public key in hex: $PK

target/debug/sigs-cli sign --scheme bls12381-minpk --msg $MSG --secret-key $SK

Signature in hex: $SIG
Public key in hex: $PK
```

#### Step 2:Call the verify method in Move.

```move
    use sui::bls12381;

    let msg = x"$MSG";
    let pk = x"$PK";
    let sig = x"$SIG";
    let verified = bls12381::bls12381_min_pk_verify(&sig, &pk, &msg);
    assert!(verified == true, 0);
```
