-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(waku-stealth-commitments): waku stealth commitment protocol (#2490)
* feat(waku-stealth-commitments): initialize app * feat: works! * fix: readme * feat: send and receive, handle received stealth commitment * fix: remove empty lines * chore: move to examples
- Loading branch information
Showing
7 changed files
with
601 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# wakustealthcommitments | ||
|
||
This application/tool/protocol is used to securely communicate requests and responses for the [Stealth Address Scheme](https://eips.ethereum.org/EIPS/eip-5564) | ||
|
||
Uses TWN config as default, and content topic: `/wakustealthcommitments/1/app/proto` | ||
|
||
## Usage | ||
|
||
1. Clone the erc-5564-bn254 repo and build the static lib | ||
```sh | ||
gh repo clone rymnc/erc-5564-bn254 | ||
cd erc-5564-bn254 | ||
cargo build --release --all-features | ||
cp ./target/release/liberc_5564_bn254.a <path-to-nwaku> | ||
``` | ||
|
||
> ![NOTE] | ||
> This static library also includes the rln ffi library, so you don't need to build it separately. | ||
> This is because using both of them separately brings in a lot of duplicate symbols. | ||
2. Build the wakustealthcommitments app | ||
```sh | ||
cd <path-to-nwaku> | ||
source env.sh | ||
nim c --out:build/wakustealthcommitments --verbosity:0 --hints:off -d:chronicles_log_level=INFO -d:git_version="v0.24.0-rc.0-62-g7da25c" -d:release --passL:-lm --passL:liberc_5564_bn254.a --debugger:native examples/wakustealthcommitments/wakustealthcommitments.nim | ||
``` | ||
|
||
3. | ||
```sh | ||
./build/wakustealthcommitments \ | ||
--rln-relay-eth-client-address:<insert http rpc url> \ | ||
--rln-relay-cred-path:<path-to-credentials-file> \ | ||
--rln-relay-cred-password:<password-of-credentials-file> | ||
``` | ||
|
||
This service listens for requests for stealth commitment/address generation, | ||
partakes in the generation of said stealth commitment and then distributes the response to the mesh. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
## Nim wrappers for the functions defined in librln | ||
when (NimMajor, NimMinor) < (1, 4): | ||
{.push raises: [Defect].} | ||
else: | ||
{.push raises: [].} | ||
|
||
import stew/results | ||
|
||
###################################################################### | ||
## ERC-5564-BN254 module APIs | ||
###################################################################### | ||
|
||
type CErrorCode* = uint8 | ||
|
||
type CG1Projective* = object | ||
x0: array[32, uint8] | ||
|
||
type CReturn*[T] = object | ||
value: T | ||
err_code: CErrorCode | ||
|
||
type CFr* = object | ||
x0: array[32, uint8] | ||
|
||
type CStealthCommitment* = object | ||
stealth_commitment: CG1Projective | ||
view_tag: uint64 | ||
|
||
type CKeyPair* = object | ||
private_key: CFr | ||
public_key: CG1Projective | ||
|
||
proc drop_ffi_derive_public_key*(ptrx: ptr CReturn[CG1Projective]) {.importc: "drop_ffi_derive_public_key".} | ||
|
||
proc drop_ffi_generate_random_fr*(ptrx: ptr CReturn[CFr]) {.importc: "drop_ffi_generate_random_fr".} | ||
|
||
proc drop_ffi_generate_stealth_commitment*(ptrx: ptr CReturn[CStealthCommitment]) {.importc: "drop_ffi_generate_stealth_commitment".} | ||
|
||
proc drop_ffi_generate_stealth_private_key*(ptrx: ptr CReturn[CFr]) {.importc: "drop_ffi_generate_stealth_private_key".} | ||
|
||
proc drop_ffi_random_keypair*(ptrx: ptr CReturn[CKeyPair]) {.importc: "drop_ffi_random_keypair".} | ||
|
||
proc ffi_derive_public_key*(private_key: ptr CFr): (ptr CReturn[CG1Projective]) {.importc: "ffi_derive_public_key".} | ||
|
||
proc ffi_generate_random_fr*(): (ptr CReturn[CFr]) {.importc: "ffi_generate_random_fr".} | ||
|
||
proc ffi_generate_stealth_commitment*(viewing_public_key: ptr CG1Projective, | ||
spending_public_key: ptr CG1Projective, | ||
ephemeral_private_key: ptr CFr): (ptr CReturn[CStealthCommitment]) {.importc: "ffi_generate_stealth_commitment".} | ||
|
||
proc ffi_generate_stealth_private_key*(ephemeral_public_key: ptr CG1Projective, | ||
spending_key: ptr CFr, | ||
viewing_key: ptr CFr, | ||
view_tag: ptr uint64): (ptr CReturn[CFr]) {.importc: "ffi_generate_stealth_private_key".} | ||
|
||
proc ffi_random_keypair*(): (ptr CReturn[CKeyPair]) {.importc: "ffi_random_keypair".} | ||
|
||
|
||
## Nim wrappers and types for the ERC-5564-BN254 module | ||
|
||
type FFIResult[T] = Result[T, string] | ||
type Fr = array[32, uint8] | ||
type G1Projective = array[32, uint8] | ||
type KeyPair* = object | ||
private_key*: Fr | ||
public_key*: G1Projective | ||
type StealthCommitment* = object | ||
stealth_commitment*: G1Projective | ||
view_tag*: uint64 | ||
type PrivateKey* = Fr | ||
type PublicKey* = G1Projective | ||
|
||
proc generateRandomFr*(): FFIResult[Fr] = | ||
let res_ptr = (ffi_generate_random_fr()) | ||
let res_value = res_ptr[] | ||
if res_value.err_code != 0: | ||
drop_ffi_generate_random_fr(res_ptr) | ||
return err("Error generating random field element: " & $res_value.err_code) | ||
|
||
let ret = res_value.value.x0 | ||
drop_ffi_generate_random_fr(res_ptr) | ||
return ok(ret) | ||
|
||
proc generateKeypair*(): FFIResult[KeyPair] = | ||
let res_ptr = (ffi_random_keypair()) | ||
let res_value = res_ptr[] | ||
if res_value.err_code != 0: | ||
drop_ffi_random_keypair(res_ptr) | ||
return err("Error generating random keypair: " & $res_value.err_code) | ||
|
||
let ret = KeyPair(private_key: res_value.value.private_key.x0, public_key: res_value.value.public_key.x0) | ||
drop_ffi_random_keypair(res_ptr) | ||
return ok(ret) | ||
|
||
proc generateStealthCommitment*(viewing_public_key: G1Projective, | ||
spending_public_key: G1Projective, | ||
ephemeral_private_key: Fr): FFIResult[StealthCommitment] = | ||
let viewing_public_key = CG1Projective(x0: viewing_public_key) | ||
let viewing_public_key_ptr = unsafeAddr(viewing_public_key) | ||
let spending_public_key = CG1Projective(x0: spending_public_key) | ||
let spending_public_key_ptr = unsafeAddr(spending_public_key) | ||
let ephemeral_private_key = CFr(x0: ephemeral_private_key) | ||
let ephemeral_private_key_ptr = unsafeAddr(ephemeral_private_key) | ||
|
||
let res_ptr = (ffi_generate_stealth_commitment(viewing_public_key_ptr, spending_public_key_ptr, ephemeral_private_key_ptr)) | ||
let res_value = res_ptr[] | ||
if res_value.err_code != 0: | ||
drop_ffi_generate_stealth_commitment(res_ptr) | ||
return err("Error generating stealth commitment: " & $res_value.err_code) | ||
|
||
let ret = StealthCommitment(stealth_commitment: res_value.value.stealth_commitment.x0, view_tag: res_value.value.view_tag) | ||
drop_ffi_generate_stealth_commitment(res_ptr) | ||
return ok(ret) | ||
|
||
proc generateStealthPrivateKey*(ephemeral_public_key: G1Projective, | ||
spending_key: Fr, | ||
viewing_key: Fr, | ||
view_tag: uint64): FFIResult[Fr] = | ||
let ephemeral_public_key = CG1Projective(x0: ephemeral_public_key) | ||
let ephemeral_public_key_ptr = unsafeAddr(ephemeral_public_key) | ||
let spending_key = CFr(x0: spending_key) | ||
let spending_key_ptr = unsafeAddr(spending_key) | ||
let viewing_key = CFr(x0: viewing_key) | ||
let viewing_key_ptr = unsafeAddr(viewing_key) | ||
let view_tag_ptr = unsafeAddr(view_tag) | ||
|
||
let res_ptr = (ffi_generate_stealth_private_key(ephemeral_public_key_ptr, spending_key_ptr, viewing_key_ptr, view_tag_ptr)) | ||
let res_value = res_ptr[] | ||
if res_value.err_code != 0: | ||
drop_ffi_generate_stealth_private_key(res_ptr) | ||
return err("Error generating stealth private key: " & $res_value.err_code) | ||
|
||
let ret = res_value.value.x0 | ||
drop_ffi_generate_stealth_private_key(res_ptr) | ||
return ok(ret) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
-d:chronicles_line_numbers | ||
-d:discv5_protocol_id="d5waku" | ||
-d:chronicles_runtime_filtering=on | ||
-d:chronicles_sinks="textlines,json" | ||
-d:chronicles_default_output_device=dynamic | ||
# Disabling the following topics from nim-eth and nim-dnsdisc since some types cannot be serialized | ||
-d:chronicles_disabled_topics="eth,dnsdisc.client" | ||
-d:chronicles_log_level=INFO | ||
# Results in empty output for some reason | ||
#-d:"chronicles_enabled_topics=GossipSub:TRACE,WakuRelay:TRACE" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
when (NimMajor, NimMinor) < (1, 4): | ||
{.push raises: [Defect].} | ||
else: | ||
{.push raises: [].} | ||
|
||
import ../../apps/wakunode2/[networks_config, app, external_config] | ||
import ../../waku/common/logging | ||
import | ||
std/[options, strutils, os, sequtils], | ||
stew/shims/net as stewNet, | ||
chronicles, | ||
chronos, | ||
metrics, | ||
libbacktrace, | ||
libp2p/crypto/crypto | ||
|
||
export | ||
networks_config, | ||
app, | ||
logging, | ||
options, | ||
strutils, | ||
os, | ||
sequtils, | ||
stewNet, | ||
chronicles, | ||
chronos, | ||
metrics, | ||
libbacktrace, | ||
crypto | ||
|
||
proc setup*(): App = | ||
const versionString = "version / git commit hash: " & app.git_version | ||
let rng = crypto.newRng() | ||
|
||
let confRes = WakuNodeConf.load(version = versionString) | ||
if confRes.isErr(): | ||
error "failure while loading the configuration", error = $confRes.error | ||
quit(QuitFailure) | ||
|
||
var conf = confRes.get() | ||
|
||
let twnClusterConf = ClusterConf.TheWakuNetworkConf() | ||
if len(conf.shards) != 0: | ||
conf.pubsubTopics = conf.shards.mapIt(twnClusterConf.pubsubTopics[it.uint16]) | ||
else: | ||
conf.pubsubTopics = twnClusterConf.pubsubTopics | ||
|
||
# Override configuration | ||
conf.maxMessageSize = twnClusterConf.maxMessageSize | ||
conf.clusterId = twnClusterConf.clusterId | ||
conf.rlnRelay = twnClusterConf.rlnRelay | ||
conf.rlnRelayEthContractAddress = twnClusterConf.rlnRelayEthContractAddress | ||
conf.rlnRelayDynamic = twnClusterConf.rlnRelayDynamic | ||
conf.rlnRelayBandwidthThreshold = twnClusterConf.rlnRelayBandwidthThreshold | ||
conf.discv5Discovery = twnClusterConf.discv5Discovery | ||
conf.discv5BootstrapNodes = | ||
conf.discv5BootstrapNodes & twnClusterConf.discv5BootstrapNodes | ||
conf.rlnEpochSizeSec = twnClusterConf.rlnEpochSizeSec | ||
conf.rlnRelayUserMessageLimit = twnClusterConf.rlnRelayUserMessageLimit | ||
|
||
var wakunode2 = App.init(rng, conf) | ||
## Peer persistence | ||
let res1 = wakunode2.setupPeerPersistence() | ||
if res1.isErr(): | ||
error "1/5 Setting up storage failed", error = $res1.error | ||
quit(QuitFailure) | ||
|
||
debug "2/5 Retrieve dynamic bootstrap nodes" | ||
|
||
let res3 = wakunode2.setupDyamicBootstrapNodes() | ||
if res3.isErr(): | ||
error "2/5 Retrieving dynamic bootstrap nodes failed", error = $res3.error | ||
quit(QuitFailure) | ||
|
||
debug "3/5 Initializing node" | ||
|
||
let res4 = wakunode2.setupWakuApp() | ||
if res4.isErr(): | ||
error "3/5 Initializing node failed", error = $res4.error | ||
quit(QuitFailure) | ||
|
||
debug "4/5 Mounting protocols" | ||
|
||
var res5: Result[void, string] | ||
try: | ||
res5 = waitFor wakunode2.setupAndMountProtocols() | ||
if res5.isErr(): | ||
error "4/5 Mounting protocols failed", error = $res5.error | ||
quit(QuitFailure) | ||
except Exception: | ||
error "4/5 Mounting protocols failed", error = getCurrentExceptionMsg() | ||
quit(QuitFailure) | ||
|
||
debug "5/5 Starting node and mounted protocols" | ||
|
||
# set triggerSelf to false, we don't want to process our own stealthCommitments | ||
wakunode2.node.wakuRelay.triggerSelf = false | ||
|
||
let res6 = wakunode2.startApp() | ||
if res6.isErr(): | ||
error "5/5 Starting node and protocols failed", error = $res6.error | ||
quit(QuitFailure) | ||
|
||
info "Node setup complete" | ||
return wakunode2 |
Oops, something went wrong.