Skip to content

Commit

Permalink
Merge pull request #23 from logical-mechanism/seedelf-cli-01
Browse files Browse the repository at this point in the history
Seedelf cli 01
  • Loading branch information
quinn-logicalmechanism authored Dec 17, 2024
2 parents 6991ec7 + bbe4b7b commit 55da7eb
Show file tree
Hide file tree
Showing 125 changed files with 4,988 additions and 14,724 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v3
- uses: aiken-lang/setup-aiken@v1
with:
version: v1.1.7
version: v1.1.9
- run: aiken fmt --check
- run: aiken check -D
- run: aiken build
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ copy.plutus.json
plutus.json
papers/
aiken.lock
grind_pid.sh
grind_pid.sh
app/
seedelf_app/
16 changes: 4 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Seedelf - A Cardano Stealth Wallet

**Seedelf** is a stealth wallet that hides the receiver and spender with Schnorr proofs using the BLS12-381 curve.
**Seedelf** is a stealth wallet that hides the receiver and spender with Schnorr proofs using the BLS12-381 curve. UTxOs inside the wallet are indistinguishable from one-another and it is not possible to deduce the intended receiver assuming that the Elliptic Curve Decisional-Diffie-Hellman (ECDDH) problem is hard.

## What is a Seedelf token?

Expand Down Expand Up @@ -97,21 +97,13 @@ A register defines a public address used to produce a private address. A user wi
A user selects a random integer, $d$, and constructs a new register.

$$
(g, u) \rightarrow (g^{d}, u^{d})
(g, u) \rightarrow (g^{d}, u^{d}) \rightarrow (h, v)
$$

From the outside viewer, the new register appears random and can not be inverted back into the public register because we assume the Elliptic Curve Decisional-Diffie-Hellman (ECDDH) problem is hard. The scalar multiplication of the register maintains spendability while providing privacy about who owns the UTxO.

#### Re-Randomization Spendability Proof

$$
h \leftarrow g^{d}
$$

$$
v \leftarrow u^{d}
$$

$$
h^{z} = h^{r} v^{c}
$$
Expand Down Expand Up @@ -142,13 +134,13 @@ In the contract, there will be many UTxOs with unique registers. A user can alwa

The wallet is just a smart contract. It is bound by the cpu and memory units of the underlying blockchain, meaning that a UTxO can only hold so many tokens before it becomes unspendable due to space and time limitations. In this implementation, the value is not hidden nor mixed in any way, shape, or fashion. This contract is equivalent to generating addresses using a hierarchical deterministic wallet, but instead of keeping the root key private and generating the address when asked, it is now public via a datum, and address generation is the sender's duty and not the receiver's.

Sending funds requires a correct and equal $d$ value applied to both elements of the register. Incorrectly applied $d$ values will result in a stuck UTxO inside the contract as seen in the example below.
Sending funds requires a correct and equal $d$ value applied to both elements of the register. Incorrectly applied $d$ values will result in a stuck UTxO inside the contract.

