Skip to content

Commit

Permalink
Merge pull request #32 from ideal-lab5/feat/update
Browse files Browse the repository at this point in the history
Feat/update
  • Loading branch information
driemworks authored Nov 22, 2024
2 parents 49f9d1e + 32c12f8 commit ab46271
Show file tree
Hide file tree
Showing 14 changed files with 917 additions and 622 deletions.
305 changes: 99 additions & 206 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 17 additions & 9 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "murmur-core"
version = "0.1.0"
edition = "2021"
description = "Murmur core"
description = "The core implementation of the Murmur protocol"
documentation = "https://docs.rs/murmur-core"
readme = "README.md"
keywords = ["crypto", "wallet", "keyless"]
Expand All @@ -21,36 +21,44 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
totp-rs = { version = "5.5.1", default-features = false, optional = true }
codec = { package = "parity-scale-codec", version = "3.6.12", features = ["derive"], default-features = false }
etf-crypto-primitives = { git = "https://github.com/ideal-lab5/etf-sdk/", branch = "dev", default-features = false}
timelock = { git = "https://github.com/ideal-lab5/timelock.git", default-features = false }
ckb-merkle-mountain-range = { version = "0.5.2", default-features = false }
sha3 = { version = "0.10.8", default-features = false }
serde = { version = "1.0.188", features = ["alloc", "derive"], default-features = false}
serde = { version = "1.0.188", features = ["alloc", "derive"], default-features = false }
ark-bls12-377 = { version = "0.4.0", default-features = false }
ark-std = { version = "0.4.0", default-features = false }
ark-serialize = { version = "0.4.0", default-features = false }
w3f-bls = { version = "0.1.3", default-features = false }
w3f-bls = { version = "0.1.4", default-features = false }
zeroize = { version = "1.8.1", default-features = false }
rand_chacha = { version = "0.3.1" }
ark-ec = { version = "0.4", default-features = false }
ark-ff = { version = "0.4", default-features = false }
dleq_vrf = { git = "https://github.com/w3f/ring-vrf.git", default-features = false }
ark-transcript = { git = "https://github.com/w3f/ring-vrf.git", default-features = false }

[dev-dependencies]
rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false }
hkdf = "0.12.4"
rand_chacha = { version = "0.3.1" }
rand_core = { version = "0.6.4" }

[features]
default = ["client"]
std = [
"ark-std/std",
"ark-serialize/std",
"ark-bls12-377/std",
"ark-ec/std",
"ark-ff/std",
"ark-transcript/std",
"dleq_vrf/std",
"w3f-bls/std",
"serde/std",
"ckb-merkle-mountain-range/std",
"codec/std",
"etf-crypto-primitives/std",
"timelock/std",
"sha3/std",
"ckb-merkle-mountain-range/std",
"zeroize/std",
]
no_std = []
client = [
"totp-rs",
"dleq_vrf/getrandom"
]
102 changes: 99 additions & 3 deletions core/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,104 @@
# Murmur Core

