Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You can just clone this repository and run the following commands:

```shell
$ npm install
$ task serve
$ npm run start
```

You will now be able to visit the locally served website at http://localhost:3000/
Expand Down
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ tasks:
- cmd: rm -rf .docusaurus
- cmd: rm -rf build

serve:
start:
desc: Start server locally
cmds:
- task: clean
Expand Down
8 changes: 8 additions & 0 deletions docs/core/standard-library/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Standard library",
"position": 4,
"link": {
"type": "doc",
"id": "standard-library"
}
}
8 changes: 8 additions & 0 deletions docs/core/standard-library/cryptography/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Cryptography",
"position": 2,
"link": {
"type": "doc",
"id": "cryptography"
}
}
65 changes: 65 additions & 0 deletions docs/core/standard-library/cryptography/bls12-381.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
sidebar_position: 4
---

# 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] 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.

## Verify on G1

Signature verification with public key in G1:

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: Bls12VerifyMsg,
) -> StdResult<QueryResponse> {
// Verify the signature. On chain!
let msg_hash = deps.api.bls12_381_hash_to_g2(HashFunction::Sha256, &msg.msg, &msg.dst)?;
let is_valid = deps.api.bls12_381_pairing_equality(&BLS12_381_G1_GENERATOR, &msg.signature, &msg.pubkey, &msg_hash)?;
let response = to_json_binary(&VerifyResponse {
is_valid
})?;

Ok(response)
}
```

## Verify on G2

Signature verification with public key in G2 (See
https://hackmd.io/@benjaminion/bls12-381#Verification in combination with
https://hackmd.io/@benjaminion/bls12-381#Swapping-G1-and-G2):

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: Bls12VerifyMsg,
) -> StdResult<QueryResponse> {
// Verify the signature. On chain!
let msg_hash = deps.api.bls12_381_hash_to_g1(HashFunction::Sha256, &msg.msg, &msg.dst)?;
let is_valid = deps.api.bls12_381_pairing_equality(&msg.signature, &BLS12_381_G2_GENERATOR, &msg_hash, &msg.pubkey)?;
let response = to_json_binary(&VerifyResponse {
is_valid
})?;

Ok(response)
}
```

[drand]: https://drand.love
75 changes: 75 additions & 0 deletions docs/core/standard-library/cryptography/cryptography.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 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

:::tip

Note that these values are in CosmWasm Gas (which is not equivalent to Cosmos SDK Gas; rather,
CosmWasm Gas is eventually converted to Cosmos SDK Gas). For more info on gas [check this page].

:::

### 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].

## 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 maintenance

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.

[check this page]: ../../architecture/gas
[source code]: https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/src/environment.rs#L62-L101
39 changes: 39 additions & 0 deletions docs/core/standard-library/cryptography/ed25519.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
sidebar_position: 1
---

# 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], the API we offer follows
[ZIP215]. This means you will have no issues with signatures being valid in one place and invalid in
another.

## Example

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: Ed25519VerifyMsg,
) -> StdResult<QueryResponse> {
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 = to_json_binary(&VerifyResponse {
is_valid
})?;

Ok(response)
}
```

[have issues with inconsistent validation criteria]: https://hdevalence.ca/blog/2020-10-04-its-25519am
[ZIP215]: https://zips.z.cash/zip-0215
60 changes: 60 additions & 0 deletions docs/core/standard-library/cryptography/k256.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: K-256
sidebar_position: 3
---

# 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 title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: EcdsaVerifyMsg,
) -> StdResult<QueryResponse> {
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 = to_json_binary(&VerifyResponse {
is_valid
})?;

Ok(response)
}
```

### Public key recovery

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: EcdsaRecoverMsg,
) -> StdResult<QueryResponse> {
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 response = to_json_binary(&RecoveryResponse {
public_key: public_key.into(),
})?;

Ok(response)
}
```
57 changes: 57 additions & 0 deletions docs/core/standard-library/cryptography/p256.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: P-256
sidebar_position: 2
---

# 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

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: EcdsaVerifyMsg,
) -> StdResult<QueryResponse> {
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.secp256r1_verify(&message_hash, &signature, &public_key)?;
let response = to_json_binary(&VerifyResponse {
is_valid
})?;

Ok(response)
}
```

### Public key recovery

```rust title="contract.rs"
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
deps: Deps,
_env: Env,
msg: EcdsaRecoverMsg,
) -> StdResult<QueryResponse> {
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.secp256r1_recover_pubkey(&message_hash, &signature, recovery_id)?;
let response = to_json_binary(&RecoveryResponse {
public_key: public_key.into(),
})?;

Ok(response)
}
```
8 changes: 8 additions & 0 deletions docs/core/standard-library/math/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Math",
"position": 1,
"link": {
"type": "doc",
"id": "math"
}
}
37 changes: 37 additions & 0 deletions docs/core/standard-library/math/decimals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
sidebar_position: 1
---

# Decimals

CosmWasm offers decimal types for handling fractional numbers.

In contrast to floating point numbers, these datatypes do not suffer from the same precision issues.
This means that these decimal types are safe for use in financial calculations.

Instead of storing numbers in the floating point format, which gives it a _floating_ amount of
decimal places, these decimal types have a fixed precision of 18 decimal places.

:::tip

Note that, due to how the decimal types are structured, the value ranges can seem a little weird.

For example, 128-bit unsigned decimal value $1.0$ is represented by `Decimal(1_000_000_000_000_000_000)`.

The maximal value of the 128-bit unsigned decimal is:
$$
{2^{128} - 1 \over 10^{18}} = 340282366920938463463.374607431768211455
$$

In practice, you don't really have to think about it, but it's something you should be aware of.

:::

Decimal types come in the following variants:

| Length | Unsigned | Signed |
|---------|------------|------------------|
| 128-bit | Decimal | SignedDecimal |
| 256-bit | Decimal256 | SignedDecimal256 |

Choose one of the types according to your needs and off you go!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading