storing epoch id alongside coconut key
This commit is contained in:
@@ -14,7 +14,7 @@ pub use nym_coconut::{
|
||||
aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar,
|
||||
prepare_blind_sign, prove_bandwidth_credential, Attribute, Base58, BlindSignRequest,
|
||||
BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute,
|
||||
PublicAttribute, Signature, SignatureShare, Theta, VerificationKey,
|
||||
PublicAttribute, Signature, SignatureShare, Theta, VerificationKey, SecretKey
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -75,7 +75,7 @@ pub async fn post_blind_sign(
|
||||
|
||||
// produce the partial signature
|
||||
debug!("producing the partial credential");
|
||||
let blinded_signature = blind_sign(&blind_sign_request_body, signing_key.secret_key())?;
|
||||
let blinded_signature = blind_sign(&blind_sign_request_body, signing_key.keys.secret_key())?;
|
||||
|
||||
// store the information locally
|
||||
debug!("storing the issued credential in the database");
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::coconut::keys::KeyPairWithEpoch;
|
||||
use crate::support::config;
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::path::Path;
|
||||
use thiserror::__private::AsDisplay;
|
||||
|
||||
pub(crate) fn init_bte_keypair<R: RngCore + CryptoRng>(
|
||||
@@ -34,61 +36,41 @@ pub(crate) fn load_bte_keypair(config: &config::CoconutSigner) -> anyhow::Result
|
||||
|
||||
pub(crate) fn load_coconut_keypair_if_exists(
|
||||
config: &config::CoconutSigner,
|
||||
) -> anyhow::Result<Option<nym_coconut_interface::KeyPair>> {
|
||||
if !config.storage_paths.secret_key_path.exists() {
|
||||
) -> anyhow::Result<Option<KeyPairWithEpoch>> {
|
||||
if !config.storage_paths.coconut_key_path.exists() {
|
||||
return Ok(None);
|
||||
}
|
||||
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
|
||||
&config.storage_paths.secret_key_path,
|
||||
&config.storage_paths.verification_key_path,
|
||||
))
|
||||
.context("coconut keypair load failure")
|
||||
.map(Some)
|
||||
nym_pemstore::load_key(&config.storage_paths.coconut_key_path)
|
||||
.context("coconut key load failure")
|
||||
.map(Some)
|
||||
}
|
||||
|
||||
pub(crate) fn persist_coconut_keypair(
|
||||
keys: &nym_coconut_interface::KeyPair,
|
||||
store_paths: &nym_pemstore::KeyPairPath,
|
||||
pub(crate) fn persist_coconut_keypair<P: AsRef<Path>>(
|
||||
keys: &KeyPairWithEpoch,
|
||||
store_path: P,
|
||||
) -> anyhow::Result<()> {
|
||||
nym_pemstore::store_keypair(keys, store_paths).context("coconut keypair store failure")
|
||||
nym_pemstore::store_key(keys, store_path).context("coconut key store failure")
|
||||
}
|
||||
|
||||
pub(crate) fn archive_coconut_keypair(
|
||||
store_paths: &nym_pemstore::KeyPairPath,
|
||||
pub(crate) fn archive_coconut_keypair<P: AsRef<Path>>(
|
||||
store_path: P,
|
||||
epoch_id: EpochId,
|
||||
) -> anyhow::Result<()> {
|
||||
if !store_paths.private_key_path.exists() {
|
||||
bail!(
|
||||
"private key does not exist at {}",
|
||||
store_paths.private_key_path.as_display()
|
||||
)
|
||||
let store_path = store_path.as_ref();
|
||||
if !store_path.exists() {
|
||||
bail!("coconut key does not exist at {}", store_path.as_display())
|
||||
}
|
||||
|
||||
let dir = store_paths
|
||||
.private_key_path
|
||||
let dir = store_path
|
||||
.parent()
|
||||
.ok_or(anyhow!("the private key does not have a valid parent"))?;
|
||||
let filename = store_paths
|
||||
.private_key_path
|
||||
.ok_or(anyhow!("the coconut key does not have a valid parent"))?;
|
||||
let filename = store_path
|
||||
.file_name()
|
||||
.ok_or(anyhow!("the private key does not have a filename"))?
|
||||
.ok_or(anyhow!("the coconut key does not have a valid filename"))?
|
||||
.to_str()
|
||||
.ok_or(anyhow!("the key filename is not valid UTF8"))?;
|
||||
.ok_or(anyhow!("the coconut key filename is not valid UTF8"))?;
|
||||
let archive_path = dir.join(format!("epoch-{epoch_id}-{filename}.archived"));
|
||||
std::fs::rename(&store_paths.private_key_path, archive_path)?;
|
||||
|
||||
let dir = store_paths
|
||||
.public_key_path
|
||||
.parent()
|
||||
.ok_or(anyhow!("the public key does not have a valid parent"))?;
|
||||
let filename = store_paths
|
||||
.public_key_path
|
||||
.file_name()
|
||||
.ok_or(anyhow!("the public key does not have a filename"))?
|
||||
.to_str()
|
||||
.ok_or(anyhow!("the key filename is not valid UTF8"))?;
|
||||
let archive_path = dir.join(format!("epoch-{epoch_id}-{filename}.archived"));
|
||||
std::fs::rename(&store_paths.public_key_path, archive_path)?;
|
||||
std::fs::rename(store_path, archive_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::coconut::dkg::verification_key::{
|
||||
use crate::coconut::dkg::{
|
||||
dealing::dealing_exchange, verification_key::verification_key_submission,
|
||||
};
|
||||
use crate::coconut::keypair::KeyPair as CoconutKeyPair;
|
||||
use crate::coconut::keys::KeyPair as CoconutKeyPair;
|
||||
use crate::nyxd;
|
||||
use crate::support::config;
|
||||
use anyhow::{bail, Result};
|
||||
@@ -30,8 +30,7 @@ pub(crate) mod keys;
|
||||
|
||||
pub(crate) struct DkgController<R = OsRng> {
|
||||
pub(crate) dkg_client: DkgClient,
|
||||
secret_key_path: PathBuf,
|
||||
verification_key_path: PathBuf,
|
||||
pub(crate) coconut_key_path: PathBuf,
|
||||
pub(crate) state: State,
|
||||
rng: R,
|
||||
polling_rate: Duration,
|
||||
@@ -56,8 +55,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
||||
|
||||
Ok(DkgController {
|
||||
dkg_client: DkgClient::new(nyxd_client),
|
||||
secret_key_path: config.storage_paths.secret_key_path.clone(),
|
||||
verification_key_path: config.storage_paths.verification_key_path.clone(),
|
||||
coconut_key_path: config.storage_paths.coconut_key_path.clone(),
|
||||
state: State::new(
|
||||
config.storage_paths.dkg_persistent_state_path.clone(),
|
||||
persistent_state,
|
||||
@@ -71,10 +69,6 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn coconut_keypaths(&self) -> nym_pemstore::KeyPairPath {
|
||||
nym_pemstore::KeyPairPath::new(&self.secret_key_path, &self.verification_key_path)
|
||||
}
|
||||
|
||||
fn persist_state(&self) -> Result<(), DkgError> {
|
||||
// if !self.state.coconut_keypair_is_some().await {
|
||||
// // Delete the files just in case the process is killed before the new keys are generated
|
||||
@@ -162,13 +156,11 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
||||
) -> Result<(), DkgError> {
|
||||
debug!("DKG: verification key submission (resharing: {resharing})");
|
||||
|
||||
let keypair_path =
|
||||
nym_pemstore::KeyPairPath::new(&self.secret_key_path, &self.verification_key_path);
|
||||
verification_key_submission(
|
||||
&self.dkg_client,
|
||||
&mut self.state,
|
||||
epoch_id,
|
||||
&keypair_path,
|
||||
&self.coconut_key_path,
|
||||
resharing,
|
||||
)
|
||||
.await
|
||||
@@ -307,8 +299,7 @@ impl DkgController {
|
||||
pub(crate) fn test_mock(dkg_client: DkgClient, state: State) -> DkgController {
|
||||
DkgController {
|
||||
dkg_client,
|
||||
secret_key_path: Default::default(),
|
||||
verification_key_path: Default::default(),
|
||||
coconut_key_path: Default::default(),
|
||||
state,
|
||||
rng: OsRng,
|
||||
polling_rate: Default::default(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::coconut::dkg::controller::keys::archive_coconut_keypair;
|
||||
use crate::coconut::dkg::controller::DkgController;
|
||||
use crate::coconut::error::CoconutError;
|
||||
use log::debug;
|
||||
@@ -26,11 +27,17 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
||||
|
||||
// if we have coconut keys available, it means we have already completed the DKG before (in previous epoch)
|
||||
// in which case, archive and reset those keys
|
||||
if let Some((old_epoch, _)) = self.state.take_coconut_keypair().await {
|
||||
if let Some(old_keypair) = self.state.take_coconut_keypair().await {
|
||||
debug!("resetting and archiving old coconut keypair");
|
||||
let store_path = self.coconut_keypaths();
|
||||
// archive_coconut_keypair(&store_path, old_epoch)?
|
||||
//
|
||||
if let Err(source) =
|
||||
archive_coconut_keypair(&self.coconut_key_path, old_keypair.issued_for_epoch)
|
||||
{
|
||||
return Err(CoconutError::KeyArchiveFailure {
|
||||
epoch_id,
|
||||
path: self.coconut_key_path.clone(),
|
||||
source,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// FAILURE CASE:
|
||||
@@ -48,6 +55,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
||||
}
|
||||
}
|
||||
|
||||
// perform the full registration instead
|
||||
let bte_key = bs58::encode(&self.state.dkg_keypair().public_key().to_bytes()).into_string();
|
||||
let identity_key = self.state.identity_key().to_base58_string();
|
||||
let announce_address = self.state.announce_address().to_string();
|
||||
@@ -88,7 +96,7 @@ pub(crate) mod tests {
|
||||
AccountId::from_str(TEST_VALIDATOR_ADDRESS).unwrap(),
|
||||
));
|
||||
let identity_keypair = identity::KeyPair::new(&mut thread_rng());
|
||||
let mut state = State::new(
|
||||
let state = State::new(
|
||||
PathBuf::default(),
|
||||
PersistentState::default(),
|
||||
Url::parse("localhost:8000").unwrap(),
|
||||
@@ -96,6 +104,7 @@ pub(crate) mod tests {
|
||||
*identity_keypair.public_key(),
|
||||
KeyPair::new(),
|
||||
);
|
||||
let epoch = dkg_client.get_current_epoch().await.unwrap().epoch_id;
|
||||
let mut controller = DkgController::test_mock(dkg_client, state);
|
||||
|
||||
assert!(controller
|
||||
@@ -105,7 +114,10 @@ pub(crate) mod tests {
|
||||
.unwrap()
|
||||
.details
|
||||
.is_none());
|
||||
controller.public_key_submission(0, false).await.unwrap();
|
||||
controller
|
||||
.public_key_submission(epoch, false)
|
||||
.await
|
||||
.unwrap();
|
||||
let client_idx = controller
|
||||
.dkg_client
|
||||
.get_self_registered_dealer_details()
|
||||
@@ -114,11 +126,31 @@ pub(crate) mod tests {
|
||||
.details
|
||||
.unwrap()
|
||||
.assigned_index;
|
||||
assert_eq!(controller.state.node_index().unwrap(), client_idx);
|
||||
assert_eq!(
|
||||
controller
|
||||
.state
|
||||
.registration_state(epoch)
|
||||
.assigned_index
|
||||
.unwrap(),
|
||||
client_idx
|
||||
);
|
||||
|
||||
// keeps the same index from chain, not calling register_dealer again
|
||||
controller.state.set_node_index(None);
|
||||
controller.public_key_submission(0, false).await.unwrap();
|
||||
assert_eq!(controller.state.node_index().unwrap(), client_idx);
|
||||
controller
|
||||
.state
|
||||
.registration_state_mut(epoch)
|
||||
.assigned_index = None;
|
||||
controller
|
||||
.public_key_submission(epoch, false)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
controller
|
||||
.state
|
||||
.registration_state(epoch)
|
||||
.assigned_index
|
||||
.unwrap(),
|
||||
client_idx
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
mod registration;
|
||||
|
||||
use crate::coconut::dkg::complaints::ComplaintReason;
|
||||
use crate::coconut::dkg::state::registration::RegistrationState;
|
||||
use crate::coconut::error::CoconutError;
|
||||
use crate::coconut::keypair::KeyPair as CoconutKeyPair;
|
||||
use crate::coconut::keys::{KeyPair as CoconutKeyPair, KeyPairWithEpoch};
|
||||
use cosmwasm_std::Addr;
|
||||
use log::debug;
|
||||
use nym_coconut_dkg_common::dealer::DealerDetails;
|
||||
@@ -15,35 +13,23 @@ use nym_crypto::asymmetric::identity;
|
||||
use nym_dkg::bte::{keys::KeyPair as DkgKeyPair, PublicKey, PublicKeyWithProof};
|
||||
use nym_dkg::{Dealing, NodeIndex, RecoveredVerificationKeys, Threshold};
|
||||
use nym_validator_client::nyxd::{tx, Hash};
|
||||
use rocket::form::validate::Contains;
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_helpers::{bte_pk_serde, generated_dealings, vks_serde};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::path::{Path, PathBuf};
|
||||
use time::OffsetDateTime;
|
||||
use tokio::sync::RwLockReadGuard;
|
||||
use url::Url;
|
||||
|
||||
fn bte_pk_serialize<S: Serializer>(
|
||||
val: &PublicKeyWithProof,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
val.to_bytes().serialize(serializer)
|
||||
}
|
||||
|
||||
fn bte_pk_deserialize<'de, D>(deserializer: D) -> Result<PublicKeyWithProof, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<u8> = Deserialize::deserialize(deserializer)?;
|
||||
PublicKeyWithProof::try_from_bytes(&vec).map_err(|err| Error::custom(format_args!("{:?}", err)))
|
||||
}
|
||||
mod registration;
|
||||
mod serde_helpers;
|
||||
|
||||
// note: each dealer is also a receiver which simplifies some logic significantly
|
||||
#[derive(Clone, Deserialize, Debug, Serialize)]
|
||||
pub(crate) struct DkgParticipant {
|
||||
pub(crate) _address: Addr,
|
||||
#[serde(serialize_with = "bte_pk_serialize")]
|
||||
#[serde(deserialize_with = "bte_pk_deserialize")]
|
||||
#[serde(with = "bte_pk_serde")]
|
||||
pub(crate) bte_public_key_with_proof: PublicKeyWithProof,
|
||||
pub(crate) assigned_index: NodeIndex,
|
||||
}
|
||||
@@ -146,69 +132,6 @@ impl ConsistentState for State {
|
||||
}
|
||||
}
|
||||
|
||||
fn vks_serialize<S: Serializer>(
|
||||
val: &[RecoveredVerificationKeys],
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let vec: Vec<Vec<u8>> = val.iter().map(|vk| vk.to_bytes()).collect();
|
||||
vec.serialize(serializer)
|
||||
}
|
||||
|
||||
fn vks_deserialize<'de, D>(deserializer: D) -> Result<Vec<RecoveredVerificationKeys>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<Vec<u8>> = Deserialize::deserialize(deserializer)?;
|
||||
vec.into_iter()
|
||||
.map(|b| {
|
||||
RecoveredVerificationKeys::try_from_bytes(&b)
|
||||
.map_err(|err| D::Error::custom(format_args!("{:?}", err)))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
mod generated_dealings {
|
||||
use nym_coconut_dkg_common::types::{DealingIndex, EpochId};
|
||||
use nym_dkg::Dealing;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
|
||||
type Helper = HashMap<EpochId, HashMap<DealingIndex, Vec<u8>>>;
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
dealings: &HashMap<EpochId, HashMap<DealingIndex, Dealing>>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let mut helper = HashMap::new();
|
||||
for (epoch, dealings) in dealings {
|
||||
let mut inner = HashMap::new();
|
||||
for (dealing_index, dealing) in dealings {
|
||||
inner.insert(*dealing_index, dealing.to_bytes());
|
||||
}
|
||||
helper.insert(*epoch, inner);
|
||||
}
|
||||
helper.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<HashMap<EpochId, HashMap<DealingIndex, Dealing>>, D::Error> {
|
||||
let helper = <Helper>::deserialize(deserializer)?;
|
||||
|
||||
let mut epoch_dealings = HashMap::with_capacity(helper.len());
|
||||
for (epoch, dealings) in helper {
|
||||
let mut inner = HashMap::with_capacity(dealings.len());
|
||||
for (dealing_index, raw_dealing) in dealings {
|
||||
let dealing =
|
||||
Dealing::try_from_bytes(&raw_dealing).map_err(serde::de::Error::custom)?;
|
||||
inner.insert(dealing_index, dealing);
|
||||
}
|
||||
epoch_dealings.insert(epoch, inner);
|
||||
}
|
||||
Ok(epoch_dealings)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub(crate) struct PersistentState {
|
||||
timestamp: OffsetDateTime,
|
||||
@@ -220,8 +143,7 @@ pub(crate) struct PersistentState {
|
||||
generated_dealings: HashMap<EpochId, HashMap<DealingIndex, Dealing>>,
|
||||
receiver_index: Option<usize>,
|
||||
threshold: Option<Threshold>,
|
||||
#[serde(serialize_with = "vks_serialize")]
|
||||
#[serde(deserialize_with = "vks_deserialize")]
|
||||
#[serde(with = "vks_serde")]
|
||||
recovered_vks: Vec<RecoveredVerificationKeys>,
|
||||
proposal_id: Option<u64>,
|
||||
voted_vks: bool,
|
||||
@@ -288,19 +210,33 @@ pub(crate) struct State {
|
||||
dkg_instances: HashMap<EpochId, DkgState>,
|
||||
|
||||
//
|
||||
#[deprecated]
|
||||
announce_address: Url,
|
||||
#[deprecated]
|
||||
identity_key: identity::PublicKey,
|
||||
#[deprecated]
|
||||
dkg_keypair: DkgKeyPair,
|
||||
#[deprecated]
|
||||
coconut_keypair: CoconutKeyPair,
|
||||
#[deprecated]
|
||||
node_index: Option<NodeIndex>,
|
||||
#[deprecated]
|
||||
dealers: BTreeMap<Addr, Result<DkgParticipant, ComplaintReason>>,
|
||||
#[deprecated]
|
||||
generated_dealings: HashMap<EpochId, HashMap<DealingIndex, Dealing>>,
|
||||
#[deprecated]
|
||||
receiver_index: Option<usize>,
|
||||
#[deprecated]
|
||||
threshold: Option<Threshold>,
|
||||
#[deprecated]
|
||||
recovered_vks: Vec<RecoveredVerificationKeys>,
|
||||
#[deprecated]
|
||||
proposal_id: Option<u64>,
|
||||
#[deprecated]
|
||||
voted_vks: bool,
|
||||
#[deprecated]
|
||||
executed_proposal: bool,
|
||||
#[deprecated]
|
||||
was_in_progress: bool,
|
||||
}
|
||||
|
||||
@@ -313,24 +249,24 @@ impl State {
|
||||
identity_key: identity::PublicKey,
|
||||
coconut_keypair: CoconutKeyPair,
|
||||
) -> Self {
|
||||
todo!()
|
||||
// State {
|
||||
// persistent_state_path,
|
||||
// announce_address,
|
||||
// identity_key,
|
||||
// dkg_keypair,
|
||||
// coconut_keypair,
|
||||
// node_index: persistent_state.node_index,
|
||||
// dealers: persistent_state.dealers,
|
||||
// generated_dealings: persistent_state.generated_dealings,
|
||||
// receiver_index: persistent_state.receiver_index,
|
||||
// threshold: persistent_state.threshold,
|
||||
// recovered_vks: persistent_state.recovered_vks,
|
||||
// proposal_id: persistent_state.proposal_id,
|
||||
// voted_vks: persistent_state.voted_vks,
|
||||
// executed_proposal: persistent_state.executed_proposal,
|
||||
// was_in_progress: persistent_state.was_in_progress,
|
||||
// }
|
||||
State {
|
||||
persistent_state_path,
|
||||
dkg_instances: Default::default(),
|
||||
announce_address,
|
||||
identity_key,
|
||||
dkg_keypair,
|
||||
coconut_keypair,
|
||||
node_index: persistent_state.node_index,
|
||||
dealers: persistent_state.dealers,
|
||||
generated_dealings: persistent_state.generated_dealings,
|
||||
receiver_index: persistent_state.receiver_index,
|
||||
threshold: persistent_state.threshold,
|
||||
recovered_vks: persistent_state.recovered_vks,
|
||||
proposal_id: persistent_state.proposal_id,
|
||||
voted_vks: persistent_state.voted_vks,
|
||||
executed_proposal: persistent_state.executed_proposal,
|
||||
was_in_progress: persistent_state.was_in_progress,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn persist(&self) -> Result<(), CoconutError> {
|
||||
@@ -392,7 +328,7 @@ impl State {
|
||||
self.coconut_keypair.get().await.is_some()
|
||||
}
|
||||
|
||||
pub async fn take_coconut_keypair(&self) -> Option<(EpochId, nym_coconut::KeyPair)> {
|
||||
pub async fn take_coconut_keypair(&self) -> Option<KeyPairWithEpoch> {
|
||||
self.coconut_keypair.take().await
|
||||
}
|
||||
|
||||
@@ -417,7 +353,7 @@ impl State {
|
||||
#[cfg(test)]
|
||||
pub async fn coconut_keypair(
|
||||
&self,
|
||||
) -> tokio::sync::RwLockReadGuard<'_, Option<nym_coconut::KeyPair>> {
|
||||
) -> tokio::sync::RwLockReadGuard<'_, Option<KeyPairWithEpoch>> {
|
||||
self.coconut_keypair.get().await
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
pub(super) mod bte_pk_serde {
|
||||
use nym_dkg::bte::PublicKeyWithProof;
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
val: &PublicKeyWithProof,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
val.to_bytes().serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<PublicKeyWithProof, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<u8> = Deserialize::deserialize(deserializer)?;
|
||||
PublicKeyWithProof::try_from_bytes(&vec)
|
||||
.map_err(|err| Error::custom(format_args!("{:?}", err)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) mod vks_serde {
|
||||
use nym_dkg::RecoveredVerificationKeys;
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
val: &[RecoveredVerificationKeys],
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let vec: Vec<Vec<u8>> = val.iter().map(|vk| vk.to_bytes()).collect();
|
||||
vec.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<RecoveredVerificationKeys>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<Vec<u8>> = Deserialize::deserialize(deserializer)?;
|
||||
vec.into_iter()
|
||||
.map(|b| {
|
||||
RecoveredVerificationKeys::try_from_bytes(&b)
|
||||
.map_err(|err| D::Error::custom(format_args!("{:?}", err)))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) mod generated_dealings {
|
||||
use nym_coconut_dkg_common::types::{DealingIndex, EpochId};
|
||||
use nym_dkg::Dealing;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
|
||||
type Helper = HashMap<EpochId, HashMap<DealingIndex, Vec<u8>>>;
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
dealings: &HashMap<EpochId, HashMap<DealingIndex, Dealing>>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let mut helper = HashMap::new();
|
||||
for (epoch, dealings) in dealings {
|
||||
let mut inner = HashMap::new();
|
||||
for (dealing_index, dealing) in dealings {
|
||||
inner.insert(*dealing_index, dealing.to_bytes());
|
||||
}
|
||||
helper.insert(*epoch, inner);
|
||||
}
|
||||
helper.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<HashMap<EpochId, HashMap<DealingIndex, Dealing>>, D::Error> {
|
||||
let helper = <Helper>::deserialize(deserializer)?;
|
||||
|
||||
let mut epoch_dealings = HashMap::with_capacity(helper.len());
|
||||
for (epoch, dealings) in helper {
|
||||
let mut inner = HashMap::with_capacity(dealings.len());
|
||||
for (dealing_index, raw_dealing) in dealings {
|
||||
let dealing =
|
||||
Dealing::try_from_bytes(&raw_dealing).map_err(serde::de::Error::custom)?;
|
||||
inner.insert(dealing_index, dealing);
|
||||
}
|
||||
epoch_dealings.insert(epoch, inner);
|
||||
}
|
||||
Ok(epoch_dealings)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ use nym_dkg::{combine_shares, try_recover_verification_keys, Dealing, Threshold}
|
||||
use nym_pemstore::KeyPairPath;
|
||||
use nym_validator_client::nyxd::cosmwasm_client::logs::find_attribute;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::path::PathBuf;
|
||||
|
||||
// Filter the dealers based on what dealing they posted (or not) in the contract
|
||||
|
||||
@@ -207,7 +208,7 @@ pub(crate) async fn verification_key_submission(
|
||||
dkg_client: &DkgClient,
|
||||
state: &mut State,
|
||||
epoch_id: EpochId,
|
||||
keypair_path: &KeyPairPath,
|
||||
key_path: &PathBuf,
|
||||
resharing: bool,
|
||||
) -> Result<(), CoconutError> {
|
||||
if state.coconut_keypair_is_some().await {
|
||||
@@ -215,38 +216,40 @@ pub(crate) async fn verification_key_submission(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let threshold = state.threshold()?;
|
||||
let dealings_maps =
|
||||
deterministic_filter_dealers(dkg_client, state, epoch_id, threshold, resharing).await?;
|
||||
debug!(
|
||||
"Filtered dealers to {:?}",
|
||||
dealings_maps[0].keys().collect::<Vec<_>>()
|
||||
);
|
||||
let coconut_keypair = derive_partial_keypair(state, threshold, dealings_maps)?;
|
||||
debug!("Derived own coconut keypair");
|
||||
let vk_share = coconut_keypair.verification_key().to_bs58();
|
||||
nym_pemstore::store_keypair(&coconut_keypair, keypair_path)?;
|
||||
let res = dkg_client
|
||||
.submit_verification_key_share(vk_share, resharing)
|
||||
.await?;
|
||||
let proposal_id = find_attribute(&res.logs, "wasm", DKG_PROPOSAL_ID)
|
||||
.ok_or(CoconutError::ProposalIdError {
|
||||
reason: String::from("proposal id not found"),
|
||||
})?
|
||||
.value
|
||||
.parse::<u64>()
|
||||
.map_err(|_| CoconutError::ProposalIdError {
|
||||
reason: String::from("proposal id could not be parsed to u64"),
|
||||
})?;
|
||||
debug!(
|
||||
"Submitted own verification key share, proposal id {} is attached to it",
|
||||
proposal_id
|
||||
);
|
||||
state.set_proposal_id(proposal_id);
|
||||
state.set_coconut_keypair(epoch_id, coconut_keypair).await;
|
||||
info!("DKG: Submitted own verification key");
|
||||
|
||||
Ok(())
|
||||
todo!()
|
||||
//
|
||||
// let threshold = state.threshold()?;
|
||||
// let dealings_maps =
|
||||
// deterministic_filter_dealers(dkg_client, state, epoch_id, threshold, resharing).await?;
|
||||
// debug!(
|
||||
// "Filtered dealers to {:?}",
|
||||
// dealings_maps[0].keys().collect::<Vec<_>>()
|
||||
// );
|
||||
// let coconut_keypair = derive_partial_keypair(state, threshold, dealings_maps)?;
|
||||
// debug!("Derived own coconut keypair");
|
||||
// let vk_share = coconut_keypair.verification_key().to_bs58();
|
||||
// nym_pemstore::store_keypair(&coconut_keypair, keypair_path)?;
|
||||
// let res = dkg_client
|
||||
// .submit_verification_key_share(vk_share, resharing)
|
||||
// .await?;
|
||||
// let proposal_id = find_attribute(&res.logs, "wasm", DKG_PROPOSAL_ID)
|
||||
// .ok_or(CoconutError::ProposalIdError {
|
||||
// reason: String::from("proposal id not found"),
|
||||
// })?
|
||||
// .value
|
||||
// .parse::<u64>()
|
||||
// .map_err(|_| CoconutError::ProposalIdError {
|
||||
// reason: String::from("proposal id could not be parsed to u64"),
|
||||
// })?;
|
||||
// debug!(
|
||||
// "Submitted own verification key share, proposal id {} is attached to it",
|
||||
// proposal_id
|
||||
// );
|
||||
// state.set_proposal_id(proposal_id);
|
||||
// state.set_coconut_keypair(epoch_id, coconut_keypair).await;
|
||||
// info!("DKG: Submitted own verification key");
|
||||
//
|
||||
// Ok(())
|
||||
}
|
||||
|
||||
fn validate_proposal(proposal: &ProposalResponse) -> Option<(Addr, u64)> {
|
||||
@@ -451,20 +454,17 @@ pub(crate) mod tests {
|
||||
let mut clients_and_states = prepare_clients_and_states_with_dealing(db).await;
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
let random_file: usize = OsRng.gen();
|
||||
let private_key_path = temp_dir().join(format!("private{}.pem", random_file));
|
||||
let public_key_path = temp_dir().join(format!("public{}.pem", random_file));
|
||||
let keypair_path = KeyPairPath::new(private_key_path.clone(), public_key_path.clone());
|
||||
let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
|
||||
verification_key_submission(
|
||||
&controller.dkg_client,
|
||||
&mut controller.state,
|
||||
0,
|
||||
&keypair_path,
|
||||
&keypath,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
std::fs::remove_file(private_key_path).unwrap();
|
||||
std::fs::remove_file(public_key_path).unwrap();
|
||||
std::fs::remove_file(keypath).unwrap();
|
||||
}
|
||||
clients_and_states
|
||||
}
|
||||
@@ -1023,6 +1023,7 @@ pub(crate) mod tests {
|
||||
.await
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.keys
|
||||
.verification_key()
|
||||
.clone();
|
||||
let index = controller.state.node_index().unwrap();
|
||||
@@ -1083,20 +1084,17 @@ pub(crate) mod tests {
|
||||
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
let random_file: usize = OsRng.gen();
|
||||
let private_key_path = temp_dir().join(format!("private{}.pem", random_file));
|
||||
let public_key_path = temp_dir().join(format!("public{}.pem", random_file));
|
||||
let keypair_path = KeyPairPath::new(private_key_path.clone(), public_key_path.clone());
|
||||
let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
|
||||
verification_key_submission(
|
||||
&controller.dkg_client,
|
||||
&mut controller.state,
|
||||
0,
|
||||
&keypair_path,
|
||||
&keypath,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
std::fs::remove_file(private_key_path).unwrap();
|
||||
std::fs::remove_file(public_key_path).unwrap();
|
||||
std::fs::remove_file(keypath).unwrap();
|
||||
}
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
verification_key_validation(&controller.dkg_client, &mut controller.state, true)
|
||||
@@ -1124,6 +1122,7 @@ pub(crate) mod tests {
|
||||
.await
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.keys
|
||||
.verification_key()
|
||||
.clone();
|
||||
let index = controller.state.node_index().unwrap();
|
||||
@@ -1208,20 +1207,17 @@ pub(crate) mod tests {
|
||||
}
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
let random_file: usize = OsRng.gen();
|
||||
let private_key_path = temp_dir().join(format!("private{}.pem", random_file));
|
||||
let public_key_path = temp_dir().join(format!("public{}.pem", random_file));
|
||||
let keypair_path = KeyPairPath::new(private_key_path.clone(), public_key_path.clone());
|
||||
let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
|
||||
verification_key_submission(
|
||||
&controller.dkg_client,
|
||||
&mut controller.state,
|
||||
0,
|
||||
&keypair_path,
|
||||
&keypath,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
std::fs::remove_file(private_key_path).unwrap();
|
||||
std::fs::remove_file(public_key_path).unwrap();
|
||||
std::fs::remove_file(keypath).unwrap();
|
||||
}
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
verification_key_validation(&controller.dkg_client, &mut controller.state, false)
|
||||
@@ -1253,6 +1249,7 @@ pub(crate) mod tests {
|
||||
.await
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.keys
|
||||
.verification_key()
|
||||
.clone();
|
||||
let index = controller.state.node_index().unwrap();
|
||||
@@ -1290,20 +1287,17 @@ pub(crate) mod tests {
|
||||
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
let random_file: usize = OsRng.gen();
|
||||
let private_key_path = temp_dir().join(format!("private{}.pem", random_file));
|
||||
let public_key_path = temp_dir().join(format!("public{}.pem", random_file));
|
||||
let keypair_path = KeyPairPath::new(private_key_path.clone(), public_key_path.clone());
|
||||
let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
|
||||
verification_key_submission(
|
||||
&controller.dkg_client,
|
||||
&mut controller.state,
|
||||
0,
|
||||
&keypair_path,
|
||||
&keypath,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
std::fs::remove_file(private_key_path).unwrap();
|
||||
std::fs::remove_file(public_key_path).unwrap();
|
||||
std::fs::remove_file(keypath).unwrap();
|
||||
}
|
||||
|
||||
for controller in clients_and_states.iter_mut() {
|
||||
@@ -1332,6 +1326,7 @@ pub(crate) mod tests {
|
||||
.await
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.keys
|
||||
.verification_key()
|
||||
.clone();
|
||||
let index = controller.state.node_index().unwrap();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use rocket::http::{ContentType, Status};
|
||||
use rocket::response::Responder;
|
||||
use rocket::{response, Request, Response};
|
||||
use std::io::Cursor;
|
||||
use std::path::PathBuf;
|
||||
use thiserror::Error;
|
||||
|
||||
use nym_crypto::asymmetric::{
|
||||
@@ -12,6 +14,7 @@ use nym_crypto::asymmetric::{
|
||||
identity::{Ed25519RecoveryError, SignatureError},
|
||||
};
|
||||
use nym_dkg::error::DkgError;
|
||||
use nym_pemstore::KeyPairPath;
|
||||
use nym_validator_client::coconut::CoconutApiError;
|
||||
use nym_validator_client::nyxd::error::{NyxdError, TendermintError};
|
||||
|
||||
@@ -118,6 +121,16 @@ pub enum CoconutError {
|
||||
#[error("the coconut keypair is corrupted")]
|
||||
CorruptedCoconutKeyPair,
|
||||
|
||||
#[error("failed to archive coconut key for epoch {epoch_id} using path {}: {source}", path.display())]
|
||||
KeyArchiveFailure {
|
||||
epoch_id: EpochId,
|
||||
path: PathBuf,
|
||||
|
||||
// I hate that we're using anyhow error source here, but changing that would require bigger refactoring
|
||||
#[source]
|
||||
source: anyhow::Error,
|
||||
},
|
||||
|
||||
#[error("there was a problem with the proposal id: {reason}")]
|
||||
ProposalIdError { reason: String },
|
||||
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
mod persistence;
|
||||
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct KeyPair {
|
||||
// keys: Arc<RwLock<HashMap<EpochId, nym_coconut_interface::KeyPair>>>,
|
||||
keys: Arc<RwLock<Option<(EpochId, nym_coconut_interface::KeyPair)>>>,
|
||||
// issued_for_epoch: Arc<AtomicU64>,
|
||||
keys: Arc<RwLock<Option<KeyPairWithEpoch>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KeyPairWithEpoch {
|
||||
pub(crate) keys: nym_coconut_interface::KeyPair,
|
||||
pub(crate) issued_for_epoch: EpochId,
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
@@ -20,11 +28,11 @@ impl KeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn take(&self) -> Option<(EpochId, nym_coconut::KeyPair)> {
|
||||
pub async fn take(&self) -> Option<KeyPairWithEpoch> {
|
||||
self.keys.write().await.take()
|
||||
}
|
||||
|
||||
pub async fn get(&self) -> RwLockReadGuard<'_, Option<nym_coconut::KeyPair>> {
|
||||
pub async fn get(&self) -> RwLockReadGuard<'_, Option<KeyPairWithEpoch>> {
|
||||
todo!()
|
||||
// self.keys.read().await
|
||||
}
|
||||
@@ -35,6 +43,7 @@ impl KeyPair {
|
||||
// *w_lock = Some(keypair);
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn invalidate(&self) {
|
||||
*self.keys.write().await = None
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::coconut::keys::KeyPairWithEpoch;
|
||||
use crate::coconut::state::BANDWIDTH_CREDENTIAL_PARAMS;
|
||||
use nym_coconut::{CoconutError, KeyPair, SecretKey};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use nym_pemstore::traits::PemStorableKey;
|
||||
use std::mem;
|
||||
|
||||
impl PemStorableKey for KeyPairWithEpoch {
|
||||
// that's not the best error for this, but it felt like an overkill to define a dedicated struct just for this purpose
|
||||
type Error = CoconutError;
|
||||
|
||||
fn pem_type() -> &'static str {
|
||||
"COCONUT KEY WITH EPOCH"
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = self.issued_for_epoch.to_be_bytes().to_vec();
|
||||
bytes.append(&mut self.keys.secret_key().to_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
|
||||
if bytes.len() <= mem::size_of::<EpochId>() {
|
||||
return Err(CoconutError::Deserialization(
|
||||
"insufficient number of bytes to decode secret key with epoch id".into(),
|
||||
));
|
||||
}
|
||||
let epoch_id = EpochId::from_be_bytes([
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
]);
|
||||
|
||||
let sk = SecretKey::from_bytes(&bytes[mem::size_of::<EpochId>()..])?;
|
||||
let vk = sk.verification_key(&BANDWIDTH_CREDENTIAL_PARAMS);
|
||||
|
||||
Ok(KeyPairWithEpoch {
|
||||
keys: KeyPair::from_keys(sk, vk),
|
||||
issued_for_epoch: epoch_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use self::comm::APICommunicationChannel;
|
||||
use crate::coconut::client::Client as LocalClient;
|
||||
use crate::coconut::state::State;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use keypair::KeyPair;
|
||||
use keys::KeyPair;
|
||||
use nym_config::defaults::NYM_API_VERSION;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_validator_client::nym_api::routes::{BANDWIDTH, COCONUT_ROUTES};
|
||||
@@ -18,7 +18,7 @@ mod deposit;
|
||||
pub(crate) mod dkg;
|
||||
pub(crate) mod error;
|
||||
pub(crate) mod helpers;
|
||||
pub(crate) mod keypair;
|
||||
pub(crate) mod keys;
|
||||
pub(crate) mod state;
|
||||
pub(crate) mod storage;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::coconut::client::Client as LocalClient;
|
||||
use crate::coconut::comm::APICommunicationChannel;
|
||||
use crate::coconut::deposit::validate_deposit_tx;
|
||||
use crate::coconut::error::Result;
|
||||
use crate::coconut::keypair::KeyPair;
|
||||
use crate::coconut::keys::KeyPair;
|
||||
use crate::coconut::storage::CoconutStorageExt;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result<ShutdownHandles>
|
||||
let nym_network_details = NymNetworkDetails::new_from_env();
|
||||
let network_details = NetworkDetails::new(connected_nyxd.to_string(), nym_network_details);
|
||||
|
||||
let coconut_keypair_wrapper = coconut::keypair::KeyPair::new();
|
||||
let coconut_keypair_wrapper = coconut::keys::KeyPair::new();
|
||||
|
||||
// if the keypair doesnt exist (because say this API is running in the caching mode), nothing will happen
|
||||
if let Some(loaded_keys) = load_coconut_keypair_if_exists(&config.coconut_signer)? {
|
||||
|
||||
@@ -14,8 +14,7 @@ pub const DEFAULT_NODE_STATUS_API_DATABASE_FILENAME: &str = "db.sqlite";
|
||||
pub const DEFAULT_DKG_PERSISTENT_STATE_FILENAME: &str = "dkg_persistent_state.json";
|
||||
pub const DEFAULT_DKG_DECRYPTION_KEY_FILENAME: &str = "dkg_decryption_key.pem";
|
||||
pub const DEFAULT_DKG_PUBLIC_KEY_WITH_PROOF_FILENAME: &str = "dkg_public_key_with_proof.pem";
|
||||
pub const DEFAULT_COCONUT_VERIFICATION_KEY_FILENAME: &str = "coconut_verification_key.pem";
|
||||
pub const DEFAULT_COCONUT_SECRET_KEY_FILENAME: &str = "coconut_secret_key.pem";
|
||||
pub const DEFAULT_COCONUT_KEY_FILENAME: &str = "coconut.pem";
|
||||
|
||||
pub const DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME: &str = "private_identity.pem";
|
||||
pub const DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME: &str = "public_identity.pem";
|
||||
@@ -78,11 +77,8 @@ pub struct CoconutSignerPaths {
|
||||
/// Path to a JSON file where state is persisted between different stages of DKG.
|
||||
pub dkg_persistent_state_path: PathBuf,
|
||||
|
||||
/// Path to the coconut verification key.
|
||||
pub verification_key_path: PathBuf,
|
||||
|
||||
/// Path to the coconut secret key.
|
||||
pub secret_key_path: PathBuf,
|
||||
/// Path to the coconut key.
|
||||
pub coconut_key_path: PathBuf,
|
||||
|
||||
/// Path to the dkg dealer decryption key.
|
||||
pub decryption_key_path: PathBuf,
|
||||
@@ -97,8 +93,7 @@ impl CoconutSignerPaths {
|
||||
|
||||
CoconutSignerPaths {
|
||||
dkg_persistent_state_path: data_dir.join(DEFAULT_DKG_PERSISTENT_STATE_FILENAME),
|
||||
verification_key_path: data_dir.join(DEFAULT_COCONUT_VERIFICATION_KEY_FILENAME),
|
||||
secret_key_path: data_dir.join(DEFAULT_COCONUT_SECRET_KEY_FILENAME),
|
||||
coconut_key_path: data_dir.join(DEFAULT_COCONUT_KEY_FILENAME),
|
||||
decryption_key_path: data_dir.join(DEFAULT_DKG_DECRYPTION_KEY_FILENAME),
|
||||
public_key_with_proof_path: data_dir.join(DEFAULT_DKG_PUBLIC_KEY_WITH_PROOF_FILENAME),
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ pub(crate) async fn setup_rocket(
|
||||
network_details: NetworkDetails,
|
||||
_nyxd_client: nyxd::Client,
|
||||
identity_keypair: identity::KeyPair,
|
||||
coconut_keypair: coconut::keypair::KeyPair,
|
||||
coconut_keypair: coconut::keys::KeyPair,
|
||||
) -> anyhow::Result<Rocket<Ignite>> {
|
||||
let openapi_settings = rocket_okapi::settings::OpenApiSettings::default();
|
||||
let mut rocket = rocket::build();
|
||||
|
||||
Reference in New Issue
Block a user