This library contains the core implementation of the murmur protocol. This implementation can support both BLS12-377 and BLS12-381, but is left curve-agnostic, only expecting that the beacon is produced by an ETF-PFG instance.
This library contains the core implementation of the Murmur protocol. This implementation can support both BLS12-377 and BLS12-381, but is left curve-agnostic. This crate can support the randomness beacon produced by the [Ideal Network](https://idealabs.network) as well as [Drand](https://drand.love)'s Quicknet. In general, this library is intended to work with a blockchain whose runtime includes the corresponding [Murmur Pallet](https://github.com/ideal-lab5/idn-sdk/tree/main/pallets/murmur). More specifcially, it is intended to run against the [Ideal Network](https://idealabs.network). For examples of usage against the Ideal Network, refer to the [CLI](../lib/src/bin/murmur/main.rs).

## Usage

### Create, Update, Execute

To create and update murmur wallets, you must define an `IdentityBuilder`. The [BasicIdentityBuilder](../lib/src/lib.rs) struct implements allows for the construction of valid identities on the Ideal Network. In the future, we will add support for Drand's Quicknet as well.

#### Create a Murmur Store

``` rust
use ark_serialize::CanonicalDeserialize;
use ark_std::rand::SeedableRng;
use rand_chacha::ChaCha20Rng;
use rand_core::OsRng;
use murmur_core::{
murmur::{EngineTinyBLS377, Error, MurmurStore},
};
use w3f_bls::{DoublePublicKeyScheme, KeypairVT, TinyBLS377};

// This simulates the production of a randomness beacon public key
// In practice, this would be fetched from the beacon (e.g. as a hex string) and must be deseraialized
let keypair = KeypairVT::<TinyBLS377>::generate(&mut rng);
let double_public: DoublePublicKey<TinyBLS377> =
DoublePublicKey(keypair.into_public_key_in_signature_group().0, keypair.public.0);

// The 'lifetime' of the Murmur wallet for the given session
// This corresponds to future rounds of the randomness beacon
// for which timelocked commitments can be made
let schedule = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

// This is your 'secret' seed, a short password used while constructing OTP codes
let seed = vec![1, 2, 3];

// The nonce functions similarly to nonce's for standard accounts, except instead of updating on a
// "per transaction" basis, it only updates on a "per session" basis
//
let nonce = 0;

let murmur_store = MurmurStore::<EngineTinyBLS377>::new::<
BasicIdentityBuilder,
OsRng,
ChaCha20Rng,
>(seed.clone(), schedule.to_vec(), nonce, double_public, &mut rng)
.unwrap();
```
#### Update a Murmur Store

Updating a Murmur store is done by calling the same `new` function as above and incrementing the previous nonce by 1. The data any single MMR can contain is finite, so when a Murmur wallet is created it can only be functional for a finite number of blocks (the block schedule). In this sense, Murmur is a "session-based" wallet. To ensure wallet lifetimes can be extended, Murmur wallets can be updated by generating a new Murmur store and submitting the result to a system that implements a verifier (see below). More specifically, when a Murmur store is created a DLEQ proof is generated (Discrete Log Equivalence Proof - a type of zkp) and attached to the store. This proof allows the Murmur store creator to convince a verifier that it knows the secret input (seed) without exposing it.

``` rust
// Compute the next nonce
let nonce = 1;
// Construct a new murmur store
let murmur_store = MurmurStore::<EngineTinyBLS377>::new::<
BasicIdentityBuilder,
OsRng,
ChaCha20Rng,
>(seed.clone(), block_schedule.to_vec(), nonce, double_public, &mut rng)
.unwrap();
```

#### Prepare Execution Parameters

This library allows for arbitary payloads to be strictly associated with the reveal of a future OTP code. That is, given an OTP created for a future round r, it allows for the creation of a commitment to that data that cannot be verified until the future round `r` happens and the beacon outputs a signature allowing for decryption of the OTP code. We can consider this a form of `timelocked` commitments.

``` rust
// The round when the commitment will be verifiable
let when = 156921;
// Generates a Merkle proof, the hash Sha256(OTP || aux_data),
// the timelocked OTP code ciphertext and its position in the MMR.
// This data is used later on by the verifier to verify the commitment.
let (proof, commitment, ciphertext, pos) =
murmur_store.execute(seed.clone(), when, aux_data.clone()).unwrap();
```

### Verification

The verifier module provides functionality to verify Murmur store data and timelocked commitments. In general, this would be executed by whichever actor in the system implementing Murmur has agency to directly manipulate the system or otherwise proxy user input to meaningful actions. This is intended to be run in trustless systems, specifically in the context of a blockchain runtime.

#### Verify Updates

When a Murmur store is updated, a DLEQ proof is generated and attached to the store. This is intended to allow the creator of the Murmur store to prove that they know the secret inputs without revealing them, allowing them to update the Murmur store whenever they need to. The `verify_update` function verifies the DLEQ proof. If it is true, then the prover (Murmur store creator) has convinced the verifier (e.g. Blockchain Runtime) that it was generated with the same seed.

``` rust
verifier::verify_update::<TinyBLS377>(proof, public_key, nonce).unwrap()
```

#### Verify Execution Parameters

This function allows for "timelocked" commitments to be verified. The OTP input should be the timelock decrypted ciphertext. More specifically, it:
1) verifies a Merkle proof to prove that the ciphertext is indeed at the given position in the MMR defined by the given root.
2) reconstructs the commitment and compares it against the given one

``` rust
verifier::verify_execute(
root, proof, commitment, ciphertext, OTP, &aux_data, pos,
);
```

## Build

Expand Down Expand Up @@ -33,8 +131,6 @@ cargo test --features "client"
## Future Work/Notes

- **OTPAuth Feature**: There is an 'otpauth' feature that can be enabled on the totp lib. It allows for the inclusion of an issuer and account_name. We can investigate usage of this in the future. [TOTP Library Reference](https://github.com/constantoine/totp-rs/blob/da78569b0c233adbce126dbe0c35452340fd3929/src/lib.rs#L160)
- **Wallet Update logic**: Each murmur wallet is ephemeral, since any MMR must be limited in size. We can use a zkp to prove knowledge of the seed in order to allow the wallet owner to update the wallet by providing a new MMR root.

## Contributing

Contributions are welcome! Please open an issue or submit a pull request.
Expand Down
Loading

0 comments on commit ab46271

Please sign in to comment.