$$
(g, u) \rightarrow (g^{d}, u^{d'}) \quad \text{where } d \neq d'
$$

This register would become unspendable, resulting in lost funds for both Bob and Alice.
This register would become unspendable, resulting in lost funds.

### De-Anonymizing Attacks

Expand Down
6 changes: 3 additions & 3 deletions aiken.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "logical-mechanism/Seedelf-Wallet"
version = "0.1.2"
compiler = "v1.1.7"
version = "0.2.0"
compiler = "v1.1.9"
plutus = "v3"
license = "GPL-3.0-or-later"
description = "A Cardano Stealth Wallet"
Expand All @@ -12,7 +12,7 @@ platform = "github"

[[dependencies]]
name = "aiken-lang/stdlib"
version = "v2.1.0"
version = "v2.2.0"
source = "github"

[config]
5 changes: 3 additions & 2 deletions complete_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mkdir -p hashes
rm contracts/* || true
rm hashes/* || true

# delete the build folder all together
# delete the build folder
rm -fr build/ || true

# compile the scripts with aiken build
Expand All @@ -22,7 +22,8 @@ aiken build --trace-level silent --trace-filter user-defined
# aiken build --trace-level verbose --trace-filter all

# some random string to make the contracts unique
rand=$(head /dev/urandom | tr -dc a-f0-9 | head -c 16)
# rand=$(head /dev/urandom | tr -dc a-f0-9 | head -c 16)
rand="acabbeeffacecafe"
rand_cbor=$(python3 -c "import cbor2; print(cbor2.dumps(bytes.fromhex('${rand}')).hex())")
echo "Random Seed:" ${rand}

Expand Down
2 changes: 1 addition & 1 deletion contracts/always_false_contract.plutus
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "PlutusScriptV3",
"description": "Generated by Aiken",
"cborHex": "58435841010100332323232225333003323232323263009300a0033008002300700230070013004375400229309b2b2b9a5573cae855d1260109489f758fe61354a4490001"
"cborHex": "58435841010100332323232225333003323232323263009300a0033008002300700230070013004375400229309b2b2b9a5573cae855d126010948acabbeeffacecafe0001"
}
2 changes: 1 addition & 1 deletion contracts/seedelf_contract.plutus
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "PlutusScriptV3",
"description": "Generated by Aiken",
"cborHex": "59024b590248010100332323232323232225333003323232323253330083370e900018049baa00113232323322533300d533300d00214a22002266601aa66601a004200229412825114a06464a66602060260042646464a66602066e3c020dd7180a8020a99980819b8f3337189000240100049101045eed0e1f0013370e90008008a5014a06eb4c050c054008dd7180980098098008b1bac30110013001375660206022602260226022601a6ea8018c8c8c8c94ccc048c0540084c8c8c8c8c94ccc050cdc3a4000602a6ea80044c8c8c8c94ccc060cdc400124100082a66603066e3c04002054ccc060cdc7800803899b87480080185280a5014a06466600266e28cdc52441045eed0e1f0033300100f48001201c337160046eb8c00cc068dd51801980d1baa00448001203e22233371800466e00cdc0800801240040066eb4c06cc070c060dd51800980c1baa0022301b0013019301637540022ca66602c00e2980103d87a800013374a90001980b980c003a5eb80dd6980b980c0019bae3016002375c602a004602a0022c6eb0c04c004c00cdd5980918099809980998098011bac3011001300d375400c4646600200200444a666020002297ae01323332223233001001003225333016001100313233018374e660306ea4018cc060c054004cc060c0580052f5c066006006603400460300026eb8c03c004dd5980800099801801980a00118090009bae003375c601a60146ea800458c030c03400cc02c008c028008c028004c014dd50008a4c26cacae6955ceaab9e5573eae815d0aba24c0109489f758fe61354a4490001"
"cborHex": "59024b590248010100332323232323232225333003323232323253330083370e900018049baa00113232323322533300d533300d00214a22002266601aa66601a004200229412825114a06464a66602060260042646464a66602066e3c020dd7180a8020a99980819b8f3337189000240100049101045eed0e1f0013370e90008008a5014a06eb4c050c054008dd7180980098098008b1bac30110013001375660206022602260226022601a6ea8018c8c8c8c94ccc048c0540084c8c8c8c8c94ccc050cdc3a4000602a6ea80044c8c8c8c94ccc060cdc400124100082a66603066e3c04002054ccc060cdc7800803899b87480080185280a5014a06466600266e28cdc52441045eed0e1f0033300100f48001201c337160046eb8c00cc068dd51801980d1baa00448001203e22233371800466e00cdc0800801240040066eb4c06cc070c060dd51800980c1baa0022301b0013019301637540022ca66602c00e2980103d87a800013374a90001980b980c003a5eb80dd6980b980c0019bae3016002375c602a004602a0022c6eb0c04c004c00cdd5980918099809980998098011bac3011001300d375400c4646600200200444a666020002297ae01323332223233001001003225333016001100313233018374e660306ea4018cc060c054004cc060c0580052f5c066006006603400460300026eb8c03c004dd5980800099801801980a00118090009bae003375c601a60146ea800458c030c03400cc02c008c028008c028004c014dd50008a4c26cacae6955ceaab9e5573eae815d0aba24c010948acabbeeffacecafe0001"
}
2 changes: 1 addition & 1 deletion contracts/wallet_contract.plutus
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "PlutusScriptV3",
"description": "Generated by Aiken",
"cborHex": "59027959027601010033232323232323232225333003323232323253330083370e900118049baa001132332253323300c3001300d375400c2646464646464a66602a60300042a666024600e60266ea80204c8c94cccccc06c00854ccc050c024c054dd5001099299980c000801099299999980e80080180180180189919299980d8008028992999999810000803003003003099299980e9810001899299980d9919199999911111192999812180c98129baa001132325333026301b30273754002266ee4008cddb1bbb005337706eb4c0acc0a0dd50009bbb007163008379066e28cdc519b8a007004006003337706eb4c0a4c098dd50009bbb006163006003232533301f533301f337129000000899b880014820a02020383ffffffffef7f97fefe0693ef3aaa02efa21222c39e660ea77f3aa69a77b6f838528099ba548000cc08cdd4000a5eb805300103d87a800033794944004dd71800980f9baa00b375c6004603e6ea802cdd71800980f9baa017375c6004603e6ea805cdd71801980f9baa0172302200123021302200113322323300100100322533302200114a026644a66604266e3c0080145288998020020009bae302400130250013758604060426042604260426042604260426042603a6ea8058dd71800980e9baa01514a0460406042604200200e6eb8004c074004c07400cdd7000980d000980b1baa00200100100100100114a2602e60286ea80205288b1bae30160013016002375c602800260280046eb8c048004c038dd50031b874800058c038004c038c03c004c028dd50008b1806180680198058011805001180500098029baa00114984d9595cd2ab9d5573caae7d5d02ba15744ae91300109489f758fe61354a4490001"
"cborHex": "59027959027601010033232323232323232225333003323232323253330083370e900118049baa001132332253323300c3001300d375400c2646464646464a66602a60300042a666024600e60266ea80204c8c94cccccc06c00854ccc050c024c054dd5001099299980c000801099299999980e80080180180180189919299980d8008028992999999810000803003003003099299980e9810001899299980d9919199999911111192999812180c98129baa001132325333026301b30273754002266ee4008cddb1bbb005337706eb4c0acc0a0dd50009bbb007163008379066e28cdc519b8a007004006003337706eb4c0a4c098dd50009bbb006163006003232533301f533301f337129000000899b880014820a02020383ffffffffef7f97fefe0693ef3aaa02efa21222c39e660ea77f3aa69a77b6f838528099ba548000cc08cdd4000a5eb805300103d87a800033794944004dd71800980f9baa00b375c6004603e6ea802cdd71800980f9baa017375c6004603e6ea805cdd71801980f9baa0172302200123021302200113322323300100100322533302200114a026644a66604266e3c0080145288998020020009bae302400130250013758604060426042604260426042604260426042603a6ea8058dd71800980e9baa01514a0460406042604200200e6eb8004c074004c07400cdd7000980d000980b1baa00200100100100100114a2602e60286ea80205288b1bae30160013016002375c602800260280046eb8c048004c038dd50031b874800058c038004c038c03c004c028dd50008b1806180680198058011805001180500098029baa00114984d9595cd2ab9d5573caae7d5d02ba15744ae9130010948acabbeeffacecafe0001"
}
2 changes: 1 addition & 1 deletion hashes/always_false.hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fd80f72ab30b506e1fc7a7dd20ef820ca67105cd93f18f2292437217
8e511d37053024c30870a6c7e59d9947bec0d25d42ec4e953e302fa1
2 changes: 1 addition & 1 deletion hashes/seedelf.hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
88176fa1b636ef39dd71d83b17fa487942492bb3af99fd375ec71847
52af77cf39fd08cf872f04dccf90f27b4fbf09252901f5e88f564ae5
2 changes: 1 addition & 1 deletion hashes/wallet.hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
32f95ddceffb5d3c27cfb88be8c8c5e7861234f6db313ef4df785a49
6a3fee2fe7c8be0ab2548728d37d2efa3eed55b3ab1c4f2e0de6d140
23 changes: 23 additions & 0 deletions lib/schnorr.ak
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ test valid_schnorr_proof() {
// the z value
let z: Scalar = scalar.mul(c, x) |> scalar.add(r)
let z_b: ByteArray = scalar.to_bytearray_big_endian(z, 0)
trace datum.generator
trace datum.public_value
trace z_b
trace g_r_b
trace bound
prove(datum.generator, datum.public_value, z_b, g_r_b, bound)
}

Expand Down Expand Up @@ -189,6 +194,11 @@ test randomized_valid_schnorr_proof() {
// the z value
let z: Scalar = scalar.mul(c, x) |> scalar.add(r)
let z_b: ByteArray = scalar.to_bytearray_big_endian(z, 0)
trace datum_rng.generator
trace datum_rng.public_value
trace z_b
trace g_r_b
trace bound
prove(datum_rng.generator, datum_rng.public_value, z_b, g_r_b, bound)
}

Expand Down Expand Up @@ -252,3 +262,16 @@ test simple_schnorr_proof() {
let z_b: ByteArray = scalar.to_bytearray_big_endian(z, 0)
prove(datum.generator, datum.public_value, z_b, g_r_b, bound)
}

test simple_regsiter() {
// some secret x
expect Some(x): Option<Scalar> = scalar.new(18446744073709551606)
// the datum register using the g1 generator and the public value for x
let datum: Register =
Register {
generator: g1.generator |> g1.compress,
public_value: g1.generator |> g1.scale(x) |> g1.compress,
}
trace datum
datum == datum
}
12 changes: 12 additions & 0 deletions scripts/all_balances.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,15 @@ for wallet_folder in wallets/*-wallet; do
echo -e "\033[0m"
fi
done


${cli} conway query ref-script-size \
--tx-in "46d48857d704091e19f28818363e5b44bffac53379aa703811d88bc3c0276319#1" \
${network} \
--output-json


${cli} conway query ref-script-size \
--tx-in "4ec8f5a0eed8e5567db96b43de59b57c3dc8a8abd88c70ca26f8989346e31889#1" \
${network} \
--output-json
2 changes: 1 addition & 1 deletion scripts/create_wallet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ folder=${1}

# the wallet should not be over written
if [ ! -d ${folder} ]; then
mkdir ${folder}
mkdir -p ${folder}
${cli} address key-gen --verification-key-file ${folder}/payment.vkey --signing-key-file ${folder}/payment.skey
${cli} address build --payment-verification-key-file ${folder}/payment.vkey --out-file ${folder}/payment.addr ${network}
${cli} address key-hash --payment-verification-key-file ${folder}/payment.vkey --out-file ${folder}/payment.hash
Expand Down
2 changes: 1 addition & 1 deletion scripts/data/path_to_socket.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/home/logic/Documents/Work/LogicalMechanism/testnets/node-preprod/db-testnet/node.socket
/home/logic/Documents/LogicalMechanism/testnets/node-preprod/db-testnet/node.socket
2 changes: 1 addition & 1 deletion scripts/data/pointer/pointer-redeemer.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"bytes": ""
"bytes": "74657374696e67"
}
2 changes: 1 addition & 1 deletion scripts/data/wallet/wallet-datum.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"bytes": "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"
},
{
"bytes": "8912c5a3e0a3f6dfeee8ab7e1559ad2ff40c4caf32c952593a1ab8863662c26e795176b3bb8930c58f566c53a885452c"
"bytes": "aafdf5aaed4bae8122d02990b67b9030c8fe352dc40c5823cce4588ed981e89ec7057e1c057a9657a934f310e8c0851a"
}
]
}
14 changes: 14 additions & 0 deletions scripts/submit_tx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -e

# SET UP VARS HERE
source .env

echo -e "\033[0;36m Submitting \033[0m"
${cli} conway transaction submit \
${network} \
--tx-file ./tmp/test.tx


tx=$(${cli} conway transaction txid --tx-file ./tmp/test.tx)
echo "Tx Id:" $tx
46 changes: 46 additions & 0 deletions seedelf-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Generated by Cargo
/target/
**/*.rs.bk

# Build artifacts
/debug/
release/

# Ignore Cargo.lock if the project is a library (optional)
# Uncomment if your project is a library and not a binary
# Cargo.lock

# Dependency directories
/.cargo/
**/Cargo.lock.bak

# Ignore temporary files
*.tmp
*.swp
*.swo
*.DS_Store
*.log
*.bak
*.lock
*.temp

# By default, don't ignore node_modules of your app
node_modules/
**/*.js.map

# Editor-specific files
.idea/
*.iml
*.vs/
.vscode/
*.code-workspace

# MacOS files
.DS_Store

# Windows files
Thumbs.db
*.cabinet
.idea/cache- backup

---
34 changes: 34 additions & 0 deletions seedelf-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "seedelf-cli"
version = "0.2.0"
edition = "2021"

[dependencies]
clap = { version = "4.5.21", features = ["derive"] }
dirs = "5.0"
whoami = "1.5.2"
blstrs = "0.7.1"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
serde_cbor = "0.11.2"
hex = "0.4.3"
rand_core = { version = "0.6.4", features = ["std"] }
ff = "0.13.0"
blake2 = "0.10.6"
tokio = { version = "1.41.1", features = ["full"] }
reqwest = { version = "0.12.9", features = ["json"] }
pallas-addresses = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-addresses = "0.31.0"
pallas-crypto = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-crypto = "0.31.0"
pallas-codec = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-codec = "0.31.0"
pallas-txbuilder = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-txbuilder = "0.31.0"
pallas-traverse = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-traverse = "0.31.0"
pallas-wallet = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-wallet = "0.31.0"
pallas-primitives = { git = "https://github.com/logicalmechanism/pallas", branch = "main" }
#pallas-primitives = "0.31.0"
warp = "0.3.7"
56 changes: 56 additions & 0 deletions seedelf-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Seedelf CLI

Seedelf is a stealth wallet that hides the receiver and spender.

- TODO -> Build github action workflow for tagged releases

## Installation

Installing on path

```bash
cargo install --path .
```

Building for release
```bash
cargo build --release
```

Locally running it
```bash
cargo build
cargo run -- help
```

## Using The Seedelf CLI

```bash
A Cardano Stealth Wallet

Usage: seedelf-cli [OPTIONS] <COMMAND>

Commands:
welcome Displays the Seedelf welcome message
wallet-info Displays wallet information
balance Displays the current wallet balance
fund An address sends ADA to a Seedelf
transfer A Seedelf sends ADA to a Seedelf
sweep A Seedelf sends ADA to an address
seedelf-new Create a new Seedelf
seedelf-all Display all Seedelfs
seedelf-remove Remove a Seedelf
help Print this message or the help of the given subcommand(s)

Options:
--preprod Use this flag to interact with the pre-production environment
-h, --help Print help
-V, --version Print version

```

### Basic Usage

Create a Seedelf with the `seedelf-new` command. The Seedelf is funded with the `fund` command. Send funds to another Seedelf with the `transfer` command. Funds can be send to an address with the `sweep` command. Use the `--help` option to see more information.

Some commands will prompt to open a localhost for cip30 wallet interaction.
Loading

0 comments on commit 55da7eb

Please sign in to comment.