# Crypto

The built-in contract `Crypto` can be used to perform cryptographic operations. The contract can be imported using `import Crypto`.

For example, to verify two signatures with equal weights for some signed data:

```
import Crypto

pub fun test main() {
    let keyList = Crypto.KeyList()

    let publicKeyA = Crypto.PublicKey(
        publicKey:
            "db04940e18ec414664ccfd31d5d2d4ece3985acb8cb17a2025b2f1673427267968e52e2bbf3599059649d4b2cce98fdb8a3048e68abf5abe3e710129e90696ca".decodeHex(),
        signatureAlgorithm: Crypto.ECDSA_P256
    )
    keyList.add(
        publicKeyA,
        hashAlgorithm: Crypto.SHA3_256,
        weight: 0.5
    )

    let publicKeyB = Crypto.PublicKey(
        publicKey:
            "df9609ee588dd4a6f7789df8d56f03f545d4516f0c99b200d73b9a3afafc14de5d21a4fc7a2a2015719dc95c9e756cfa44f2a445151aaf42479e7120d83df956".decodeHex(),
        signatureAlgorithm: Crypto.ECDSA_P256
    )
    keyList.add(
        publicKeyB,
        hashAlgorithm: Crypto.SHA3_256,
        weight: 0.5
    )

    let signatureSet = [
        Crypto.KeyListSignature(
            keyIndex: 0,
            signature:
                "8870a8cbe6f44932ba59e0d15a706214cc4ad2538deb12c0cf718d86f32c47765462a92ce2da15d4a29eb4e2b6fa05d08c7db5d5b2a2cd8c2cb98ded73da31f6".decodeHex()
        ),
        Crypto.KeyListSignature(
            keyIndex: 1,
            signature:
                "bbdc5591c3f937a730d4f6c0a6fde61a0a6ceaa531ccb367c3559335ab9734f4f2b9da8adbe371f1f7da913b5a3fdd96a871e04f078928ca89a83d841c72fadf".decodeHex()
        )
    ]

    // "foo", encoded as UTF-8, in hex representation
    let signedData = "666f6f".decodeHex()

    let isValid = keyList.isValid(
        signatureSet: signatureSet,
        signedData: signedData
    )
}
```

The API of the Crypto contract is:

```
pub contract Crypto {

    pub struct SignatureAlgorithm {
        pub let name: String
    }

    /// ECDSA_P256 is Elliptic Curve Digital Signature Algorithm (ECDSA) on the NIST P-256 curve
    pub let ECDSA_P256: SignatureAlgorithm

    /// ECDSA_Secp256k1 is Elliptic Curve Digital Signature Algorithm (ECDSA) on the secp256k1 curve
    pub let ECDSA_Secp256k1: SignatureAlgorithm

    pub struct HashAlgorithm {
        pub let name: String
    }

    /// SHA2_256 is Secure Hashing Algorithm 2 (SHA-2) with a 256-bit digest
    pub let SHA2_256: HashAlgorithm

    /// SHA3_256 is Secure Hashing Algorithm 3 (SHA-3) with a 256-bit digest
    pub let SHA3_256: HashAlgorithm

    pub struct PublicKey {
        pub let publicKey: [UInt8]
        pub let signatureAlgorithm: SignatureAlgorithm

        init(publicKey: [UInt8], signatureAlgorithm: SignatureAlgorithm)
    }

    pub struct KeyListEntry {
        pub let keyIndex: Int
        pub let publicKey: PublicKey
        pub let hashAlgorithm: HashAlgorithm
        pub let weight: UFix64
        pub let isRevoked: Bool

        init(
            keyIndex: Int,
            publicKey: PublicKey,
            hashAlgorithm: HashAlgorithm,
            weight: UFix64,
            isRevoked: Bool
        )
    }

    pub struct KeyList {

        init()

        /// Adds a new key with the given weight
        pub fun add(
            _ publicKey: PublicKey,
            hashAlgorithm: HashAlgorithm,
            weight: UFix64
        )

        /// Returns the key at the given index, if it exists.
        /// Revoked keys are always returned, but they have `isRevoked` field set to true
        pub fun get(keyIndex: Int): KeyListEntry?

        /// Marks the key at the given index revoked, but does not delete it
        pub fun revoke(keyIndex: Int)

        /// Returns true if the given signatures are valid for the given signed data
        pub fun isValid(
            signatureSet: [KeyListSignature],
            signedData: [UInt8]
        ): Bool
    }

    pub struct KeyListSignature {
        pub let keyIndex: Int
        pub let signature: [UInt8]

        pub init(keyIndex: Int, signature: [UInt8])
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-daunarovich.gitbook.io/flow-network/introduction/crypto.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
