Update orchestration

This commit is contained in:
Luke Parker
2024-08-06 00:27:07 -04:00
parent 8de696f169
commit 3042697243
4 changed files with 76 additions and 12 deletions

2
Cargo.lock generated
View File

@@ -8406,11 +8406,13 @@ name = "serai-orchestrator"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"ciphersuite", "ciphersuite",
"embedwards25519",
"flexible-transcript", "flexible-transcript",
"hex", "hex",
"home", "home",
"rand_chacha", "rand_chacha",
"rand_core", "rand_core",
"secq256k1",
"zalloc", "zalloc",
"zeroize", "zeroize",
] ]

View File

@@ -24,6 +24,8 @@ rand_chacha = { version = "0.3", default-features = false, features = ["std"] }
transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std", "recommended"] } transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std", "recommended"] }
ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std", "ristretto"] } ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std", "ristretto"] }
embedwards25519 = { path = "../crypto/evrf/embedwards25519" }
secq256k1 = { path = "../crypto/evrf/secq256k1" }
zalloc = { path = "../common/zalloc" } zalloc = { path = "../common/zalloc" }

View File

@@ -25,6 +25,8 @@ use ciphersuite::{
}, },
Ciphersuite, Ristretto, Ciphersuite, Ristretto,
}; };
use embedwards25519::Embedwards25519;
use secq256k1::Secq256k1;
mod mimalloc; mod mimalloc;
use mimalloc::mimalloc; use mimalloc::mimalloc;
@@ -267,6 +269,55 @@ fn infrastructure_keys(network: Network) -> InfrastructureKeys {
]) ])
} }
struct EmbeddedCurveKeys {
embedwards25519: (Zeroizing<Vec<u8>>, Vec<u8>),
secq256k1: (Zeroizing<Vec<u8>>, Vec<u8>),
}
fn embedded_curve_keys(network: Network) -> EmbeddedCurveKeys {
// Generate entropy for the embedded curve keys
let entropy = {
let path = home::home_dir()
.unwrap()
.join(".serai")
.join(network.label())
.join("embedded_curve_keys_entropy");
// Check if there's existing entropy
if let Ok(entropy) = fs::read(&path).map(Zeroizing::new) {
assert_eq!(entropy.len(), 32, "entropy saved to disk wasn't 32 bytes");
let mut res = Zeroizing::new([0; 32]);
res.copy_from_slice(entropy.as_ref());
res
} else {
// If there isn't, generate fresh entropy
let mut res = Zeroizing::new([0; 32]);
OsRng.fill_bytes(res.as_mut());
fs::write(&path, &res).unwrap();
res
}
};
let mut transcript =
RecommendedTranscript::new(b"Serai Orchestrator Embedded Curve Keys Transcript");
transcript.append_message(b"network", network.label().as_bytes());
transcript.append_message(b"entropy", entropy);
let mut rng = ChaCha20Rng::from_seed(transcript.rng_seed(b"embedded_curve_keys"));
EmbeddedCurveKeys {
embedwards25519: {
let key = Zeroizing::new(<Embedwards25519 as Ciphersuite>::F::random(&mut rng));
let pub_key = Embedwards25519::generator() * key.deref();
(Zeroizing::new(key.to_repr().as_slice().to_vec()), pub_key.to_bytes().to_vec())
},
secq256k1: {
let key = Zeroizing::new(<Secq256k1 as Ciphersuite>::F::random(&mut rng));
let pub_key = Secq256k1::generator() * key.deref();
(Zeroizing::new(key.to_repr().as_slice().to_vec()), pub_key.to_bytes().to_vec())
},
}
}
fn dockerfiles(network: Network) { fn dockerfiles(network: Network) {
let orchestration_path = orchestration_path(network); let orchestration_path = orchestration_path(network);
@@ -294,18 +345,15 @@ fn dockerfiles(network: Network) {
monero_key.1, monero_key.1,
); );
let new_entropy = || { let embedded_curve_keys = embedded_curve_keys(network);
let mut res = Zeroizing::new([0; 32]);
OsRng.fill_bytes(res.as_mut());
res
};
processor( processor(
&orchestration_path, &orchestration_path,
network, network,
"bitcoin", "bitcoin",
coordinator_key.1, coordinator_key.1,
bitcoin_key.0, bitcoin_key.0,
new_entropy(), embedded_curve_keys.embedwards25519.0.clone(),
embedded_curve_keys.secq256k1.0.clone(),
); );
processor( processor(
&orchestration_path, &orchestration_path,
@@ -313,9 +361,18 @@ fn dockerfiles(network: Network) {
"ethereum", "ethereum",
coordinator_key.1, coordinator_key.1,
ethereum_key.0, ethereum_key.0,
new_entropy(), embedded_curve_keys.embedwards25519.0.clone(),
embedded_curve_keys.secq256k1.0.clone(),
);
processor(
&orchestration_path,
network,
"monero",
coordinator_key.1,
monero_key.0,
embedded_curve_keys.embedwards25519.0.clone(),
embedded_curve_keys.embedwards25519.0.clone(),
); );
processor(&orchestration_path, network, "monero", coordinator_key.1, monero_key.0, new_entropy());
let serai_key = { let serai_key = {
let serai_key = Zeroizing::new( let serai_key = Zeroizing::new(
@@ -346,6 +403,7 @@ fn key_gen(network: Network) {
let _ = fs::create_dir_all(&serai_dir); let _ = fs::create_dir_all(&serai_dir);
fs::write(key_file, key.to_repr()).expect("couldn't write key"); fs::write(key_file, key.to_repr()).expect("couldn't write key");
// TODO: Move embedded curve key gen here, and print them
println!( println!(
"Public Key: {}", "Public Key: {}",
hex::encode((<Ristretto as Ciphersuite>::generator() * key).to_bytes()) hex::encode((<Ristretto as Ciphersuite>::generator() * key).to_bytes())

View File

@@ -12,8 +12,9 @@ pub fn processor(
network: Network, network: Network,
coin: &'static str, coin: &'static str,
_coordinator_key: <Ristretto as Ciphersuite>::G, _coordinator_key: <Ristretto as Ciphersuite>::G,
coin_key: Zeroizing<<Ristretto as Ciphersuite>::F>, processor_key: Zeroizing<<Ristretto as Ciphersuite>::F>,
entropy: Zeroizing<[u8; 32]>, substrate_evrf_key: Zeroizing<Vec<u8>>,
network_evrf_key: Zeroizing<Vec<u8>>,
) { ) {
let setup = mimalloc(Os::Debian).to_string() + let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service( &build_serai_service(
@@ -53,8 +54,9 @@ RUN apt install -y ca-certificates
let mut env_vars = vec![ let mut env_vars = vec![
("MESSAGE_QUEUE_RPC", format!("serai-{}-message-queue", network.label())), ("MESSAGE_QUEUE_RPC", format!("serai-{}-message-queue", network.label())),
("MESSAGE_QUEUE_KEY", hex::encode(coin_key.to_repr())), ("MESSAGE_QUEUE_KEY", hex::encode(processor_key.to_repr())),
("ENTROPY", hex::encode(entropy.as_ref())), ("SUBSTRATE_EVRF_KEY", hex::encode(substrate_evrf_key)),
("NETWORK_EVRF_KEY", hex::encode(network_evrf_key)),
("NETWORK", coin.to_string()), ("NETWORK", coin.to_string()),
("NETWORK_RPC_LOGIN", format!("{RPC_USER}:{RPC_PASS}")), ("NETWORK_RPC_LOGIN", format!("{RPC_USER}:{RPC_PASS}")),
("NETWORK_RPC_HOSTNAME", hostname), ("NETWORK_RPC_HOSTNAME", hostname),