diff --git a/docs-test-gen/templates/core.tpl b/docs-test-gen/templates/core.tpl
index e6703496..6ccd0771 100644
--- a/docs-test-gen/templates/core.tpl
+++ b/docs-test-gen/templates/core.tpl
@@ -12,6 +12,27 @@ struct InstantiateMsg {}
#[cw_serde]
struct QueryMsg {}
+#[cw_serde]
+struct EcdsaRecoverMsg {
+ message_hash: Binary,
+ signature: Binary,
+ recovery_id: u8,
+}
+
+#[cw_serde]
+struct EcdsaVerifyMsg {
+ message_hash: Binary,
+ signature: Binary,
+ public_key: Binary,
+}
+
+#[cw_serde]
+struct Ed25519VerifyMsg {
+ public_key: Binary,
+ message: Binary,
+ signature: Binary,
+}
+
#[cw_serde]
struct ExecuteMsg {}
diff --git a/src/pages/core/standard-library.mdx b/src/pages/core/standard-library.mdx
index c1ec4c04..7c34891c 100644
--- a/src/pages/core/standard-library.mdx
+++ b/src/pages/core/standard-library.mdx
@@ -5,3 +5,10 @@ tags: ["core"]
import { Callout } from "nextra/components";
# Standard Library
+
+CosmWasm offers a standard library providing a bunch of different components to
+write smart contracts. In this section we will go over some components and
+functionality the standard library offers.
+
+A full list of all components along with documentation can be found
+[on docs.rs](https://docs.rs/cosmwasm-std).
diff --git a/src/pages/core/standard-library/cryptography.mdx b/src/pages/core/standard-library/cryptography.mdx
index 188ef5af..32c22a6e 100644
--- a/src/pages/core/standard-library/cryptography.mdx
+++ b/src/pages/core/standard-library/cryptography.mdx
@@ -1,7 +1,82 @@
---
-tags: ["core"]
+tags: ["core", "cryptography"]
---
import { Callout } from "nextra/components";
# Cryptography
+
+CosmWasm offers cryptographic primitives that are implemented as VM intrinsics.
+This means that they are more efficient than implementations in contract code
+could be, saving you gas and code size. In some cases they are also _impossible_
+to implement in contract code, since some of them require a random intermediate
+value and randomness is generally not exposed to contracts to ensure
+deterministic execution.
+
+In the sidebar, you can find all the supported algorithms/curves along with
+documentation about them.
+
+## Gas costs
+
+
+ Note that these values are in CosmWasm Gas (which is very much different from
+ Cosmos SDK Gas). For more info on gas, [check this
+ document](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).
+
+
+### secp256k1
+
+- Verify: 96_000_000 gas
+- Recover public key: 194_000_000 gas
+
+### secp256r1
+
+- Verify: 279_000_000 gas
+- Recover public key: 592_000_000 gas
+
+### ed25519
+
+- Verify: 35_000_000 gas
+- Batch verify (multiple signatures; multiple keys):
+ - Base: 24_000_000 gas
+ - Per signature/key pair: 21_000_000 gas
+- Batch verify (multiple signatures; one key):
+ - Base: 36_000_000 gas
+ - Per signature: 10_000_000 gas
+
+### BLS12-381
+
+- Aggregate points to G1:
+ - Base: 68_000_000 gas
+ - Per point: 12_000_000 gas
+- Aggregate points to G2:
+ - Base: 103_500_000 gas
+ - Per point: 24_500_000 gas
+- Hash to G1: 563_000_000 gas
+- Hash to G2: 871_000_000 gas
+- Pairing equality:
+ - Base: 2_112_000_000 gas
+ - Per item: 163_000_000 gas
+
+You can also check these numbers in the
+[source code](https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/src/environment.rs#L62-L101).
+
+## Note on hash functions
+
+You'll notice that CosmWasm does not implement any hash functions as native
+functions, and we intend to keep it that way. The reasoning for that is:
+
+- Hash functions are pretty much always cheap in terms of execution cost _and_
+ code size
+- There are way too many hash functions out there, adding one would open the
+ floodgates where we would have to add more
+ - SHA-3 family, Keccak256, cSHAKE256, BLAKE2, BLAKE3, SHA-2 family,
+ KangarooTwelve, etc. (and this is just a small sample set to drive the point
+ home)
+- Benchmarking and pricing functions (and keeping those up-to-date) correctly is
+ a lot of work
+- We want to keep the API surface as small as possible for ease of maintainance
+
+Keep in mind that, thanks to Wasm being our execution environment, contract
+execution is quite fast. In most cases the perceived need to move hashing into a
+host function is premature optimization and not actually needed.
diff --git a/src/pages/core/standard-library/cryptography/_meta.json b/src/pages/core/standard-library/cryptography/_meta.json
new file mode 100644
index 00000000..d6c0be33
--- /dev/null
+++ b/src/pages/core/standard-library/cryptography/_meta.json
@@ -0,0 +1,6 @@
+{
+ "ed25519": "Ed25519",
+ "p256": "P-256",
+ "k256": "K-256",
+ "bls12-381": "BLS12-381"
+}
diff --git a/src/pages/core/standard-library/cryptography/bls12-381.mdx b/src/pages/core/standard-library/cryptography/bls12-381.mdx
new file mode 100644
index 00000000..b1eebc21
--- /dev/null
+++ b/src/pages/core/standard-library/cryptography/bls12-381.mdx
@@ -0,0 +1,23 @@
+---
+tags: ["core", "cryptography"]
+---
+
+import { Callout } from "nextra/components";
+
+# BLS12-381
+
+BLS12-381 is a bit of a special curve. It is a pairing-friendly curve, allowing
+for fun things such as aggregated signatures. At the moment, CosmWasm only
+supports signature verifications. In the future we might add support for
+zero-knowledge proofs on this curve.
+
+Common examples where this curve is used are Ethereum block-headers and [drand](https://drand.love/)
+randomness beacons.
+
+## Example
+
+CosmWasm offers a byte-oriented API for signature verification. This API also
+doesn't care whether the public key is part of the G1 or G2 group (same for the
+other components). They just have to somehow fit together.
+
+TODO: Add example as soon as BLS12-381 is properly released
diff --git a/src/pages/core/standard-library/cryptography/ed25519.mdx b/src/pages/core/standard-library/cryptography/ed25519.mdx
new file mode 100644
index 00000000..927762ad
--- /dev/null
+++ b/src/pages/core/standard-library/cryptography/ed25519.mdx
@@ -0,0 +1,38 @@
+---
+tags: ["core", "cryptography"]
+---
+
+import { Callout } from "nextra/components";
+
+# Ed25519
+
+CosmWasm offers an API to verify and batch verify Ed25519 signatures. This is
+powerful, especially since batch verifications require a random component which
+is impossible to implement in contract code.
+
+Ed25519 is known to
+[have issues with inconsistent validation criteria](https://hdevalence.ca/blog/2020-10-04-its-25519am),
+the API we offer follows [ZIP215](https://zips.z.cash/zip-0215). This means you
+will have no issues with signatures being valid in one place and invalid in
+another.
+
+## Example
+
+```rust filename="contract.rs" template="core"
+#[entry_point]
+pub fn query(
+ deps: Deps,
+ _env: Env,
+ msg: Ed25519VerifyMsg,
+) -> StdResult {
+ let public_key = msg.public_key;
+ let signature = msg.signature;
+ let message = msg.message;
+
+ // Verify the signature. On chain!
+ let is_valid = deps.api.ed25519_verify(&message, &signature, &public_key)?;
+ let response = format!("{{ \"is_valid\": {is_valid} }}");
+
+ Ok(QueryResponse::new(response.into_bytes()))
+}
+```
diff --git a/src/pages/core/standard-library/cryptography/k256.mdx b/src/pages/core/standard-library/cryptography/k256.mdx
new file mode 100644
index 00000000..eb363dbe
--- /dev/null
+++ b/src/pages/core/standard-library/cryptography/k256.mdx
@@ -0,0 +1,58 @@
+---
+tags: ["core", "cryptography"]
+---
+
+import { Callout } from "nextra/components";
+
+# K256 (secp256k1)
+
+K256 is a Koblitz curve that is widely used in the blockchain space (e.g. Bitcoin and Ethereum). CosmWasm
+offers the following APIs:
+
+- Signature verification
+- Public key recovery
+
+## Example
+
+### Signature verification
+
+```rust filename="contract.rs" template="core"
+#[entry_point]
+pub fn query(
+ deps: Deps,
+ _env: Env,
+ msg: EcdsaVerifyMsg,
+) -> StdResult {
+ let public_key = msg.public_key;
+ let signature = msg.signature;
+ let message_hash = msg.message_hash;
+
+ // Verify the signature. On chain!
+ let is_valid = deps.api.secp256k1_verify(&message_hash, &signature, &public_key)?;
+ let response = format!("{{ \"is_valid\": {is_valid} }}");
+
+ Ok(QueryResponse::new(response.into_bytes()))
+}
+```
+
+### Public key recovery
+
+```rust filename="contract.rs" template="core"
+#[entry_point]
+pub fn query(
+ deps: Deps,
+ _env: Env,
+ msg: EcdsaRecoverMsg,
+) -> StdResult {
+ let signature = msg.signature;
+ let message_hash = msg.message_hash;
+ let recovery_id = msg.recovery_id;
+
+ // Recover the public key. On chain!
+ let public_key = deps.api.secp256k1_recover_pubkey(&message_hash, &signature, recovery_id)?;
+ let public_key = HexBinary::from(public_key).to_hex();
+ let response = format!("{{ \"public_key\": \"{public_key}\" }}");
+
+ Ok(QueryResponse::new(response.into_bytes()))
+}
+```
diff --git a/src/pages/core/standard-library/cryptography/p256.mdx b/src/pages/core/standard-library/cryptography/p256.mdx
new file mode 100644
index 00000000..21254c4d
--- /dev/null
+++ b/src/pages/core/standard-library/cryptography/p256.mdx
@@ -0,0 +1,17 @@
+---
+tags: ["core", "cryptography"]
+---
+
+import { Callout } from "nextra/components";
+
+# P256 (secp256r1)
+
+P256 is one of NIST's prime-order elliptic curves. You may need this curve to
+implement protocols such as WebAuthn. This is the main reason this curve was
+added to CosmWasm.
+
+## Example
+
+## Signature verification
+
+TODO: Add example as soon as secp256r1 is properly released