---
# System prepended metadata

title: Untitled

---

For verifying signatures within a contract, the [Schnorrkel library](https://docs.rs/schnorrkel/latest/schnorrkel/) is utilized. This library provides support for Schnorr signatures using the Ristretto group, offering a robust framework for cryptographic operations. 

Imagine the format of the data to be signed as follows:

```rust
pub struct SignatureData {
    pub key: ActorId,
    pub duration: u64,
    pub allowed_actions: Vec<ActionsForSession>,
}
```

This structure includes a `key`, representing the unique identifier of an actor (e.g., a user or a system component), a `duration` indicating the validity period of the signature, and `allowed_actions`, a list of actions that the signer is permitted to perform within the session.

The contract receives the fields specified in the structure (`key`, `duration`, `allowed_actions`), the `signature` itself (a byte array), public key of the signer (`pub_key`)through a function like:

```rust
fn verify_signature(
    key: ActorId,
    duration: u64,
    allowed_actions: Vec<ActionsForSession>,
    signature: Vec<u8>,
) {}
```

To verify the signature, it's necessary first to reconstruct the payload that the user signed.
The user’s data is encapsulated within a struct, `SignatureData`, which includes essential fields such as `key`, `duration`, and `allowed_actions`. This struct is then serialized (encoded) into a byte format.
```rust
let message = SignatureData {
    key,
    duration,
    allowed_actions,
}.encode();

```
Following the serialization, the encoded message is framed with predefined prefixes and postfixes, <Bytes> and </Bytes>, respectively. This is essential since the operation is performed on the client side, requiring a consistent format for both the serialization and subsequent deserialization processes.
```rust
let mut combined_message = Vec::new();
combined_message.extend_from_slice(b"<Bytes>");
combined_message.extend_from_slice(&message);
combined_message.extend_from_slice(b"</Bytes>");
```
*Signature Verification*:
```rust
const SIGNING_CONTEXT: &[u8] = b"substrate";
fn verify_signature(
    key: ActorId,
    duration: u64,
    allowed_actions: Vec<ActionsForSession>,
    signature: Vec<u8>,
    pub_key: ActorId
) {
    ...
    
    // The signature and public key are converted from their byte representations.
    let signature = schnorrkel::Signature::from_bytes(&signature).expect("Invalid signature format");
    let pubkey_bytes: [u8; 32] = pub_key.into();
    let pub_key = schnorrkel::PublicKey::from_bytes(&pubkey_bytes).expect("Invalid public key format");
    
    // Verification against the signing context, ensuring the message integrity.
    pub_key.verify_simple(
        SIGNING_CONTEXT, 
        &combined_message, 
        &signature
    ).expect("Signature verification failed");
}

```
